Merge remote-tracking branch 'parent/main' into upstream-20240531
This commit is contained in:
commit
13ad383039
101 changed files with 1486 additions and 1232 deletions
|
@ -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,
|
||||
|
|
|
@ -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}` },
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ const ShortNumberCounter: React.FC<ShortNumberCounterProps> = ({ value }) => {
|
|||
|
||||
const count = (
|
||||
<FormattedNumber
|
||||
value={rawNumber}
|
||||
value={rawNumber ?? 0}
|
||||
maximumFractionDigits={maxFractionDigits}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -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] = {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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}` };
|
||||
});
|
||||
|
|
|
@ -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')} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "리스트 삭제",
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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}.",
|
||||
|
|
|
@ -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ę",
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "සංස්කරණය",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "删除列表",
|
||||
|
|
|
@ -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": "刪除列表",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue