Merge commit '520974e05211e988b0447f7f29e88798b1794bcf' into glitch-soc/merge-upstream

Conflicts:
- `app/serializers/rest/status_serializer.rb`:
  Not a real conflict, just glitch-soc code textually adjacent to code added
  upstream.
This commit is contained in:
Claire
2025-06-05 18:02:40 +02:00
48 changed files with 446 additions and 177 deletions

View File

@@ -2,6 +2,7 @@ import { browserHistory } from 'mastodon/components/router';
import { debounceWithDispatchAndArguments } from 'mastodon/utils/debounce';
import api, { getLinks } from '../api';
import { me } from '../initial_state';
import {
followAccountSuccess, unfollowAccountSuccess,
@@ -12,6 +13,7 @@ import {
blockAccountSuccess, unblockAccountSuccess,
pinAccountSuccess, unpinAccountSuccess,
fetchRelationshipsSuccess,
fetchEndorsedAccounts,
} from './accounts_typed';
import { importFetchedAccount, importFetchedAccounts } from './importer';
@@ -634,6 +636,7 @@ export function pinAccount(id) {
api().post(`/api/v1/accounts/${id}/pin`).then(response => {
dispatch(pinAccountSuccess({ relationship: response.data }));
dispatch(fetchEndorsedAccounts({ accountId: me }));
}).catch(error => {
dispatch(pinAccountFail(error));
});
@@ -646,6 +649,7 @@ export function unpinAccount(id) {
api().post(`/api/v1/accounts/${id}/unpin`).then(response => {
dispatch(unpinAccountSuccess({ relationship: response.data }));
dispatch(fetchEndorsedAccounts({ accountId: me }));
}).catch(error => {
dispatch(unpinAccountFail(error));
});

View File

@@ -12,6 +12,8 @@ import {
muteAccount,
unmuteAccount,
followAccountSuccess,
unpinAccount,
pinAccount,
} from 'mastodon/actions/accounts';
import { showAlertForError } from 'mastodon/actions/alerts';
import { openModal } from 'mastodon/actions/modal';
@@ -62,14 +64,23 @@ const messages = defineMessages({
},
});
export const Account: React.FC<{
interface AccountProps {
size?: number;
id: string;
hidden?: boolean;
minimal?: boolean;
defaultAction?: 'block' | 'mute';
withBio?: boolean;
}> = ({ id, size = 46, hidden, minimal, defaultAction, withBio }) => {
}
export const Account: React.FC<AccountProps> = ({
id,
size = 46,
hidden,
minimal,
defaultAction,
withBio,
}) => {
const intl = useIntl();
const { signedIn } = useIdentity();
const account = useAppSelector((state) => state.accounts.get(id));
@@ -119,8 +130,6 @@ export const Account: React.FC<{
},
];
} else if (defaultAction !== 'block') {
arr = [];
if (isRemote && accountUrl) {
arr.push({
text: intl.formatMessage(messages.openOriginalPage),
@@ -173,6 +182,25 @@ export const Account: React.FC<{
text: intl.formatMessage(messages.addToLists),
action: handleAddToLists,
});
if (id !== me && (relationship?.following || relationship?.requested)) {
const handleEndorseToggle = () => {
if (relationship.endorsed) {
dispatch(unpinAccount(id));
} else {
dispatch(pinAccount(id));
}
};
arr.push({
text: intl.formatMessage(
// Defined in features/account_timeline/components/account_header.tsx
relationship.endorsed
? { id: 'account.unendorse' }
: { id: 'account.endorse' },
),
action: handleEndorseToggle,
});
}
}
}

View File

@@ -8,6 +8,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import Textarea from 'react-textarea-autosize';
import { LoadingIndicator } from '@/mastodon/components/loading_indicator';
const messages = defineMessages({
placeholder: { id: 'account_note.placeholder', defaultMessage: 'Click to add a note' },
});
@@ -153,17 +155,23 @@ class AccountNote extends ImmutablePureComponent {
<FormattedMessage id='account.account_note_header' defaultMessage='Personal note' /> <InlineAlert show={saved} />
</label>
<Textarea
id={`account-note-${accountId}`}
className='account__header__account-note__content'
disabled={this.props.value === null || value === null}
placeholder={intl.formatMessage(messages.placeholder)}
value={value || ''}
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
onBlur={this.handleBlur}
ref={this.setTextareaRef}
/>
{this.props.value === undefined ? (
<div className='account__header__account-note__loading-indicator-wrapper'>
<LoadingIndicator />
</div>
) : (
<Textarea
id={`account-note-${accountId}`}
className='account__header__account-note__content'
disabled={value === null}
placeholder={intl.formatMessage(messages.placeholder)}
value={value || ''}
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
onBlur={this.handleBlur}
ref={this.setTextareaRef}
/>
)}
</div>
);
}

View File

@@ -17,6 +17,7 @@ import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon';
import { SpoilerButton } from 'mastodon/components/spoiler_button';
import { formatTime, getPointerPosition } from 'mastodon/features/video';
import { useAudioContext } from 'mastodon/hooks/useAudioContext';
import { useAudioVisualizer } from 'mastodon/hooks/useAudioVisualizer';
import {
displayMedia,
@@ -119,12 +120,17 @@ export const Audio: React.FC<{
const seekRef = useRef<HTMLDivElement>(null);
const volumeRef = useRef<HTMLDivElement>(null);
const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>();
const [resumeAudio, suspendAudio, frequencyBands] = useAudioVisualizer(
audioRef,
3,
);
const accessibilityId = useId();
const { audioContextRef, sourceRef, gainNodeRef, playAudio, pauseAudio } =
useAudioContext({ audioElementRef: audioRef });
const frequencyBands = useAudioVisualizer({
audioContextRef,
sourceRef,
numBands: 3,
});
const [style, spring] = useSpring(() => ({
progress: '0%',
buffer: '0%',
@@ -152,6 +158,9 @@ export const Audio: React.FC<{
restoreVolume(audioRef.current);
setVolume(audioRef.current.volume);
setMuted(audioRef.current.muted);
if (gainNodeRef.current) {
gainNodeRef.current.gain.value = audioRef.current.volume;
}
void spring.start({
volume: `${audioRef.current.volume * 100}%`,
immediate: reduceMotion,
@@ -159,15 +168,14 @@ export const Audio: React.FC<{
}
},
[
spring,
setVolume,
setMuted,
deployPictureInPicture,
src,
poster,
backgroundColor,
accentColor,
foregroundColor,
deployPictureInPicture,
accentColor,
gainNodeRef,
spring,
],
);
@@ -178,7 +186,11 @@ export const Audio: React.FC<{
audioRef.current.volume = volume;
audioRef.current.muted = muted;
}, [volume, muted]);
if (gainNodeRef.current) {
gainNodeRef.current.gain.value = muted ? 0 : volume;
}
}, [volume, muted, gainNodeRef]);
useEffect(() => {
if (typeof visible !== 'undefined') {
@@ -192,11 +204,10 @@ export const Audio: React.FC<{
}, [visible, sensitive]);
useEffect(() => {
if (!revealed && audioRef.current) {
audioRef.current.pause();
suspendAudio();
if (!revealed) {
pauseAudio();
}
}, [suspendAudio, revealed]);
}, [pauseAudio, revealed]);
useEffect(() => {
let nextFrame: ReturnType<typeof requestAnimationFrame>;
@@ -228,13 +239,11 @@ export const Audio: React.FC<{
}
if (audioRef.current.paused) {
resumeAudio();
void audioRef.current.play();
playAudio();
} else {
audioRef.current.pause();
suspendAudio();
pauseAudio();
}
}, [resumeAudio, suspendAudio]);
}, [playAudio, pauseAudio]);
const handlePlay = useCallback(() => {
setPaused(false);
@@ -349,8 +358,7 @@ export const Audio: React.FC<{
document.removeEventListener('mouseup', handleSeekMouseUp, true);
setDragging(false);
resumeAudio();
void audioRef.current?.play();
playAudio();
};
const handleSeekMouseMove = (e: MouseEvent) => {
@@ -377,7 +385,7 @@ export const Audio: React.FC<{
e.preventDefault();
e.stopPropagation();
},
[setDragging, spring, resumeAudio],
[playAudio, spring],
);
const handleMouseEnter = useCallback(() => {
@@ -446,10 +454,9 @@ export const Audio: React.FC<{
const handleCanPlayThrough = useCallback(() => {
if (startPlaying) {
resumeAudio();
void audioRef.current?.play();
playAudio();
}
}, [startPlaying, resumeAudio]);
}, [startPlaying, playAudio]);
const seekBy = (time: number) => {
if (!audioRef.current) {
@@ -492,7 +499,7 @@ export const Audio: React.FC<{
return;
}
const newVolume = audioRef.current.volume + step;
const newVolume = Math.max(0, audioRef.current.volume + step);
if (!isNaN(newVolume)) {
audioRef.current.volume = newVolume;

View File

@@ -40,6 +40,19 @@ export const ColumnSettings: React.FC = () => {
}
/>
<SettingToggle
prefix='home_timeline'
settings={settings}
settingPath={['shows', 'quote']}
onChange={onChange}
label={
<FormattedMessage
id='home.column_settings.show_quotes'
defaultMessage='Show quotes'
/>
}
/>
<SettingToggle
prefix='home_timeline'
settings={settings}

View File

@@ -17,19 +17,22 @@ const makeGetStatusIds = (pending = false) => createSelector([
if (id === null || id === 'inline-follow-suggestions') return true;
const statusForId = statuses.get(id);
let showStatus = true;
if (statusForId.get('account') === me) return true;
if (columnSettings.getIn(['shows', 'reblog']) === false) {
showStatus = showStatus && statusForId.get('reblog') === null;
if (columnSettings.getIn(['shows', 'reblog']) === false && statusForId.get('reblog') !== null) {
return false;
}
if (columnSettings.getIn(['shows', 'reply']) === false) {
showStatus = showStatus && (statusForId.get('in_reply_to_id') === null || statusForId.get('in_reply_to_account_id') === me);
if (columnSettings.getIn(['shows', 'reply']) === false && statusForId.get('in_reply_to_id') !== null && statusForId.get('in_reply_to_account_id') !== me) {
return false;
}
return showStatus;
if (columnSettings.getIn(['shows', 'quote']) === false && statusForId.get('quote') !== null) {
return false;
}
return true;
});
});

View File

@@ -0,0 +1,62 @@
import { useCallback, useEffect, useRef } from 'react';
interface AudioContextOptions {
audioElementRef: React.MutableRefObject<HTMLAudioElement | null>;
}
/**
* Create and return an audio context instance for a given audio element [0].
* Also returns an associated audio source, a gain node, and play and pause actions
* which should be used instead of `audioElementRef.current.play/pause()`.
*
* [0] https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
*/
export const useAudioContext = ({ audioElementRef }: AudioContextOptions) => {
const audioContextRef = useRef<AudioContext>();
const sourceRef = useRef<MediaElementAudioSourceNode>();
const gainNodeRef = useRef<GainNode>();
useEffect(() => {
if (!audioElementRef.current) {
return;
}
const context = audioContextRef.current ?? new AudioContext();
const source =
sourceRef.current ??
context.createMediaElementSource(audioElementRef.current);
const gainNode = context.createGain();
gainNode.connect(context.destination);
source.connect(gainNode);
audioContextRef.current = context;
gainNodeRef.current = gainNode;
sourceRef.current = source;
return () => {
if (context.state !== 'closed') {
void context.close();
}
};
}, [audioElementRef]);
const playAudio = useCallback(() => {
void audioElementRef.current?.play();
void audioContextRef.current?.resume();
}, [audioElementRef]);
const pauseAudio = useCallback(() => {
audioElementRef.current?.pause();
void audioContextRef.current?.suspend();
}, [audioElementRef]);
return {
audioContextRef,
sourceRef,
gainNodeRef,
playAudio,
pauseAudio,
};
};

View File

@@ -1,4 +1,4 @@
import { useState, useEffect, useRef, useCallback } from 'react';
import { useState, useEffect, useRef } from 'react';
const normalizeFrequencies = (arr: Float32Array): number[] => {
return new Array(...arr).map((value: number) => {
@@ -10,12 +10,17 @@ const normalizeFrequencies = (arr: Float32Array): number[] => {
});
};
export const useAudioVisualizer = (
ref: React.MutableRefObject<HTMLAudioElement | null>,
numBands: number,
) => {
const audioContextRef = useRef<AudioContext>();
const sourceRef = useRef<MediaElementAudioSourceNode>();
interface AudioVisualiserOptions {
audioContextRef: React.MutableRefObject<AudioContext | undefined>;
sourceRef: React.MutableRefObject<MediaElementAudioSourceNode | undefined>;
numBands: number;
}
export const useAudioVisualizer = ({
audioContextRef,
sourceRef,
numBands,
}: AudioVisualiserOptions) => {
const analyzerRef = useRef<AnalyserNode>();
const [frequencyBands, setFrequencyBands] = useState<number[]>(
@@ -23,47 +28,31 @@ export const useAudioVisualizer = (
);
useEffect(() => {
if (!audioContextRef.current) {
audioContextRef.current = new AudioContext();
if (audioContextRef.current) {
analyzerRef.current = audioContextRef.current.createAnalyser();
analyzerRef.current.smoothingTimeConstant = 0.6;
analyzerRef.current.fftSize = 2048;
}
return () => {
if (audioContextRef.current) {
void audioContextRef.current.close();
}
};
}, []);
}, [audioContextRef]);
useEffect(() => {
if (
audioContextRef.current &&
analyzerRef.current &&
!sourceRef.current &&
ref.current
) {
sourceRef.current = audioContextRef.current.createMediaElementSource(
ref.current,
);
if (analyzerRef.current && sourceRef.current) {
sourceRef.current.connect(analyzerRef.current);
sourceRef.current.connect(audioContextRef.current.destination);
}
const currentSource = sourceRef.current;
return () => {
if (sourceRef.current) {
sourceRef.current.disconnect();
if (currentSource && analyzerRef.current) {
currentSource.disconnect(analyzerRef.current);
}
};
}, [ref]);
}, [audioContextRef, sourceRef]);
useEffect(() => {
const source = sourceRef.current;
const analyzer = analyzerRef.current;
const context = audioContextRef.current;
if (!source || !analyzer || !context) {
if (!analyzer || !context) {
return;
}
@@ -94,19 +83,7 @@ export const useAudioVisualizer = (
return () => {
clearInterval(updateInterval);
};
}, [numBands]);
}, [numBands, audioContextRef]);
const resume = useCallback(() => {
if (audioContextRef.current) {
void audioContextRef.current.resume();
}
}, []);
const suspend = useCallback(() => {
if (audioContextRef.current) {
void audioContextRef.current.suspend();
}
}, []);
return [resume, suspend, frequencyBands] as const;
return frequencyBands;
};

View File

@@ -430,6 +430,7 @@
"hints.profiles.see_more_posts": "See more posts on {domain}",
"hints.threads.replies_may_be_missing": "Replies from other servers may be missing.",
"hints.threads.see_more": "See more replies on {domain}",
"home.column_settings.show_quotes": "Show quotes",
"home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies",
"home.hide_announcements": "Hide announcements",

View File

@@ -1,6 +1,7 @@
{
"about.blocks": "Modereeritavad serverid",
"about.contact": "Kontakt:",
"about.default_locale": "Vaikimisi",
"about.disclaimer": "Mastodon on tasuta ja vaba tarkvara ning Mastodon gGmbH kaubamärk.",
"about.domain_blocks.no_reason_available": "Põhjus teadmata",
"about.domain_blocks.preamble": "Mastodon lubab tavaliselt vaadata sisu ning suhelda kasutajatega ükskõik millisest teisest fediversumi serverist. Need on erandid, mis on paika pandud sellel kindlal serveril.",
@@ -8,6 +9,7 @@
"about.domain_blocks.silenced.title": "Piiratud",
"about.domain_blocks.suspended.explanation": "Mitte mingeid andmeid sellelt serverilt ei töödelda, salvestata ega vahetata, tehes igasuguse interaktsiooni või kirjavahetuse selle serveri kasutajatega võimatuks.",
"about.domain_blocks.suspended.title": "Peatatud",
"about.language_label": "Keel",
"about.not_available": "See info ei ole sellel serveril saadavaks tehtud.",
"about.powered_by": "Hajutatud sotsiaalmeedia, mille taga on {mastodon}",
"about.rules": "Serveri reeglid",
@@ -322,6 +324,8 @@
"explore.trending_links": "Uudised",
"explore.trending_statuses": "Postitused",
"explore.trending_tags": "Sildid",
"featured_carousel.next": "Järgmine",
"featured_carousel.previous": "Eelmine",
"filter_modal.added.context_mismatch_explanation": "See filtrikategooria ei rakendu kontekstis, kuidas postituseni jõudsid. Kui tahad postitust ka selles kontekstis filtreerida, pead muutma filtrit.",
"filter_modal.added.context_mismatch_title": "Konteksti mittesobivus!",
"filter_modal.added.expired_explanation": "Selle filtri kategooria on aegunud. pead muutma aegumiskuupäeva, kui tahad, et filter kehtiks.",
@@ -387,6 +391,7 @@
"hashtag.counter_by_uses": "{count, plural, one {{counter} postitusega} other {{counter} postitusega}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} postitust} other {{counter} postitust}} täna",
"hashtag.follow": "Jälgi silti",
"hashtag.mute": "Vaigista @#{hashtag}",
"hashtag.unfollow": "Lõpeta sildi jälgimine",
"hashtags.and_other": "…ja {count, plural, one {}other {# veel}}",
"hints.profiles.followers_may_be_missing": "Selle profiili jälgijaid võib olla puudu.",
@@ -892,6 +897,8 @@
"video.expand": "Suurenda video",
"video.fullscreen": "Täisekraan",
"video.hide": "Peida video",
"video.mute": "Vaigista",
"video.pause": "Paus",
"video.play": "Mängi"
"video.play": "Mängi",
"video.unmute": "Lõpeta vaigistamine"
}

View File

@@ -1,6 +1,7 @@
{
"about.blocks": "Frithealaichean fo mhaorsainneachd",
"about.contact": "Fios thugainn:",
"about.default_locale": "Bun-roghainn",
"about.disclaimer": "S e bathar-bog saor le bun-tùs fosgailte a th ann am Mastodon agus na chomharra-mhalairt aig Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Chan eil an t-adhbhar ga thoirt seachad",
"about.domain_blocks.preamble": "San fharsaingeachd, leigidh Mastodon leat susbaint o fhrithealaiche sam bith sa cho-shaoghal a shealltainn agus eadar-ghìomh a ghabhail leis na cleachdaichean uapa-san. Seo na h-easgaidhean a tha an sàs air an fhrithealaiche shònraichte seo.",
@@ -8,6 +9,7 @@
"about.domain_blocks.silenced.title": "Cuingichte",
"about.domain_blocks.suspended.explanation": "Cha dèid dàta sam bith on fhrithealaiche seo a phròiseasadh, a stòradh no iomlaid agus chan urrainn do na cleachdaichean on fhrithealaiche sin conaltradh no eadar-ghnìomh a ghabhail an-seo.",
"about.domain_blocks.suspended.title": "À rèim",
"about.language_label": "Cànan",
"about.not_available": "Cha deach am fiosrachadh seo a sholar air an fhrithealaiche seo.",
"about.powered_by": "Lìonra sòisealta sgaoilte le cumhachd {mastodon}",
"about.rules": "Riaghailtean an fhrithealaiche",
@@ -28,6 +30,9 @@
"account.edit_profile": "Deasaich a phròifil",
"account.enable_notifications": "Cuir brath thugam nuair a chuireas @{name} post ris",
"account.endorse": "Brosnaich air a phròifil",
"account.familiar_followers_many": "Ga leantainn le {name1}, {name2}, and {othersCount, plural, one {# eile air a bheil thu eòlach} other {# eile air a bheil thu eòlach}}",
"account.familiar_followers_one": "Ga leantainn le {name1}",
"account.familiar_followers_two": "Ga leantainn le {name1} s {name2}",
"account.featured": "Ga bhrosnachadh",
"account.featured.accounts": "Pròifilean",
"account.featured.hashtags": "Tagaichean hais",
@@ -38,6 +43,7 @@
"account.followers": "Luchd-leantainn",
"account.followers.empty": "Chan eil neach sam bith a leantainn air a chleachdaiche seo fhathast.",
"account.followers_counter": "{count, plural, one {{counter} neach-leantainn} other {{counter} luchd-leantainn}}",
"account.followers_you_know_counter": "{counter} air a bheil thu eòlach",
"account.following": "A leantainn",
"account.following_counter": "{count, plural, one {A leantainn {counter}} other {A leantainn {counter}}}",
"account.follows.empty": "Chan eil an cleachdaiche seo a leantainn neach sam bith fhathast.",
@@ -304,6 +310,8 @@
"emoji_button.search_results": "Toraidhean an luirg",
"emoji_button.symbols": "Samhlaidhean",
"emoji_button.travel": "Siubhal ⁊ àitichean",
"empty_column.account_featured.me": "Chan eil thu a brosnachadh dad fhathast. An robh fios agad gur urrainn dhut na tagaichean hais a chleachdas tu as trice agus fiù s cunntasan do charaidean a bhrosnachadh air a phròifil agad?",
"empty_column.account_featured.other": "Chan eil {acct} a brosnachadh dad fhathast. An robh fios agad gur urrainn dhut na tagaichean hais a chleachdas tu as trice agus fiù s cunntasan do charaidean a bhrosnachadh air a phròifil agad?",
"empty_column.account_featured_other.unknown": "Chan eil an cunntas seo a brosnachadh dad fhathast.",
"empty_column.account_hides_collections": "Chuir an cleachdaiche seo roimhe nach eil am fiosrachadh seo ri fhaighinn",
"empty_column.account_suspended": "Chaidh an cunntas a chur à rèim",
@@ -337,6 +345,11 @@
"explore.trending_links": "Naidheachdan",
"explore.trending_statuses": "Postaichean",
"explore.trending_tags": "Tagaichean hais",
"featured_carousel.header": "{count, plural, one {Post prìnichte} two {Postaichean prìnichte} few {Postaichean prìnichte} other {Postaichean prìnichte}}",
"featured_carousel.next": "Air adhart",
"featured_carousel.post": "Post",
"featured_carousel.previous": "Air ais",
"featured_carousel.slide": "{index} à {total}",
"filter_modal.added.context_mismatch_explanation": "Chan eil an roinn-seòrsa criathraidh iom seo chaidh dhan cho-theacs san do dhinntrig thu am post seo. Ma tha thu airson am post a chriathradh sa cho-theacs seo cuideachd, feumaidh tu a chriathrag a dheasachadh.",
"filter_modal.added.context_mismatch_title": "Co-theacsa neo-iomchaidh!",
"filter_modal.added.expired_explanation": "Dhfhalbh an ùine air an roinn-seòrsa criathraidh seo agus feumaidh tu an ceann-là crìochnachaidh atharrachadh mus cuir thu an sàs i.",
@@ -856,6 +869,13 @@
"status.mute_conversation": "Mùch an còmhradh",
"status.open": "Leudaich am post seo",
"status.pin": "Prìnich ris a phròifil",
"status.quote_error.filtered": "Falaichte le criathrag a th agad",
"status.quote_error.not_found": "Chan urrainn dhuinn am post seo a shealltainn.",
"status.quote_error.pending_approval": "Tha am post seo a feitheamh air aontachadh leis an ùghdar tùsail.",
"status.quote_error.rejected": "Chan urrainn dhuinn am post seo a shealltainn air sgàth s nach ceadaich an t-ùghdar tùsail aige gun dèid a luaidh.",
"status.quote_error.removed": "Chaidh am post seo a thoirt air falbh le ùghdar.",
"status.quote_error.unauthorized": "Chan urrainn dhuinn am post seo a shealltainn air sgàth s nach eil cead agad fhaicinn.",
"status.quote_post_author": "Post le {name}",
"status.read_more": "Leugh an còrr",
"status.reblog": "Brosnaich",
"status.reblog_private": "Brosnaich leis an t-so-fhaicsinneachd tùsail",

View File

@@ -1,6 +1,7 @@
{
"about.blocks": "Moderált kiszolgálók",
"about.contact": "Kapcsolat:",
"about.default_locale": "Alapértelmezett",
"about.disclaimer": "A Mastodon ingyenes, nyílt forráskódú szoftver, a Mastodon gGmbH védjegye.",
"about.domain_blocks.no_reason_available": "Nem áll rendelkezésre indoklás",
"about.domain_blocks.preamble": "A Mastodon általában mindenféle tartalomcserét és interakciót lehetővé tesz bármelyik másik kiszolgálóval a födiverzumban. Ezek azok a kivételek, amelyek a mi kiszolgálónkon érvényben vannak.",
@@ -8,6 +9,7 @@
"about.domain_blocks.silenced.title": "Korlátozott",
"about.domain_blocks.suspended.explanation": "A kiszolgáló adatai nem lesznek feldolgozva, tárolva vagy megosztva, lehetetlenné téve mindennemű interakciót és kommunikációt a kiszolgáló felhasználóival.",
"about.domain_blocks.suspended.title": "Felfüggesztett",
"about.language_label": "Nyelv",
"about.not_available": "Ez az információ nem lett közzétéve ezen a kiszolgálón.",
"about.powered_by": "Decentralizált közösségi média a {mastodon} segítségével",
"about.rules": "Kiszolgáló szabályai",

View File

@@ -8,6 +8,7 @@
"about.domain_blocks.silenced.title": "ken lukin lili ",
"about.domain_blocks.suspended.explanation": "sona ale pi ma ni li kama pali ala, li kama esun ala, li kama awen ala la sina ken ala toki tawa jan pi ma ni.",
"about.domain_blocks.suspended.title": "weka",
"about.language_label": "toki",
"about.not_available": "lon kulupu ni la sina ken alasa ala e sona ni.",
"about.powered_by": "lipu kulupu pi jan lawa mute tan {mastodon}",
"about.rules": "lawa kulupu",
@@ -15,37 +16,47 @@
"account.add_or_remove_from_list": "o ante e lipu jan",
"account.badges.bot": "ilo nanpa li lawa e ni",
"account.badges.group": "kulupu",
"account.block": "o weka e @{name}",
"account.block_domain": "o weka e ma {domain}",
"account.block_short": "o weka e jan tawa mi",
"account.blocked": "jan li weka tawa mi",
"account.block": "o len e @{name}",
"account.block_domain": "o len e ma {domain}",
"account.block_short": "o len",
"account.blocked": "jan li len",
"account.blocking": "mi len e jan ni",
"account.cancel_follow_request": "o kute ala",
"account.copy": "o pali same e linja pi lipu jan",
"account.direct": "len la o mu e @{name}",
"account.disable_notifications": "@{name} li toki la o mu ala e mi",
"account.domain_blocking": "mi len e ma ni",
"account.edit_profile": "o ante e lipu mi",
"account.enable_notifications": "@{name} li toki la o toki e toki ona tawa mi",
"account.endorse": "lipu jan la o suli e ni",
"account.featured_tags.last_status_at": "sitelen pini pi jan ni li lon tenpo {date}",
"account.familiar_followers_many": "{name1} en {name2} en {othersCount, plural, other {jan ante #}} li kute e jan ni",
"account.familiar_followers_one": "{name1} li kute e jan ni",
"account.familiar_followers_two": "{name1} en {name2} li kute e jan ni",
"account.featured": "suli",
"account.featured.accounts": "lipu jan",
"account.featured.hashtags": "kulupu lipu",
"account.featured_tags.last_status_at": "sitelen pini pi jan ni li tan {date}",
"account.featured_tags.last_status_never": "toki ala li lon",
"account.follow": "o kute",
"account.follow_back": "jan ni li kute e sina. o kute",
"account.followers": "jan kute",
"account.followers.empty": "jan ala li kute e jan ni",
"account.followers_counter": "{count, plural, other {jan {counter} li kute e ona}}",
"account.followers_you_know_counter": "jan {counter} pi kute sama",
"account.following": "sina kute e jan ni",
"account.following_counter": "{count, plural, other {ona li kute e jan {counter}}}",
"account.follows.empty": "jan ni li kute e jan ala",
"account.follows_you": "ona li kute e sina",
"account.go_to_profile": "o tawa lipu jan",
"account.hide_reblogs": "o lukin ala e pana toki tan @{name}",
"account.in_memoriam": "jan ni li moli. pona o tawa ona.",
"account.joined_short": "li kama",
"account.joined_short": "ona li kama lon tenpo",
"account.languages": "sina wile lukin e sitelen pi toki seme",
"account.link_verified_on": "{date} la mi sona e ni: jan seme li jo e lipu ni",
"account.locked_info": "sina wile kute e jan ni la ona o toki e ken",
"account.media": "sitelen",
"account.mention": "o toki e jan @{name}",
"account.moved_to": "lipu jan sin pi jan {name} li ni:",
"account.mention": "o mu e jan @{name}",
"account.moved_to": "jan ni la lipu sin li ni:",
"account.mute": "o len e @{name}",
"account.mute_notifications_short": "o kute ala e mu tan jan ni",
"account.mute_short": "o kute ala",
@@ -58,11 +69,12 @@
"account.requested": "jan ni o ken e kute sina",
"account.requested_follow": "jan {name} li wile kute e sina",
"account.share": "o pana e lipu jan @{name}",
"account.show_reblogs": "o lukin e pana toki tan @{name}",
"account.show_reblogs": "o lukin e toki sike tan @{name}",
"account.statuses_counter": "{count, plural, other {toki {counter}}}",
"account.unblock": "o weka ala e jan {name}",
"account.unblock_domain": "o weka ala e ma {domain}",
"account.unblock_short": "o pini weka",
"account.unblock": "o len ala e jan {name}",
"account.unblock_domain": "o len ala e ma {domain}",
"account.unblock_domain_short": "o len ala e jan ni",
"account.unblock_short": "o len ala",
"account.unendorse": "lipu jan la o suli ala e ni",
"account.unfollow": "o kute ala",
"account.unmute": "o len ala e @{name}",
@@ -72,7 +84,7 @@
"admin.dashboard.daily_retention": "nanpa pi awen jan lon tenpo suno",
"admin.dashboard.monthly_retention": "nanpa pi awen jan lon tenpo mun",
"admin.dashboard.retention.average": "sama",
"admin.dashboard.retention.cohort": "tenpo mun open",
"admin.dashboard.retention.cohort": "kama sijelo la tenpo mun",
"admin.dashboard.retention.cohort_size": "jan sin",
"admin.impact_report.instance_accounts": "ni li pakala li weka e lipu jan ni",
"admin.impact_report.instance_followers": "jan pi ma mi li weka tan jan kute ni",
@@ -82,14 +94,14 @@
"alert.rate_limited.title": "ilo ni li lili e ken sina",
"alert.unexpected.message": "pakala li lon",
"alert.unexpected.title": "pakala a!",
"alt_text_badge.title": "toki sona sitelen",
"alt_text_badge.title": "toki pi sona lukin",
"alt_text_modal.add_alt_text": "o pana e toki pi sona lukin",
"alt_text_modal.add_text_from_image": "o kama jo e toki sitelen tan sitelen ni",
"alt_text_modal.cancel": "weka",
"alt_text_modal.add_text_from_image": "o pana e nimi tan sitelen ni",
"alt_text_modal.cancel": "o weka",
"alt_text_modal.change_thumbnail": "o ante e sitelen lili",
"alt_text_modal.describe_for_people_with_hearing_impairments": "jan li ken ala kute la o pana e toki pi sona kalama…",
"alt_text_modal.describe_for_people_with_visual_impairments": "jan li ken ala lukin la o pana e toki pi sona lukin…",
"alt_text_modal.done": "pini",
"alt_text_modal.done": "o pana",
"announcement.announcement": "toki suli",
"annual_report.summary.archetype.booster": "jan ni li alasa e pona",
"annual_report.summary.archetype.lurker": "jan ni li lukin taso",
@@ -103,6 +115,8 @@
"annual_report.summary.highlighted_post.by_reblogs": "toki pi sike nanpa wan",
"annual_report.summary.highlighted_post.by_replies": "toki li jo e toki kama pi nanpa wan",
"annual_report.summary.highlighted_post.possessive": "tan jan {name}",
"annual_report.summary.most_used_app.most_used_app": "ilo pi kepeken suli",
"annual_report.summary.most_used_hashtag.most_used_hashtag": "kulupu toki pi kepeken suli",
"annual_report.summary.most_used_hashtag.none": "ala",
"annual_report.summary.new_posts.new_posts": "toki suli sin",
"annual_report.summary.percentile.text": "<topLabel>ni la sina nanpa sewi</topLabel><percentage></percentage><bottomLabel>pi jan ale lon {domain}.</bottomLabel>",
@@ -115,8 +129,8 @@
"block_modal.show_more": "o pana e mute",
"block_modal.they_cant_mention": "ona li ken ala toki tawa sina li ken ala kute e sina.",
"block_modal.they_cant_see_posts": "ona li ken ala lukin e toki sina. sina ken ala lukin e toki ona.",
"block_modal.they_will_know": "ona li sona e ni: sina weka e lukin ona.",
"block_modal.title": "o weka ala weka e jan",
"block_modal.they_will_know": "ona li ken sona e ni: sina len e ona.",
"block_modal.title": "o len ala len e jan?",
"block_modal.you_wont_see_mentions": "jan li toki e nimi ona la sina lukin ala e toki ni.",
"boost_modal.combo": "sina ken luka e nena {combo} tawa ni: sina wile ala luka e nena lon tenpo kama",
"boost_modal.reblog": "o wawa ala wawa e toki?",
@@ -139,13 +153,13 @@
"closed_registrations_modal.preamble": "ilo Masoton li lon ilo wan ala. sina kepeken ma ante la sina ken lukin li ken kute e jan pi ma ni. sina wile la, sina ken pali e ma sin!",
"closed_registrations_modal.title": "sina kama lon kulupu Masoton",
"column.about": "sona",
"column.blocks": "kulupu pi jan weka",
"column.blocks": "jan len",
"column.bookmarks": "awen toki",
"column.community": "linja tenpo pi ma ni",
"column.create_list": "o pali e kulupu",
"column.direct": "mu len",
"column.directory": "o lukin e jan",
"column.domain_blocks": "ma pi wile ala lukin",
"column.domain_blocks": "ma len",
"column.edit_list": "o ante e kulupu",
"column.favourites": "ijo pona",
"column.firehose": "toki pi tenpo ni",
@@ -194,7 +208,7 @@
"compose_form.spoiler.unmarked": "o pali e toki pi ijo ike ken",
"compose_form.spoiler_placeholder": "toki pi ijo ike ken (sina ken ala e ni)",
"confirmation_modal.cancel": "o weka",
"confirmations.block.confirm": "o weka",
"confirmations.block.confirm": "o len",
"confirmations.delete.confirm": "o weka",
"confirmations.delete.message": "sina wile ala wile weka e toki ni?",
"confirmations.delete.title": "o weka ala weka e toki?",
@@ -214,6 +228,7 @@
"confirmations.logout.title": "o weka?",
"confirmations.missing_alt_text.confirm": "pana e toki pi sona lukin",
"confirmations.missing_alt_text.message": "toki ni la sitelen li lon. taso toki pi sona lukin li lon ala. toki pi sona lukin li pona tan ni: jan ale li ken sona e toki.",
"confirmations.missing_alt_text.secondary": "o pana a",
"confirmations.missing_alt_text.title": "o pana e toki pi sona lukin",
"confirmations.mute.confirm": "o len",
"confirmations.redraft.confirm": "o weka o pali sin e toki",
@@ -245,9 +260,11 @@
"dismissable_banner.dismiss": "o weka",
"dismissable_banner.explore_links": "tenpo suno ni la jan pi kulupu ale li toki e ijo sin ni. ijo sin pi jan ante mute li sewi lon lipu ni.",
"dismissable_banner.explore_statuses": "jan mute li lukin e toki ni tan ma ilo weka. toki sin en toki pi wawa mute li lon sewi.",
"domain_block_modal.block": "o weka e ma",
"domain_block_modal.they_wont_know": "ona li sona ala e ni: sina weka e ona.",
"domain_block_modal.title": "sina wile weka ala weka e ma?",
"domain_block_modal.block": "o len e ma",
"domain_block_modal.block_account_instead": "o len e @{name}",
"domain_block_modal.they_cant_follow": "jan pi ma ni li ken ala kute e sina.",
"domain_block_modal.they_wont_know": "ona li sona ala e ni: sina len e ona.",
"domain_block_modal.title": "sina wile ala wile len e ma?",
"domain_block_modal.you_will_lose_num_followers": "{followersCount, plural, other {jan {followersCountDisplay}}} li kute e sina la, ona kama kute ala e sina. sina kute e {followingCount, plural,other {jan {followingCountDisplay}}} la, sina kama kute ala e ona.",
"domain_block_modal.you_will_lose_relationships": "jan li lon kulupu ni la ona kute e sina la, ona li kama kute ala e sina. jan li lon kulupu ni la sina kute e ona la, sina kama kute ala e ona.",
"domain_block_modal.you_wont_see_posts": "sina ken ala lukin e toki tan jan pi ma ni",
@@ -281,9 +298,9 @@
"empty_column.account_suspended": "lipu ni li weka",
"empty_column.account_timeline": "toki ala li lon!",
"empty_column.account_unavailable": "ken ala lukin e lipu jan",
"empty_column.blocks": "jan ala li weka tawa sina.",
"empty_column.blocks": "sina len ala e jan.",
"empty_column.direct": "jan ala li toki len e sina. jan li toki len e sina la sina ken lukin e ni lon ni.",
"empty_column.domain_blocks": "ma ala li weka tawa sina.",
"empty_column.domain_blocks": "sina len ala e ma.",
"empty_column.favourited_statuses": "sina suli ala e toki. sina suli e toki la sina ken lukin e toki ni lon ni.",
"empty_column.favourites": "jan ala li suli e toki ni. jan li suli e toki ni la sina ken lukin e ona lon ni.",
"empty_column.follow_requests": "jan ala li toki pi wile kute tawa sina. jan li toki pi wile kute tawa sina la sina ken lukin e toki ni lon ni.",
@@ -345,7 +362,7 @@
"interaction_modal.username_prompt": "ni li sama ni: {example}",
"intervals.full.days": "{number, plural, other {suni #}}",
"intervals.full.hours": "{number, plural, other {tenpo suli #}}",
"keyboard_shortcuts.blocked": "o lukin e lipu sina pi jan weka",
"keyboard_shortcuts.blocked": "o lukin e lipu pi len sina",
"keyboard_shortcuts.boost": "o pana sin e toki",
"keyboard_shortcuts.down": "o tawa anpa lon lipu",
"keyboard_shortcuts.enter": "o lukin e toki",
@@ -362,6 +379,7 @@
"lightbox.next": "sinpin",
"lightbox.previous": "monsi",
"link_preview.author": "tan {name}",
"lists.create": "o lipu e kulupu jan",
"lists.delete": "o weka e kulupu lipu",
"lists.done": "ale li pini",
"lists.edit": "o ante e kulupu lipu",
@@ -378,9 +396,9 @@
"loading_indicator.label": "ni li kama…",
"mute_modal.title": "sina wile ala wile kute e jan ni?",
"navigation_bar.about": "sona",
"navigation_bar.blocks": "jan weka",
"navigation_bar.blocks": "jan len",
"navigation_bar.compose": "o pali e toki sin",
"navigation_bar.domain_blocks": "kulupu pi ma weka",
"navigation_bar.domain_blocks": "ma len",
"navigation_bar.favourites": "ijo pona",
"navigation_bar.filters": "nimi len",
"navigation_bar.lists": "kulupu lipu",
@@ -400,6 +418,8 @@
"notification.mentioned_you": "jan {name} li toki e sina",
"notification.moderation-warning.learn_more": "o kama sona e ijo ante",
"notification.reblog": "{name} li wawa e toki sina",
"notification.relationships_severance_event.domain_block": "ma {from} la jan lawa li len e ma {target}. ma ni la jan {followersCount} li kute e sina. sina kute e {followingCount, plural, other {jan #}} tan ma ni. kama la ona ale li len tawa sina.",
"notification.relationships_severance_event.user_domain_block": "sina len e ma {target}. ma ni la jan {followersCount} li kute e sina. sina kute e {followingCount, plural, other {jan #}} tan ma ni. kama la ona ale li len tawa sina.",
"notification.status": "{name} li toki",
"notification.update": "{name} li ante e toki",
"notification_requests.dismiss": "o weka",
@@ -433,7 +453,7 @@
"relative_time.seconds": "{number}s",
"relative_time.today": "tenpo suno ni",
"reply_indicator.cancel": "o ala",
"report.block": "o weka e jan",
"report.block": "o len e jan",
"report.block_explanation": "sina kama lukin ala e toki ona. ona li kama ala ken lukin e toki sina li kama ala ken kute e sina. ona li ken sona e kama ni.",
"report.categories.other": "ante",
"report.categories.spam": "ike tan toki mute",
@@ -465,7 +485,7 @@
"search_results.see_all": "ale",
"search_results.statuses": "toki",
"server_banner.administered_by": "jan lawa:",
"status.block": "o weka e @{name}",
"status.block": "o len e @{name}",
"status.cancel_reblog_private": "o pini e pana",
"status.delete": "o weka",
"status.edit": "o ante",

View File

@@ -20,6 +20,7 @@ const initialState = ImmutableMap({
home: ImmutableMap({
shows: ImmutableMap({
quote: true,
reblog: true,
reply: true,
}),

View File

@@ -7068,18 +7068,19 @@ a.status-card {
}
.audio-player {
overflow: hidden;
box-sizing: border-box;
container: audio-player / inline-size;
position: relative;
background: var(--player-background-color, var(--background-color));
color: var(--player-foreground-color);
border-radius: 8px;
padding-bottom: 44px;
overflow: hidden;
display: flex;
flex-direction: column;
width: 100%;
aspect-ratio: 16 / 9;
color: var(--player-foreground-color);
background: var(--player-background-color, var(--background-color));
border-radius: 8px;
outline: 1px solid var(--media-outline-color);
outline-offset: -1px;
aspect-ratio: 16 / 9;
container: audio-player / inline-size;
&__controls {
display: grid;
@@ -7128,9 +7129,17 @@ a.status-card {
}
&__visualizer {
width: 100%;
max-width: 200px;
}
.video-player__seek {
position: absolute;
inset: 0 0 auto;
height: 24px;
z-index: 1; /* Ensure this renders on top of audio player controls */
}
&.inactive {
.video-player__seek,
.audio-player__controls,
@@ -8194,6 +8203,20 @@ noscript {
font-weight: 400;
margin-bottom: 10px;
&__loading-indicator-wrapper {
position: relative;
height: 37px;
.loading-indicator {
left: 10px;
}
.circular-progress {
width: 14px;
height: 14px;
}
}
label {
display: block;
font-size: 12px;
@@ -11053,6 +11076,8 @@ noscript {
&__slide {
flex: 0 0 auto;
flex-basis: 100%;
width: 100%;
overflow: hidden;
}
.status {