Merge remote-tracking branch 'parent/main' into upstream-20240531

This commit is contained in:
KMY 2024-05-31 08:27:09 +09:00
commit 13ad383039
101 changed files with 1486 additions and 1232 deletions

View file

@ -65,7 +65,7 @@ window.addEventListener('message', (e) => {
{
type: 'setHeight',
id: data.id,
height: document.getElementsByTagName('html')[0].scrollHeight,
height: document.getElementsByTagName('html')[0]?.scrollHeight,
},
'*',
);
@ -135,7 +135,7 @@ function loaded() {
);
};
const todayFormat = new IntlMessageFormat(
localeData['relative_format.today'] || 'Today at {time}',
localeData['relative_format.today'] ?? 'Today at {time}',
locale,
);
@ -288,13 +288,13 @@ function loaded() {
if (statusEl.dataset.spoiler === 'expanded') {
statusEl.dataset.spoiler = 'folded';
this.textContent = new IntlMessageFormat(
localeData['status.show_more'] || 'Show more',
localeData['status.show_more'] ?? 'Show more',
locale,
).format() as string;
} else {
statusEl.dataset.spoiler = 'expanded';
this.textContent = new IntlMessageFormat(
localeData['status.show_less'] || 'Show less',
localeData['status.show_less'] ?? 'Show less',
locale,
).format() as string;
}
@ -316,8 +316,8 @@ function loaded() {
const message =
statusEl.dataset.spoiler === 'expanded'
? localeData['status.show_less'] || 'Show less'
: localeData['status.show_more'] || 'Show more';
? localeData['status.show_less'] ?? 'Show less'
: localeData['status.show_more'] ?? 'Show more';
spoilerLink.textContent = new IntlMessageFormat(
message,
locale,

View file

@ -67,7 +67,9 @@ const fetchInteractionURLFailure = () => {
);
};
const isValidDomain = (value: string) => {
const isValidDomain = (value: unknown) => {
if (typeof value !== 'string') return false;
const url = new URL('https:///path');
url.hostname = value;
return url.hostname === value;
@ -124,6 +126,11 @@ const fromAcct = (acct: string) => {
const domain = segments[1];
const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
if (!domain) {
fetchInteractionURLFailure();
return;
}
axios
.get(`https://${domain}/.well-known/webfinger`, {
params: { resource: `acct:${acct}` },

View file

@ -48,8 +48,9 @@ export const AnimatedNumber: React.FC<Props> = ({ value }) => {
<span
key={key}
style={{
position: direction * style.y > 0 ? 'absolute' : 'static',
transform: `translateY(${style.y * 100}%)`,
position:
direction * (style.y ?? 0) > 0 ? 'absolute' : 'static',
transform: `translateY(${(style.y ?? 0) * 100}%)`,
}}
>
<ShortNumber value={data as number} />

View file

@ -52,7 +52,10 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
);
return Object.values(groups).map((tags) => {
if (tags.length === 1) return tags[0];
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the array has at least one element
const firstTag = tags[0]!;
if (tags.length === 1) return firstTag;
// The best match is the one where we have the less difference between upper and lower case letter count
const best = minBy(tags, (tag) => {
@ -66,7 +69,7 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
return Math.abs(lowerCase - upperCase);
});
return best ?? tags[0];
return best ?? firstTag;
});
}

View file

@ -54,7 +54,7 @@ const ShortNumberCounter: React.FC<ShortNumberCounterProps> = ({ value }) => {
const count = (
<FormattedNumber
value={rawNumber}
value={rawNumber ?? 0}
maximumFractionDigits={maxFractionDigits}
/>
);

View file

@ -29,7 +29,10 @@ const emojis: Emojis = {};
// decompress
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
const [_filenameData, searchData] = shortCodesToEmojiData[shortCode];
const emojiData = shortCodesToEmojiData[shortCode];
if (!emojiData) return;
const [_filenameData, searchData] = emojiData;
const [native, short_names, search, unified] = searchData;
emojis[shortCode] = {

View file

@ -46,7 +46,10 @@ function processEmojiMapData(
Object.keys(shortCodesToEmojiData).forEach(
(shortCode: ShortCodesToEmojiDataKey) => {
if (shortCode === undefined) return;
const [filenameData, _searchData] = shortCodesToEmojiData[shortCode];
const emojiData = shortCodesToEmojiData[shortCode];
if (!emojiData) return;
const [filenameData, _searchData] = emojiData;
filenameData.forEach((emojiMapData) => {
processEmojiMapData(emojiMapData, shortCode);
});

View file

@ -15,7 +15,7 @@ const mapStateToProps = (state, { columnId }) => {
return {
settings: columns.get(index).get('params'),
onLoad (value) {
return api(() => state).get('/api/v2/search', { params: { q: value, type: 'hashtags' } }).then(response => {
return api().get('/api/v2/search', { params: { q: value, type: 'hashtags' } }).then(response => {
return (response.data.hashtags || []).map((tag) => {
return { value: tag.name, label: `#${tag.name}` };
});

View file

@ -6,6 +6,8 @@ import { PureComponent } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
@ -13,6 +15,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react';
import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react';
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react';
import { Avatar } from 'mastodon/components/avatar';
import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
@ -56,6 +59,20 @@ const addAutoPlay = html => {
return html;
};
const MoreFromAuthor = ({ author }) => (
<div className='more-from-author'>
<svg viewBox='0 0 79 79' className='logo logo--icon' role='img'>
<use xlinkHref='#logo-symbol-icon' />
</svg>
<FormattedMessage id='link_preview.more_from_author' defaultMessage='More from {name}' values={{ name: <Link to={`/@${author.get('acct')}`}><Avatar account={author} size={16} /> {author.get('display_name')}</Link> }} />
</div>
);
MoreFromAuthor.propTypes = {
author: ImmutablePropTypes.map,
};
export default class Card extends PureComponent {
static propTypes = {
@ -136,6 +153,7 @@ export default class Card extends PureComponent {
const interactive = card.get('type') === 'video';
const language = card.get('language') || '';
const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive;
const showAuthor = !!card.get('author_account');
const description = (
<div className='status-card__content'>
@ -146,7 +164,7 @@ export default class Card extends PureComponent {
<strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong>
{card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>}
{!showAuthor && (card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>)}
</div>
);
@ -235,10 +253,14 @@ export default class Card extends PureComponent {
}
return (
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
{embed}
{description}
</a>
<>
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
{embed}
{description}
</a>
{showAuthor && <MoreFromAuthor author={card.get('author_account')} />}
</>
);
}

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostra el perfil de totes maneres",
"limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
"link_preview.author": "Per {name}",
"link_preview.more_from_author": "Més de {name}",
"lists.account.add": "Afegeix a la llista",
"lists.account.remove": "Elimina de la llista",
"lists.delete": "Elimina la llista",

View file

@ -520,6 +520,7 @@
"limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
"link_preview.author": "By {name}",
"link_preview.more_from_author": "More from {name}",
"lists.account.add": "Add to list",
"lists.account.remove": "Remove from list",
"lists.antennas": "Related antennas",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostrar perfil de todos modos",
"limited_account_hint.title": "Este perfil fue ocultado por los moderadores de {domain}.",
"link_preview.author": "Por {name}",
"link_preview.more_from_author": "Más de {name}",
"lists.account.add": "Agregar a lista",
"lists.account.remove": "Quitar de lista",
"lists.delete": "Eliminar lista",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Näytä profiili joka tapauksessa",
"limited_account_hint.title": "Palvelimen {domain} valvojat ovat piilottaneet tämän käyttäjätilin.",
"link_preview.author": "Julkaissut {name}",
"link_preview.more_from_author": "Lisää käyttäjältä {name}",
"lists.account.add": "Lisää listalle",
"lists.account.remove": "Poista listalta",
"lists.delete": "Poista lista",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostrar perfil igualmente",
"limited_account_hint.title": "Este perfil foi agochado pola moderación de {domain}.",
"link_preview.author": "Por {name}",
"link_preview.more_from_author": "Máis de {name}",
"lists.account.add": "Engadir á listaxe",
"lists.account.remove": "Eliminar da listaxe",
"lists.delete": "Eliminar listaxe",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostra comunque il profilo",
"limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.",
"link_preview.author": "Di {name}",
"link_preview.more_from_author": "Altro da {name}",
"lists.account.add": "Aggiungi all'elenco",
"lists.account.remove": "Rimuovi dall'elenco",
"lists.delete": "Elimina elenco",

View file

@ -234,7 +234,7 @@
"embed.preview": "이렇게 표시됩니다:",
"emoji_button.activity": "활동",
"emoji_button.clear": "지우기",
"emoji_button.custom": "사용자 지정",
"emoji_button.custom": "커스텀",
"emoji_button.flags": "깃발",
"emoji_button.food": "음식과 마실것",
"emoji_button.label": "에모지 추가",
@ -414,6 +414,7 @@
"limited_account_hint.action": "그래도 프로필 보기",
"limited_account_hint.title": "이 프로필은 {domain}의 중재자에 의해 숨겨진 상태입니다.",
"link_preview.author": "{name}",
"link_preview.more_from_author": "{name} 더 둘러보기",
"lists.account.add": "리스트에 추가",
"lists.account.remove": "리스트에서 제거",
"lists.delete": "리스트 삭제",

View file

@ -466,6 +466,7 @@
"notification.follow_request": "{name} paprašė tave sekti",
"notification.mention": "{name} paminėjo tave",
"notification.moderation-warning.learn_more": "Sužinoti daugiau",
"notification.moderation_warning": "Gavai prižiūrėjimo įspėjimą",
"notification.moderation_warning.action_delete_statuses": "Kai kurie tavo įrašai buvo pašalintos.",
"notification.moderation_warning.action_disable": "Tavo paskyra buvo išjungta.",
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Kai kurie tavo įrašai buvo pažymėtos kaip jautrios.",

View file

@ -297,6 +297,7 @@
"filter_modal.select_filter.subtitle": "Bruk ein eksisterande kategori eller opprett ein ny",
"filter_modal.select_filter.title": "Filtrer dette innlegget",
"filter_modal.title.status": "Filtrer eit innlegg",
"filtered_notifications_banner.mentions": "{count, plural, one {omtale} other {omtaler}}",
"filtered_notifications_banner.pending_requests": "Varsel frå {count, plural, =0 {ingen} one {ein person} other {# folk}} du kanskje kjenner",
"filtered_notifications_banner.title": "Filtrerte varslingar",
"firehose.all": "Alle",
@ -307,6 +308,8 @@
"follow_requests.unlocked_explanation": "Sjølv om kontoen din ikkje er låst tenkte dei som driv {domain} at du kanskje ville gå gjennom førespurnadar frå desse kontoane manuelt.",
"follow_suggestions.curated_suggestion": "Utvalt av staben",
"follow_suggestions.dismiss": "Ikkje vis igjen",
"follow_suggestions.featured_longer": "Hanplukka av gjengen på {domain}",
"follow_suggestions.friends_of_friends_longer": "Populært hjå dei du fylgjer",
"follow_suggestions.hints.featured": "Denne profilen er handplukka av folka på {domain}.",
"follow_suggestions.hints.friends_of_friends": "Denne profilen er populær hjå dei du fylgjer.",
"follow_suggestions.hints.most_followed": "Mange på {domain} fylgjer denne profilen.",
@ -314,6 +317,8 @@
"follow_suggestions.hints.similar_to_recently_followed": "Denne profilen liknar på dei andre profilane du har fylgt i det siste.",
"follow_suggestions.personalized_suggestion": "Personleg forslag",
"follow_suggestions.popular_suggestion": "Populært forslag",
"follow_suggestions.popular_suggestion_longer": "Populært på {domain}",
"follow_suggestions.similar_to_recently_followed_longer": "Liknar på profilar du har fylgt i det siste",
"follow_suggestions.view_all": "Vis alle",
"follow_suggestions.who_to_follow": "Kven du kan fylgja",
"followed_tags": "Fylgde emneknaggar",
@ -668,7 +673,7 @@
"search.quick_action.account_search": "Profiler som samsvarer med {x}",
"search.quick_action.go_to_account": "Gå til profil {x}",
"search.quick_action.go_to_hashtag": "Gå til emneknagg {x}",
"search.quick_action.open_url": "Åpne URL i Mastodon",
"search.quick_action.open_url": "Opne adressa i Mastodon",
"search.quick_action.status_search": "Innlegg som samsvarer med {x}",
"search.search_or_paste": "Søk eller lim inn URL",
"search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Pokaż profil mimo to",
"limited_account_hint.title": "Ten profil został ukryty przez moderatorów {domain}.",
"link_preview.author": "{name}",
"link_preview.more_from_author": "Więcej od {name}",
"lists.account.add": "Dodaj do listy",
"lists.account.remove": "Usunąć z listy",
"lists.delete": "Usuń listę",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Exibir perfil mesmo assim",
"limited_account_hint.title": "Este perfil foi ocultado pelos moderadores do {domain}.",
"link_preview.author": "Por {name}",
"link_preview.more_from_author": "Mais de {name}",
"lists.account.add": "Adicionar à lista",
"lists.account.remove": "Remover da lista",
"lists.delete": "Excluir lista",
@ -474,6 +475,7 @@
"notification.follow_request": "{name} quer te seguir",
"notification.mention": "{name} te mencionou",
"notification.moderation-warning.learn_more": "Aprender mais",
"notification.moderation_warning": "Você recebeu um aviso de moderação",
"notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.",
"notification.moderation_warning.action_disable": "Sua conta foi desativada.",
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas de suas publicações foram marcadas por ter conteúdo sensível.",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Exibir perfil mesmo assim",
"limited_account_hint.title": "Este perfil foi ocultado pelos moderadores de {domain}.",
"link_preview.author": "Por {name}",
"link_preview.more_from_author": "Mais de {name}",
"lists.account.add": "Adicionar à lista",
"lists.account.remove": "Remover da lista",
"lists.delete": "Eliminar lista",

View file

@ -18,6 +18,7 @@
"account.edit_profile": "පැතිකඩ සංස්කරණය",
"account.enable_notifications": "@{name} පළ කරන විට මට දැනුම් දෙන්න",
"account.endorse": "පැතිකඩෙහි විශේෂාංගය",
"account.featured_tags.last_status_at": "අවසාන ලිපිය: {date}",
"account.featured_tags.last_status_never": "ලිපි නැත",
"account.follow": "අනුගමනය",
"account.followers": "අනුගාමිකයින්",
@ -104,6 +105,7 @@
"compose_form.poll.duration": "මත විමසීමේ කාලය",
"compose_form.poll.switch_to_multiple": "තේරීම් කිහිපයකට මත විමසුම වෙනස් කරන්න",
"compose_form.poll.switch_to_single": "තනි තේරීමකට මත විමසුම වෙනස් කරන්න",
"compose_form.publish": "ප්‍රකාශනය",
"compose_form.publish_form": "නව ලිපිය",
"compose_form.spoiler.marked": "අන්තර්ගත අවවාදය ඉවත් කරන්න",
"compose_form.spoiler.unmarked": "අන්තර්ගත අවවාදයක් එක් කරන්න",
@ -154,6 +156,7 @@
"empty_column.bookmarked_statuses": "ඔබ සතුව පොත්යොමු තබන ලද ලිපි කිසිවක් නැත. ඔබ පොත්යොමුවක් තබන විට, එය මෙහි දිස්වනු ඇත.",
"empty_column.domain_blocks": "අවහිර කරන ලද වසම් නැත.",
"empty_column.explore_statuses": "දැන් කිසිවක් නැඹුරු නොවේ. පසුව නැවත පරීක්ෂා කරන්න!",
"empty_column.favourited_statuses": "ඔබ සතුව ප්‍රියතම ලිපි කිසිවක් නැත. ඔබ යමකට ප්‍රිය කළ විට එය මෙහි පෙන්වනු ඇත.",
"empty_column.follow_requests": "ඔබට තවමත් අනුගමන ඉල්ලීම් ලැබී නැත. ඉල්ලීමක් ලැබුණු විට, එය මෙහි පෙන්වනු ඇත.",
"empty_column.home": "මුල් පිටුව හිස් ය! මෙය පිරවීමට බොහෝ පුද්ගලයින් අනුගමනය කරන්න.",
"empty_column.lists": "ඔබට තවමත් ලැයිස්තු කිසිවක් නැත. ඔබ එකක් සාදන විට, එය මෙහි පෙන්වනු ඇත.",
@ -205,6 +208,7 @@
"interaction_modal.on_this_server": "මෙම සේවාදායකයෙහි",
"interaction_modal.title.favourite": "{name}ගේ ලිපිය ප්‍රිය කරන්න",
"interaction_modal.title.follow": "{name} අනුගමනය",
"interaction_modal.title.reply": "{name}ගේ ලිපියට පිළිතුරු",
"intervals.full.days": "{number, plural, one {දවස් #} other {දවස් #}}",
"intervals.full.hours": "{number, plural, one {පැය #} other {පැය #}}",
"intervals.full.minutes": "{number, plural, one {විනාඩි #} other {විනාඩි #}}",
@ -239,6 +243,7 @@
"lists.delete": "ලැයිස්තුව මකන්න",
"lists.edit": "ලැයිස්තුව සංස්කරණය",
"lists.edit.submit": "සිරැසිය සංශෝධනය",
"lists.new.create": "එකතු",
"lists.new.title_placeholder": "නව ලැයිස්තුවේ සිරැසිය",
"lists.replies_policy.list": "ලැයිස්තුවේ සාමාජිකයින්",
"lists.replies_policy.none": "කිසිවෙක් නැත",
@ -266,6 +271,7 @@
"navigation_bar.search": "සොයන්න",
"navigation_bar.security": "ආරක්ෂාව",
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
"notification.favourite": "{name} ඔබගේ ලිපියට ප්‍රිය කළා",
"notification.follow": "{name} ඔබව අනුගමනය කළා",
"notification.mention": "{name} ඔබව සඳහන් කර ඇත",
"notification.own_poll": "ඔබගේ මත විමසුම නිමයි",
@ -395,6 +401,7 @@
"status.admin_status": "මෙම ලිපිය මැදිහත්කරණ අතුරුමුහුණතෙහි අරින්න",
"status.block": "@{name} අවහිර",
"status.bookmark": "පොත්යොමුවක්",
"status.copy": "ලිපියට සබැඳියේ පිටපතක්",
"status.delete": "මකන්න",
"status.detailed_status": "විස්තරාත්මක සංවාද දැක්ම",
"status.edit": "සංස්කරණය",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Vseeno pokaži profil",
"limited_account_hint.title": "Profil so moderatorji strežnika {domain} skrili.",
"link_preview.author": "Avtor_ica {name}",
"link_preview.more_from_author": "Več od {name}",
"lists.account.add": "Dodaj na seznam",
"lists.account.remove": "Odstrani s seznama",
"lists.delete": "Izbriši seznam",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "Vẫn cứ xem",
"limited_account_hint.title": "Người này đã bị ẩn bởi quản trị viên của {domain}.",
"link_preview.author": "Bởi {name}",
"link_preview.more_from_author": "Thêm từ {name}",
"lists.account.add": "Thêm vào danh sách",
"lists.account.remove": "Xóa khỏi danh sách",
"lists.delete": "Xóa danh sách",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "仍要显示个人资料",
"limited_account_hint.title": "此账号资料已被 {domain} 管理员隐藏。",
"link_preview.author": "由 {name}",
"link_preview.more_from_author": "查看 {name} 的更多内容",
"lists.account.add": "添加到列表",
"lists.account.remove": "从列表中移除",
"lists.delete": "删除列表",

View file

@ -414,6 +414,7 @@
"limited_account_hint.action": "一律顯示個人檔案",
"limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。",
"link_preview.author": "來自 {name}",
"link_preview.more_from_author": "來自 {name} 之更多內容",
"lists.account.add": "新增至列表",
"lists.account.remove": "自列表中移除",
"lists.delete": "刪除列表",

View file

@ -74,8 +74,9 @@ export const soundsMiddleware = (): Middleware<
if (isActionWithMetaSound(action)) {
const sound = action.meta.sound;
if (sound && Object.hasOwn(soundCache, sound)) {
play(soundCache[sound]);
if (sound) {
const s = soundCache[sound];
if (s) play(s);
}
}

View file

@ -89,21 +89,17 @@ type OnData<LoadDataResult, ReturnedData> = (
},
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
type ArgsType = Record<string, unknown> | undefined;
// Overload when there is no `onData` method, the payload is the `onData` result
export function createDataLoadingThunk<
LoadDataResult,
Args extends Record<string, unknown>,
>(
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
name: string,
loadData: (args: Args) => Promise<LoadDataResult>,
thunkOptions?: AppThunkOptions,
): ReturnType<typeof createThunk<Args, LoadDataResult>>;
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
export function createDataLoadingThunk<
LoadDataResult,
Args extends Record<string, unknown>,
>(
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
name: string,
loadData: (args: Args) => Promise<LoadDataResult>,
onDataOrThunkOptions?:
@ -113,10 +109,7 @@ export function createDataLoadingThunk<
): ReturnType<typeof createThunk<Args, void>>;
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result
export function createDataLoadingThunk<
LoadDataResult,
Args extends Record<string, unknown>,
>(
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
name: string,
loadData: (args: Args) => Promise<LoadDataResult>,
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>,
@ -126,7 +119,7 @@ export function createDataLoadingThunk<
// Overload when there is an `onData` method returning something
export function createDataLoadingThunk<
LoadDataResult,
Args extends Record<string, unknown>,
Args extends ArgsType,
Returned,
>(
name: string,
@ -162,7 +155,7 @@ export function createDataLoadingThunk<
*/
export function createDataLoadingThunk<
LoadDataResult,
Args extends Record<string, unknown>,
Args extends ArgsType,
Returned,
>(
name: string,

View file

@ -4040,6 +4040,10 @@ button.icon-button.active i.fa-retweet {
border: 1px solid var(--background-border-color);
border-radius: 8px;
&.bottomless {
border-radius: 8px 8px 0 0;
}
&__actions {
bottom: 0;
inset-inline-start: 0;
@ -10654,3 +10658,42 @@ noscript {
}
}
}
.more-from-author {
font-size: 14px;
color: $darker-text-color;
background: var(--surface-background-color);
border: 1px solid var(--background-border-color);
border-top: 0;
border-radius: 0 0 8px 8px;
padding: 15px;
display: flex;
align-items: center;
gap: 8px;
.logo {
height: 16px;
color: $darker-text-color;
}
& > span {
display: flex;
align-items: center;
gap: 8px;
}
a {
display: inline-flex;
align-items: center;
gap: 4px;
font-weight: 500;
color: $primary-text-color;
text-decoration: none;
&:hover,
&:focus,
&:active {
color: $highlight-text-color;
}
}
}