Merge pull request #2817 from ClearlyClaire/glitch-soc/merge-upstream

Merge upstream changes up to 53c183f899
This commit is contained in:
Claire 2024-08-19 20:43:17 +02:00 committed by GitHub
commit 89a61954a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 1168 additions and 514 deletions

View file

@ -514,17 +514,17 @@ GEM
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-rack (~> 0.21)
opentelemetry-instrumentation-action_view (0.7.1)
opentelemetry-instrumentation-action_view (0.7.2)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-active_support (~> 0.1)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_job (0.7.4)
opentelemetry-instrumentation-active_job (0.7.6)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_model_serializers (0.20.2)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_record (0.7.2)
opentelemetry-instrumentation-active_record (0.7.3)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_support (0.6.0)
@ -558,7 +558,7 @@ GEM
opentelemetry-instrumentation-rack (0.24.6)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-rails (0.31.1)
opentelemetry-instrumentation-rails (0.31.2)
opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-action_mailer (~> 0.1.0)
opentelemetry-instrumentation-action_pack (~> 0.9.0)

View file

@ -1,8 +1,10 @@
# frozen_string_literal: true
class Api::V1::Notifications::RequestsController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :index
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, except: :index
include Redisable
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: [:index, :show, :merged?]
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, except: [:index, :show, :merged?]
before_action :require_user!
before_action :set_request, only: [:show, :accept, :dismiss]
@ -19,6 +21,10 @@ class Api::V1::Notifications::RequestsController < Api::BaseController
render json: @requests, each_serializer: REST::NotificationRequestSerializer, relationships: @relationships
end
def merged?
render json: { merged: redis.get("notification_unfilter_jobs:#{current_account.id}").to_i <= 0 }
end
def show
render json: @request, serializer: REST::NotificationRequestSerializer
end

View file

@ -138,8 +138,18 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
export const loadPending = createAction('notificationGroups/loadPending');
export const updateScrollPosition = createAction<{ top: boolean }>(
export const updateScrollPosition = createAppAsyncThunk(
'notificationGroups/updateScrollPosition',
({ top }: { top: boolean }, { dispatch, getState }) => {
if (
top &&
getState().notificationGroups.mergedNotifications === 'needs-reload'
) {
void dispatch(fetchNotifications());
}
return { top };
},
);
export const setNotificationsFilter = createAppAsyncThunk(
@ -165,5 +175,34 @@ export const markNotificationsAsRead = createAction(
'notificationGroups/markAsRead',
);
export const mountNotifications = createAction('notificationGroups/mount');
export const mountNotifications = createAppAsyncThunk(
'notificationGroups/mount',
(_, { dispatch, getState }) => {
const state = getState();
if (
state.notificationGroups.mounted === 0 &&
state.notificationGroups.mergedNotifications === 'needs-reload'
) {
void dispatch(fetchNotifications());
}
},
);
export const unmountNotifications = createAction('notificationGroups/unmount');
export const refreshStaleNotificationGroups = createAppAsyncThunk<{
deferredRefresh: boolean;
}>('notificationGroups/refreshStale', (_, { dispatch, getState }) => {
const state = getState();
if (
state.notificationGroups.scrolledToTop ||
!state.notificationGroups.mounted
) {
void dispatch(fetchNotifications());
return { deferredRefresh: false };
}
return { deferredRefresh: true };
});

View file

@ -200,8 +200,8 @@ const noOp = () => {};
let expandNotificationsController = new AbortController();
export function expandNotifications({ maxId, forceLoad = false } = {}, done = noOp) {
return (dispatch, getState) => {
export function expandNotifications({ maxId = undefined, forceLoad = false }) {
return async (dispatch, getState) => {
const activeFilter = getState().getIn(['settings', 'notifications', 'quickFilter', 'active']);
const notifications = getState().get('notifications');
const isLoadingMore = !!maxId;
@ -211,7 +211,6 @@ export function expandNotifications({ maxId, forceLoad = false } = {}, done = no
expandNotificationsController.abort();
expandNotificationsController = new AbortController();
} else {
done();
return;
}
}
@ -238,7 +237,8 @@ export function expandNotifications({ maxId, forceLoad = false } = {}, done = no
dispatch(expandNotificationsRequest(isLoadingMore));
api().get('/api/v1/notifications', { params, signal: expandNotificationsController.signal }).then(response => {
try {
const response = await api().get('/api/v1/notifications', { params, signal: expandNotificationsController.signal });
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(item => item.account)));
@ -248,11 +248,9 @@ export function expandNotifications({ maxId, forceLoad = false } = {}, done = no
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent, isLoadingRecent && preferPendingItems));
fetchRelatedRelationships(dispatch, response.data);
dispatch(submitMarkers());
}).catch(error => {
} catch(error) {
dispatch(expandNotificationsFail(error, isLoadingMore));
}).finally(() => {
done();
});
}
};
}

View file

@ -13,6 +13,6 @@ export const initializeNotifications = createAppAsyncThunk(
) as boolean;
if (enableBeta) void dispatch(fetchNotifications());
else dispatch(expandNotifications());
else void dispatch(expandNotifications());
},
);

View file

@ -10,7 +10,7 @@ import {
deleteAnnouncement,
} from './announcements';
import { updateConversations } from './conversations';
import { processNewNotificationForGroups } from './notification_groups';
import { processNewNotificationForGroups, refreshStaleNotificationGroups } from './notification_groups';
import { updateNotifications, expandNotifications } from './notifications';
import { updateStatus } from './statuses';
import {
@ -37,7 +37,7 @@ const randomUpTo = max =>
* @param {string} channelName
* @param {Object.<string, string>} params
* @param {Object} options
* @param {function(Function, Function): void} [options.fallback]
* @param {function(Function): Promise<void>} [options.fallback]
* @param {function(): void} [options.fillGaps]
* @param {function(object): boolean} [options.accept]
* @returns {function(): void}
@ -52,14 +52,13 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
let pollingId;
/**
* @param {function(Function, Function): void} fallback
* @param {function(Function): Promise<void>} fallback
*/
const useFallback = fallback => {
fallback(dispatch, () => {
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
pollingId = setTimeout(() => useFallback(fallback), 20000 + randomUpTo(20000));
});
const useFallback = async fallback => {
await fallback(dispatch);
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
pollingId = setTimeout(() => useFallback(fallback), 20000 + randomUpTo(20000));
};
return {
@ -109,6 +108,14 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
}
break;
}
case 'notifications_merged':
const state = getState();
if (state.notifications.top || !state.notifications.mounted)
dispatch(expandNotifications({ forceLoad: true, maxId: undefined }));
if(state.settings.getIn(['notifications', 'groupingBeta'], false)) {
dispatch(refreshStaleNotificationGroups());
}
break;
case 'conversation':
// @ts-expect-error
dispatch(updateConversations(JSON.parse(data.payload)));
@ -132,21 +139,17 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
/**
* @param {Function} dispatch
* @param {function(): void} done
*/
const refreshHomeTimelineAndNotification = (dispatch, done) => {
// @ts-expect-error
dispatch(expandHomeTimeline({}, () =>
// @ts-expect-error
dispatch(expandNotifications({}, () =>
dispatch(fetchAnnouncements(done))))));
};
async function refreshHomeTimelineAndNotification(dispatch) {
await dispatch(expandHomeTimeline({ maxId: undefined }));
await dispatch(expandNotifications({}));
await dispatch(fetchAnnouncements());
}
/**
* @returns {function(): void}
*/
export const connectUserStream = () =>
// @ts-expect-error
connectTimelineStream('home', 'user', {}, { fallback: refreshHomeTimelineAndNotification, fillGaps: fillHomeTimelineGaps });
/**

View file

@ -87,21 +87,18 @@ export function clearTimeline(timeline) {
};
}
const noOp = () => {};
const parseTags = (tags = {}, mode) => {
return (tags[mode] || []).map((tag) => {
return tag.value;
});
};
export function expandTimeline(timelineId, path, params = {}, done = noOp) {
return (dispatch, getState) => {
export function expandTimeline(timelineId, path, params = {}) {
return async (dispatch, getState) => {
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
const isLoadingMore = !!params.max_id;
if (timeline.get('isLoading')) {
done();
return;
}
@ -120,7 +117,8 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
dispatch(expandTimelineRequest(timelineId, isLoadingMore));
api().get(path, { params }).then(response => {
try {
const response = await api().get(path, { params });
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
@ -138,53 +136,49 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
if (timelineId === 'home') {
dispatch(submitMarkers());
}
}).catch(error => {
} catch(error) {
dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
}).finally(() => {
done();
});
}
};
}
export function fillTimelineGaps(timelineId, path, params = {}, done = noOp) {
return (dispatch, getState) => {
export function fillTimelineGaps(timelineId, path, params = {}) {
return async (dispatch, getState) => {
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
const items = timeline.get('items');
const nullIndexes = items.map((statusId, index) => statusId === null ? index : null);
const gaps = nullIndexes.map(index => index > 0 ? items.get(index - 1) : null);
// Only expand at most two gaps to avoid doing too many requests
done = gaps.take(2).reduce((done, maxId) => {
return (() => dispatch(expandTimeline(timelineId, path, { ...params, maxId }, done)));
}, done);
done();
for (const maxId of gaps.take(2)) {
await dispatch(expandTimeline(timelineId, path, { ...params, maxId }));
}
};
}
export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote, allowLocalOnly } = {}, done = noOp) => expandTimeline(`public${onlyRemote ? ':remote' : (allowLocalOnly ? ':allow_local_only' : '')}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, allow_local_only: !!allowLocalOnly, max_id: maxId, only_media: !!onlyMedia }, done);
export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia }, done);
export const expandDirectTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done);
export const expandHomeTimeline = ({ maxId } = {}) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId });
export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote, allowLocalOnly } = {}) => expandTimeline(`public${onlyRemote ? ':remote' : (allowLocalOnly ? ':allow_local_only' : '')}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, allow_local_only: !!allowLocalOnly, max_id: maxId, only_media: !!onlyMedia });
export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia });
export const expandDirectTimeline = ({ maxId } = {}) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId });
export const expandAccountTimeline = (accountId, { maxId, withReplies, tagged } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}${tagged ? `:${tagged}` : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, exclude_reblogs: withReplies, tagged, max_id: maxId });
export const expandAccountFeaturedTimeline = (accountId, { tagged } = {}) => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true, tagged });
export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true, limit: 40 });
export const expandListTimeline = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
export const expandLinkTimeline = (url, { maxId } = {}, done = noOp) => expandTimeline(`link:${url}`, `/api/v1/timelines/link`, { url, max_id: maxId }, done);
export const expandHashtagTimeline = (hashtag, { maxId, tags, local } = {}, done = noOp) => {
export const expandListTimeline = (id, { maxId } = {}) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId });
export const expandLinkTimeline = (url, { maxId } = {}) => expandTimeline(`link:${url}`, `/api/v1/timelines/link`, { url, max_id: maxId });
export const expandHashtagTimeline = (hashtag, { maxId, tags, local } = {}) => {
return expandTimeline(`hashtag:${hashtag}${local ? ':local' : ''}`, `/api/v1/timelines/tag/${hashtag}`, {
max_id: maxId,
any: parseTags(tags, 'any'),
all: parseTags(tags, 'all'),
none: parseTags(tags, 'none'),
local: local,
}, done);
});
};
export const fillHomeTimelineGaps = (done = noOp) => fillTimelineGaps('home', '/api/v1/timelines/home', {}, done);
export const fillPublicTimelineGaps = ({ onlyMedia, onlyRemote, allowLocalOnly } = {}, done = noOp) => fillTimelineGaps(`public${onlyRemote ? ':remote' : (allowLocalOnly ? ':allow_local_only' : '')}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, only_media: !!onlyMedia, allow_local_only: !!allowLocalOnly }, done);
export const fillCommunityTimelineGaps = ({ onlyMedia } = {}, done = noOp) => fillTimelineGaps(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, only_media: !!onlyMedia }, done);
export const fillListTimelineGaps = (id, done = noOp) => fillTimelineGaps(`list:${id}`, `/api/v1/timelines/list/${id}`, {}, done);
export const fillHomeTimelineGaps = () => fillTimelineGaps('home', '/api/v1/timelines/home', {});
export const fillPublicTimelineGaps = ({ onlyMedia, onlyRemote, allowLocalOnly } = {}) => fillTimelineGaps(`public${onlyRemote ? ':remote' : (allowLocalOnly ? ':allow_local_only' : '')}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, only_media: !!onlyMedia, allow_local_only: !!allowLocalOnly });
export const fillCommunityTimelineGaps = ({ onlyMedia } = {}) => fillTimelineGaps(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, only_media: !!onlyMedia });
export const fillListTimelineGaps = (id) => fillTimelineGaps(`list:${id}`, `/api/v1/timelines/list/${id}`, {});
export function expandTimelineRequest(timeline, isLoadingMore) {
return {

View file

@ -153,7 +153,7 @@ class ReportReasonSelector extends PureComponent {
<Category id='other' text={intl.formatMessage(messages.other)} selected={category === 'other'} onSelect={this.handleSelect} disabled={disabled} />
<Category id='legal' text={intl.formatMessage(messages.legal)} selected={category === 'legal'} onSelect={this.handleSelect} disabled={disabled} />
<Category id='spam' text={intl.formatMessage(messages.spam)} selected={category === 'spam'} onSelect={this.handleSelect} disabled={disabled} />
<Category id='violation' text={intl.formatMessage(messages.violation)} selected={category === 'violation'} onSelect={this.handleSelect} disabled={disabled}>
<Category id='violation' text={intl.formatMessage(messages.violation)} selected={category === 'violation'} onSelect={this.handleSelect} disabled={disabled || rules.length === 0}>
{rules.map(rule => <Rule key={rule.id} id={rule.id} text={rule.text} selected={rule_ids.includes(rule.id)} onToggle={this.handleToggle} disabled={disabled} />)}
</Category>
</div>

View file

@ -36,13 +36,13 @@ export const LinkTimeline: React.FC<{
const handleLoadMore = useCallback(
(maxId: string) => {
dispatch(expandLinkTimeline(decodedUrl, { maxId }));
void dispatch(expandLinkTimeline(decodedUrl, { maxId }));
},
[dispatch, decodedUrl],
);
useEffect(() => {
dispatch(expandLinkTimeline(decodedUrl));
void dispatch(expandLinkTimeline(decodedUrl));
}, [dispatch, decodedUrl]);
return (

View file

@ -81,7 +81,11 @@ export const Notifications: React.FC<{
const anyPendingNotification = useAppSelector(selectAnyPendingNotification);
const isUnread = unreadNotificationsCount > 0;
const needsReload = useAppSelector(
(state) => state.notificationGroups.mergedNotifications === 'needs-reload',
);
const isUnread = unreadNotificationsCount > 0 || needsReload;
const canMarkAsRead =
useAppSelector(selectSettingsNotificationsShowUnread) &&
@ -118,11 +122,11 @@ export const Notifications: React.FC<{
// Keep track of mounted components for unread notification handling
useEffect(() => {
dispatch(mountNotifications());
void dispatch(mountNotifications());
return () => {
dispatch(unmountNotifications());
dispatch(updateScrollPosition({ top: false }));
void dispatch(updateScrollPosition({ top: false }));
};
}, [dispatch]);
@ -147,11 +151,11 @@ export const Notifications: React.FC<{
}, [dispatch]);
const handleScrollToTop = useDebouncedCallback(() => {
dispatch(updateScrollPosition({ top: true }));
void dispatch(updateScrollPosition({ top: true }));
}, 100);
const handleScroll = useDebouncedCallback(() => {
dispatch(updateScrollPosition({ top: false }));
void dispatch(updateScrollPosition({ top: false }));
}, 100);
useEffect(() => {

View file

@ -19,6 +19,7 @@ import {
markNotificationsAsRead,
mountNotifications,
unmountNotifications,
refreshStaleNotificationGroups,
} from 'flavours/glitch/actions/notification_groups';
import {
disconnectTimeline,
@ -51,6 +52,7 @@ interface NotificationGroupsState {
readMarkerId: string;
mounted: number;
isTabVisible: boolean;
mergedNotifications: 'ok' | 'pending' | 'needs-reload';
}
const initialState: NotificationGroupsState = {
@ -58,6 +60,8 @@ const initialState: NotificationGroupsState = {
pendingGroups: [], // holds pending groups in slow mode
scrolledToTop: false,
isLoading: false,
// this is used to track whether we need to refresh notifications after accepting requests
mergedNotifications: 'ok',
// The following properties are used to track unread notifications
lastReadId: '0', // used internally for unread notifications
readMarkerId: '0', // user-facing and updated when focus changes
@ -301,6 +305,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
json.type === 'gap' ? json : createNotificationGroupFromJSON(json),
);
state.isLoading = false;
state.mergedNotifications = 'ok';
updateLastReadId(state);
})
.addCase(fetchNotificationsGap.fulfilled, (state, action) => {
@ -455,7 +460,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
state.groups = state.pendingGroups.concat(state.groups);
state.pendingGroups = [];
})
.addCase(updateScrollPosition, (state, action) => {
.addCase(updateScrollPosition.fulfilled, (state, action) => {
state.scrolledToTop = action.payload.top;
updateLastReadId(state);
trimNotifications(state);
@ -482,7 +487,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
action.payload.markers.notifications.last_read_id;
}
})
.addCase(mountNotifications, (state) => {
.addCase(mountNotifications.fulfilled, (state) => {
state.mounted += 1;
commitLastReadId(state);
updateLastReadId(state);
@ -498,6 +503,10 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
.addCase(unfocusApp, (state) => {
state.isTabVisible = false;
})
.addCase(refreshStaleNotificationGroups.fulfilled, (state, action) => {
if (action.payload.deferredRefresh)
state.mergedNotifications = 'needs-reload';
})
.addMatcher(
isAnyOf(authorizeFollowRequestSuccess, rejectFollowRequestSuccess),
(state, action) => {

View file

@ -138,8 +138,18 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
export const loadPending = createAction('notificationGroups/loadPending');
export const updateScrollPosition = createAction<{ top: boolean }>(
export const updateScrollPosition = createAppAsyncThunk(
'notificationGroups/updateScrollPosition',
({ top }: { top: boolean }, { dispatch, getState }) => {
if (
top &&
getState().notificationGroups.mergedNotifications === 'needs-reload'
) {
void dispatch(fetchNotifications());
}
return { top };
},
);
export const setNotificationsFilter = createAppAsyncThunk(
@ -165,5 +175,34 @@ export const markNotificationsAsRead = createAction(
'notificationGroups/markAsRead',
);
export const mountNotifications = createAction('notificationGroups/mount');
export const mountNotifications = createAppAsyncThunk(
'notificationGroups/mount',
(_, { dispatch, getState }) => {
const state = getState();
if (
state.notificationGroups.mounted === 0 &&
state.notificationGroups.mergedNotifications === 'needs-reload'
) {
void dispatch(fetchNotifications());
}
},
);
export const unmountNotifications = createAction('notificationGroups/unmount');
export const refreshStaleNotificationGroups = createAppAsyncThunk<{
deferredRefresh: boolean;
}>('notificationGroups/refreshStale', (_, { dispatch, getState }) => {
const state = getState();
if (
state.notificationGroups.scrolledToTop ||
!state.notificationGroups.mounted
) {
void dispatch(fetchNotifications());
return { deferredRefresh: false };
}
return { deferredRefresh: true };
});

View file

@ -188,8 +188,8 @@ const noOp = () => {};
let expandNotificationsController = new AbortController();
export function expandNotifications({ maxId, forceLoad = false } = {}, done = noOp) {
return (dispatch, getState) => {
export function expandNotifications({ maxId = undefined, forceLoad = false }) {
return async (dispatch, getState) => {
const activeFilter = getState().getIn(['settings', 'notifications', 'quickFilter', 'active']);
const notifications = getState().get('notifications');
const isLoadingMore = !!maxId;
@ -199,7 +199,6 @@ export function expandNotifications({ maxId, forceLoad = false } = {}, done = no
expandNotificationsController.abort();
expandNotificationsController = new AbortController();
} else {
done();
return;
}
}
@ -226,7 +225,8 @@ export function expandNotifications({ maxId, forceLoad = false } = {}, done = no
dispatch(expandNotificationsRequest(isLoadingMore));
api().get('/api/v1/notifications', { params, signal: expandNotificationsController.signal }).then(response => {
try {
const response = await api().get('/api/v1/notifications', { params, signal: expandNotificationsController.signal });
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(item => item.account)));
@ -236,11 +236,9 @@ export function expandNotifications({ maxId, forceLoad = false } = {}, done = no
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent, isLoadingRecent && preferPendingItems));
fetchRelatedRelationships(dispatch, response.data);
dispatch(submitMarkers());
}).catch(error => {
} catch(error) {
dispatch(expandNotificationsFail(error, isLoadingMore));
}).finally(() => {
done();
});
}
};
}

View file

@ -13,6 +13,6 @@ export const initializeNotifications = createAppAsyncThunk(
) as boolean;
if (enableBeta) void dispatch(fetchNotifications());
else dispatch(expandNotifications());
else void dispatch(expandNotifications());
},
);

View file

@ -10,7 +10,7 @@ import {
deleteAnnouncement,
} from './announcements';
import { updateConversations } from './conversations';
import { processNewNotificationForGroups } from './notification_groups';
import { processNewNotificationForGroups, refreshStaleNotificationGroups } from './notification_groups';
import { updateNotifications, expandNotifications } from './notifications';
import { updateStatus } from './statuses';
import {
@ -37,7 +37,7 @@ const randomUpTo = max =>
* @param {string} channelName
* @param {Object.<string, string>} params
* @param {Object} options
* @param {function(Function, Function): void} [options.fallback]
* @param {function(Function): Promise<void>} [options.fallback]
* @param {function(): void} [options.fillGaps]
* @param {function(object): boolean} [options.accept]
* @returns {function(): void}
@ -52,14 +52,13 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
let pollingId;
/**
* @param {function(Function, Function): void} fallback
* @param {function(Function): Promise<void>} fallback
*/
const useFallback = fallback => {
fallback(dispatch, () => {
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
pollingId = setTimeout(() => useFallback(fallback), 20000 + randomUpTo(20000));
});
const useFallback = async fallback => {
await fallback(dispatch);
// eslint-disable-next-line react-hooks/rules-of-hooks -- this is not a react hook
pollingId = setTimeout(() => useFallback(fallback), 20000 + randomUpTo(20000));
};
return {
@ -109,6 +108,14 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
}
break;
}
case 'notifications_merged':
const state = getState();
if (state.notifications.top || !state.notifications.mounted)
dispatch(expandNotifications({ forceLoad: true, maxId: undefined }));
if(state.settings.getIn(['notifications', 'groupingBeta'], false)) {
dispatch(refreshStaleNotificationGroups());
}
break;
case 'conversation':
// @ts-expect-error
dispatch(updateConversations(JSON.parse(data.payload)));
@ -132,21 +139,17 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
/**
* @param {Function} dispatch
* @param {function(): void} done
*/
const refreshHomeTimelineAndNotification = (dispatch, done) => {
// @ts-expect-error
dispatch(expandHomeTimeline({}, () =>
// @ts-expect-error
dispatch(expandNotifications({}, () =>
dispatch(fetchAnnouncements(done))))));
};
async function refreshHomeTimelineAndNotification(dispatch) {
await dispatch(expandHomeTimeline({ maxId: undefined }));
await dispatch(expandNotifications({}));
await dispatch(fetchAnnouncements());
}
/**
* @returns {function(): void}
*/
export const connectUserStream = () =>
// @ts-expect-error
connectTimelineStream('home', 'user', {}, { fallback: refreshHomeTimelineAndNotification, fillGaps: fillHomeTimelineGaps });
/**

View file

@ -76,21 +76,18 @@ export function clearTimeline(timeline) {
};
}
const noOp = () => {};
const parseTags = (tags = {}, mode) => {
return (tags[mode] || []).map((tag) => {
return tag.value;
});
};
export function expandTimeline(timelineId, path, params = {}, done = noOp) {
return (dispatch, getState) => {
export function expandTimeline(timelineId, path, params = {}) {
return async (dispatch, getState) => {
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
const isLoadingMore = !!params.max_id;
if (timeline.get('isLoading')) {
done();
return;
}
@ -109,7 +106,8 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
dispatch(expandTimelineRequest(timelineId, isLoadingMore));
api().get(path, { params }).then(response => {
try {
const response = await api().get(path, { params });
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
@ -127,52 +125,48 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
if (timelineId === 'home') {
dispatch(submitMarkers());
}
}).catch(error => {
} catch(error) {
dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
}).finally(() => {
done();
});
}
};
}
export function fillTimelineGaps(timelineId, path, params = {}, done = noOp) {
return (dispatch, getState) => {
export function fillTimelineGaps(timelineId, path, params = {}) {
return async (dispatch, getState) => {
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
const items = timeline.get('items');
const nullIndexes = items.map((statusId, index) => statusId === null ? index : null);
const gaps = nullIndexes.map(index => index > 0 ? items.get(index - 1) : null);
// Only expand at most two gaps to avoid doing too many requests
done = gaps.take(2).reduce((done, maxId) => {
return (() => dispatch(expandTimeline(timelineId, path, { ...params, maxId }, done)));
}, done);
done();
for (const maxId of gaps.take(2)) {
await dispatch(expandTimeline(timelineId, path, { ...params, maxId }));
}
};
}
export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote } = {}, done = noOp) => expandTimeline(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, max_id: maxId, only_media: !!onlyMedia }, done);
export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia }, done);
export const expandHomeTimeline = ({ maxId } = {}) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId });
export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote } = {}) => expandTimeline(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, max_id: maxId, only_media: !!onlyMedia });
export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia });
export const expandAccountTimeline = (accountId, { maxId, withReplies, tagged } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}${tagged ? `:${tagged}` : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, exclude_reblogs: withReplies, tagged, max_id: maxId });
export const expandAccountFeaturedTimeline = (accountId, { tagged } = {}) => expandTimeline(`account:${accountId}:pinned${tagged ? `:${tagged}` : ''}`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true, tagged });
export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true, limit: 40 });
export const expandListTimeline = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
export const expandLinkTimeline = (url, { maxId } = {}, done = noOp) => expandTimeline(`link:${url}`, `/api/v1/timelines/link`, { url, max_id: maxId }, done);
export const expandHashtagTimeline = (hashtag, { maxId, tags, local } = {}, done = noOp) => {
export const expandListTimeline = (id, { maxId } = {}) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId });
export const expandLinkTimeline = (url, { maxId } = {}) => expandTimeline(`link:${url}`, `/api/v1/timelines/link`, { url, max_id: maxId });
export const expandHashtagTimeline = (hashtag, { maxId, tags, local } = {}) => {
return expandTimeline(`hashtag:${hashtag}${local ? ':local' : ''}`, `/api/v1/timelines/tag/${hashtag}`, {
max_id: maxId,
any: parseTags(tags, 'any'),
all: parseTags(tags, 'all'),
none: parseTags(tags, 'none'),
local: local,
}, done);
});
};
export const fillHomeTimelineGaps = (done = noOp) => fillTimelineGaps('home', '/api/v1/timelines/home', {}, done);
export const fillPublicTimelineGaps = ({ onlyMedia, onlyRemote } = {}, done = noOp) => fillTimelineGaps(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, only_media: !!onlyMedia }, done);
export const fillCommunityTimelineGaps = ({ onlyMedia } = {}, done = noOp) => fillTimelineGaps(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, only_media: !!onlyMedia }, done);
export const fillListTimelineGaps = (id, done = noOp) => fillTimelineGaps(`list:${id}`, `/api/v1/timelines/list/${id}`, {}, done);
export const fillHomeTimelineGaps = () => fillTimelineGaps('home', '/api/v1/timelines/home', {});
export const fillPublicTimelineGaps = ({ onlyMedia, onlyRemote } = {}) => fillTimelineGaps(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, only_media: !!onlyMedia });
export const fillCommunityTimelineGaps = ({ onlyMedia } = {}) => fillTimelineGaps(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, only_media: !!onlyMedia });
export const fillListTimelineGaps = (id) => fillTimelineGaps(`list:${id}`, `/api/v1/timelines/list/${id}`, {});
export function expandTimelineRequest(timeline, isLoadingMore) {
return {

View file

@ -153,7 +153,7 @@ class ReportReasonSelector extends PureComponent {
<Category id='other' text={intl.formatMessage(messages.other)} selected={category === 'other'} onSelect={this.handleSelect} disabled={disabled} />
<Category id='legal' text={intl.formatMessage(messages.legal)} selected={category === 'legal'} onSelect={this.handleSelect} disabled={disabled} />
<Category id='spam' text={intl.formatMessage(messages.spam)} selected={category === 'spam'} onSelect={this.handleSelect} disabled={disabled} />
<Category id='violation' text={intl.formatMessage(messages.violation)} selected={category === 'violation'} onSelect={this.handleSelect} disabled={disabled}>
<Category id='violation' text={intl.formatMessage(messages.violation)} selected={category === 'violation'} onSelect={this.handleSelect} disabled={disabled || rules.length === 0}>
{rules.map(rule => <Rule key={rule.id} id={rule.id} text={rule.text} selected={rule_ids.includes(rule.id)} onToggle={this.handleToggle} disabled={disabled} />)}
</Category>
</div>

View file

@ -36,13 +36,13 @@ export const LinkTimeline: React.FC<{
const handleLoadMore = useCallback(
(maxId: string) => {
dispatch(expandLinkTimeline(decodedUrl, { maxId }));
void dispatch(expandLinkTimeline(decodedUrl, { maxId }));
},
[dispatch, decodedUrl],
);
useEffect(() => {
dispatch(expandLinkTimeline(decodedUrl));
void dispatch(expandLinkTimeline(decodedUrl));
}, [dispatch, decodedUrl]);
return (

View file

@ -81,7 +81,11 @@ export const Notifications: React.FC<{
const anyPendingNotification = useAppSelector(selectAnyPendingNotification);
const isUnread = unreadNotificationsCount > 0;
const needsReload = useAppSelector(
(state) => state.notificationGroups.mergedNotifications === 'needs-reload',
);
const isUnread = unreadNotificationsCount > 0 || needsReload;
const canMarkAsRead =
useAppSelector(selectSettingsNotificationsShowUnread) &&
@ -118,11 +122,11 @@ export const Notifications: React.FC<{
// Keep track of mounted components for unread notification handling
useEffect(() => {
dispatch(mountNotifications());
void dispatch(mountNotifications());
return () => {
dispatch(unmountNotifications());
dispatch(updateScrollPosition({ top: false }));
void dispatch(updateScrollPosition({ top: false }));
};
}, [dispatch]);
@ -147,11 +151,11 @@ export const Notifications: React.FC<{
}, [dispatch]);
const handleScrollToTop = useDebouncedCallback(() => {
dispatch(updateScrollPosition({ top: true }));
void dispatch(updateScrollPosition({ top: true }));
}, 100);
const handleScroll = useDebouncedCallback(() => {
dispatch(updateScrollPosition({ top: false }));
void dispatch(updateScrollPosition({ top: false }));
}, 100);
useEffect(() => {

View file

@ -32,7 +32,7 @@
"account.featured_tags.last_status_never": "لا توجد رسائل",
"account.featured_tags.title": "وسوم {name} المميَّزة",
"account.follow": "متابعة",
"account.follow_back": "تابعهم بالمثل",
"account.follow_back": "تابعه بالمثل",
"account.followers": "مُتابِعون",
"account.followers.empty": "لا أحدَ يُتابع هذا المُستخدم إلى حد الآن.",
"account.followers_counter": "{count, plural, zero {}one {{counter} متابع} two {{counter} متابعين} few {{counter} متابعين} many {{counter} متابعين} other {{counter} متابعين}}",
@ -169,12 +169,15 @@
"confirmations.block.confirm": "حظر",
"confirmations.delete.confirm": "حذف",
"confirmations.delete.message": "هل أنتَ مُتأكدٌ أنك تُريدُ حَذفَ هذا المنشور؟",
"confirmations.delete.title": "أتريد حذف المنشور؟",
"confirmations.delete_list.confirm": "حذف",
"confirmations.delete_list.message": "هل أنتَ مُتأكدٌ أنكَ تُريدُ حَذفَ هذِهِ القائمة بشكلٍ دائم؟",
"confirmations.delete_list.title": "أتريد حذف القائمة؟",
"confirmations.discard_edit_media.confirm": "تجاهل",
"confirmations.discard_edit_media.message": "لديك تغييرات غير محفوظة لوصف الوسائط أو معاينتها، أتريد تجاهلها على أي حال؟",
"confirmations.edit.confirm": "تعديل",
"confirmations.edit.message": "التعديل في الحين سوف يُعيد كتابة الرسالة التي أنت بصدد تحريرها. متأكد من أنك تريد المواصلة؟",
"confirmations.edit.title": "هل تريد استبدال المنشور؟",
"confirmations.logout.confirm": "خروج",
"confirmations.logout.message": "متأكد من أنك تريد الخروج؟",
"confirmations.logout.title": "أتريد المغادرة؟",
@ -184,8 +187,10 @@
"confirmations.redraft.title": "أتريد حذف وإعادة صياغة المنشور؟",
"confirmations.reply.confirm": "رد",
"confirmations.reply.message": "الرد في الحين سوف يُعيد كتابة الرسالة التي أنت بصدد كتابتها. متأكد من أنك تريد المواصلة؟",
"confirmations.reply.title": "هل تريد استبدال المنشور؟",
"confirmations.unfollow.confirm": "إلغاء المتابعة",
"confirmations.unfollow.message": "متأكد من أنك تريد إلغاء متابعة {name} ؟",
"confirmations.unfollow.title": "إلغاء متابعة المستخدم؟",
"conversation.delete": "احذف المحادثة",
"conversation.mark_as_read": "اعتبرها كمقروءة",
"conversation.open": "اعرض المحادثة",
@ -221,8 +226,8 @@
"domain_pill.their_username": "مُعرّفُهم الفريد على الخادم. من الممكن العثور على مستخدمين بنفس اسم المستخدم على خوادم مختلفة.",
"domain_pill.username": "اسم المستخدم",
"domain_pill.whats_in_a_handle": "ما المقصود بالمُعرِّف؟",
"domain_pill.who_they_are": "بما أن المعالجات تقول من هو الشخص ومكان وجوده، يمكنك التفاعل مع الناس عبر الشبكة الاجتماعية لـ <button>ActivityPub-Power منصات</button>.",
"domain_pill.who_you_are": "لأن معالجتك تقول من أنت ومكان وجودك، يمكن الناس التفاعل معك عبر الشبكة الاجتماعية لـ <button>ActivityPub-Power منصات</button>.",
"domain_pill.who_they_are": "بما أن المعرفات تقول من هو الشخص ومكان وجوده، يمكنك التفاعل مع الناس عبر الويب الاجتماعي لل <button>منصات التي تعمل ب ActivityPub</button>.",
"domain_pill.who_you_are": "بما أن معرفك يقول من أنت ومكان وجوده، يمكن للناس التفاعل معك عبر الويب الاجتماعي لل <button>منصات التي تعمل ب ActivityPub</button>.",
"domain_pill.your_handle": "عنوانك الكامل:",
"domain_pill.your_server": "منزلك الرقمي، حيث تعيش جميع مشاركاتك. لا تحب هذا؟ إنقل الخوادم في أي وقت واخضر متابعينك أيضًا.",
"domain_pill.your_username": "معرفك الفريد على هذا الخادم. من الممكن العثور على مستخدمين بنفس إسم المستخدم على خوادم مختلفة.",
@ -348,6 +353,9 @@
"home.pending_critical_update.link": "اطّلع على التحديثات",
"home.pending_critical_update.title": "تحديث أمان حرج متوفر!",
"home.show_announcements": "إظهار الإعلانات",
"ignore_notifications_modal.disclaimer": "لا يمكن لـ Mastodon إبلاغ المستخدمين بأنك قد تجاهلت إشعاراتهم. تجاهل الإشعارات لن يمنع إرسال الرسائل نفسها.",
"ignore_notifications_modal.ignore": "تجاهل الإشعارات",
"ignore_notifications_modal.limited_accounts_title": "تجاهل الإشعارات من الحسابات التي هي تحت الإشراف؟",
"interaction_modal.description.favourite": "بفضل حساب على ماستدون، يمكنك إضافة هذا المنشور إلى مفضلتك لإبلاغ الناشر عن تقديرك وكذا للاحتفاظ بالمنشور إلى وقت لاحق.",
"interaction_modal.description.follow": "بفضل حساب في ماستدون، يمكنك متابعة {name} وتلقي منشوراته في موجزات خيطك الرئيس.",
"interaction_modal.description.reblog": "مع حساب في ماستدون، يمكنك تعزيز هذا المنشور ومشاركته مع مُتابِعيك.",
@ -434,7 +442,7 @@
"mute_modal.they_can_mention_and_follow": "سيكون بإمكانه الإشارة إليك ومتابعتك، لكنك لن تره.",
"mute_modal.they_wont_know": "لن يَعرف أنه قد تم كتمه.",
"mute_modal.title": "أتريد كتم المُستخدم؟",
"mute_modal.you_wont_see_mentions": "سوف لن تر المنشورات التي يُشار إليه.",
"mute_modal.you_wont_see_mentions": "لن تر المنشورات التي يُشار فيها إليه.",
"mute_modal.you_wont_see_posts": "سيكون بإمكانه رؤية منشوراتك، لكنك لن ترى منشوراته.",
"navigation_bar.about": "عن",
"navigation_bar.advanced_interface": "افتحه في واجهة الويب المتقدمة",
@ -494,11 +502,13 @@
"notification_requests.accept": "موافقة",
"notification_requests.accept_all": "قبول الكل",
"notification_requests.confirm_accept_all.button": "قبول الكل",
"notification_requests.confirm_accept_all.title": "أتريد قبول طلبات الإشعار؟",
"notification_requests.confirm_dismiss_all.button": "تجاهل الكل",
"notification_requests.dismiss": "تخطي",
"notification_requests.dismiss_all": "تجاهل الكل",
"notification_requests.enter_selection_mode": "اختر",
"notification_requests.exit_selection_mode": "إلغاء",
"notification_requests.explainer_for_limited_account": "تم تصفية الإشعارات من هذا الحساب لأن الحساب تم تقييده من قبل مشرف.",
"notification_requests.notifications_from": "إشعارات من {name}",
"notification_requests.title": "الإشعارات المصفاة",
"notifications.clear": "مسح الإشعارات",
@ -506,6 +516,8 @@
"notifications.column_settings.admin.report": "التبليغات الجديدة:",
"notifications.column_settings.admin.sign_up": "التسجيلات الجديدة:",
"notifications.column_settings.alert": "إشعارات سطح المكتب",
"notifications.column_settings.beta.category": "ميزات تجريبية",
"notifications.column_settings.beta.grouping": "جمّع الإشعارات",
"notifications.column_settings.favourite": "المفضلة:",
"notifications.column_settings.filter_bar.advanced": "عرض جميع الفئات",
"notifications.column_settings.filter_bar.category": "شريط التصفية السريعة",
@ -534,14 +546,21 @@
"notifications.permission_denied": "تنبيهات سطح المكتب غير متوفرة بسبب رفض أذونات المتصفح مسبقاً",
"notifications.permission_denied_alert": "لا يمكن تفعيل إشعارات سطح المكتب، لأن إذن المتصفح قد تم رفضه سابقاً",
"notifications.permission_required": "إشعارات سطح المكتب غير متوفرة لأنه لم يتم منح الإذن المطلوب.",
"notifications.policy.accept": "قبول",
"notifications.policy.accept_hint": "إظهار في الإشعارات",
"notifications.policy.drop": "تجاهل",
"notifications.policy.filter": "تصفية",
"notifications.policy.filter_limited_accounts_hint": "المحدودة من قبل مشرفي الخادم",
"notifications.policy.filter_limited_accounts_title": "حسابات تحت الإشراف",
"notifications.policy.filter_new_accounts.hint": "تم إنشاؤها منذ {days, plural, zero {}one {يوم واحد} two {يومان} few {# أيام} many {# أيام} other {# أيام}}",
"notifications.policy.filter_new_accounts_title": "حسابات جديدة",
"notifications.policy.filter_not_followers_hint": "بما في ذلك الأشخاص الذين يتابعونك أقل من {days, plural, zero {}one {يوم واحد} two {يومان} few {# أيام} many {# أيام} other {# أيام}}",
"notifications.policy.filter_not_followers_hint": "بما في ذلك الأشخاص الذين يتابعونك منذ أقل من {days, plural, zero {}one {يوم واحد} two {يومين} few {# أيام} many {# يوما} other {# أيام}}",
"notifications.policy.filter_not_followers_title": "أشخاص لا يتابعونك",
"notifications.policy.filter_not_following_hint": "حتى توافق عليهم يدويا",
"notifications.policy.filter_not_following_title": "أشخاص لا تتابعهم",
"notifications.policy.filter_private_mentions_hint": "تمت تصفيته إلا إذا أن يكون ردًا على ذكرك أو إذا كنت تتابع الحساب",
"notifications.policy.filter_private_mentions_title": "إشارات خاصة غير مرغوب فيها",
"notifications.policy.filter_private_mentions_hint": "يتم تصفيتها إلا إن كانت ردًا على أحد ردودك أو إذا كنت متابعا للمرسل",
"notifications.policy.filter_private_mentions_title": "الإشارات الخاصة غير المرغوب فيها",
"notifications.policy.title": "إدارة الإشعارات الواردة من…",
"notifications_permission_banner.enable": "تفعيل إشعارات سطح المكتب",
"notifications_permission_banner.how_to_control": "لتلقي الإشعارات عندما لا يكون ماستدون مفتوح، قم بتفعيل إشعارات سطح المكتب، يمكنك التحكم بدقة في أنواع التفاعلات التي تولد إشعارات سطح المكتب من خلال زر الـ{icon} أعلاه بمجرد تفعيلها.",
"notifications_permission_banner.title": "لا تفوت شيئاً أبداً",
@ -650,7 +669,7 @@
"report.reasons.legal_description": "أنت تعتقد أنه ينتهك قانون بلدك أو دولة الخادم",
"report.reasons.other": "شيء آخر",
"report.reasons.other_description": "لا تندرج هذه المشكلة ضمن فئات أخرى",
"report.reasons.spam": "إنها رسالة مزعجة",
"report.reasons.spam": "إنه منشور غير مرغوب فيه",
"report.reasons.spam_description": "روابط خبيثة أو تفاعل كاذب أو ردود متكررة",
"report.reasons.violation": "ينتهك قواعد الخادم",
"report.reasons.violation_description": "تعلم أنه ينتهك قواعد محددة",
@ -668,6 +687,7 @@
"report.unfollow_explanation": "أنت تتابع هذا الحساب، لإزالة مَنشوراته من موجزات خيطك الرئيس، ألغ متابعته.",
"report_notification.attached_statuses": "{count, plural, one {{count} منشور} other {{count} منشورات}} مرفقة",
"report_notification.categories.legal": "أمور قانونية",
"report_notification.categories.legal_sentence": "محتوى غير قانوني",
"report_notification.categories.other": "آخر",
"report_notification.categories.other_sentence": "آخر",
"report_notification.categories.spam": "مزعج",
@ -723,7 +743,7 @@
"status.embed": "إدماج",
"status.favourite": "فضّل",
"status.favourites": "{count, plural, zero {}one {مفضلة واحدة} two {مفضلتان} few {# مفضلات} many {# مفضلات} other {# مفضلات}}",
"status.filter": "تصفية هذه الرسالة",
"status.filter": "تصفية هذا المنشور",
"status.filtered": "مُصفّى",
"status.hide": "إخفاء المنشور",
"status.history.created": "أنشأه {name} {date}",

View file

@ -523,13 +523,18 @@
"notification_requests.confirm_accept_all.message": "Esteu a punt d'acceptar {count, plural, one {una petició de notificació} other {# peticions de notificació}}. N'esteu segurs de continuar?",
"notification_requests.confirm_accept_all.title": "Accepteu peticions de notificació?",
"notification_requests.confirm_dismiss_all.button": "Descarta-les totes",
"notification_requests.confirm_dismiss_all.title": "Descarta la sol·licitud de notificació?",
"notification_requests.dismiss": "Ignora",
"notification_requests.dismiss_all": "Descarta-ho tot",
"notification_requests.enter_selection_mode": "Selecciona",
"notification_requests.exit_selection_mode": "Cancel·la",
"notification_requests.explainer_for_limited_account": "S'han filtrat les notificacions d'aquest compte perquè un moderador l'ha limitat.",
"notification_requests.explainer_for_limited_remote_account": "S'han filtrat les notificacions d'aquest compte perquè un moderador ha limitat el compte o el seu servidor.",
"notification_requests.maximize": "Maximitza",
"notification_requests.minimize_banner": "Minimitza el bàner de notificacions filtrades",
"notification_requests.notifications_from": "Notificacions de {name}",
"notification_requests.title": "Notificacions filtrades",
"notification_requests.view": "Mostra les notificacions",
"notifications.clear": "Esborra les notificacions",
"notifications.clear_confirmation": "Segur que vols esborrar permanentment totes les teves notificacions?",
"notifications.clear_title": "Esborrar les notificacions?",
@ -566,6 +571,12 @@
"notifications.permission_denied": "Les notificacions descriptori no estan disponibles perquè prèviament sha denegat el permís al navegador",
"notifications.permission_denied_alert": "No es poden activar les notificacions de l'escriptori perquè abans s'ha denegat el permís del navegador",
"notifications.permission_required": "Les notificacions d'escriptori no estan disponibles perquè el permís requerit no ha estat concedit.",
"notifications.policy.accept": "Acceptar",
"notifications.policy.accept_hint": "Mostra a notificacions",
"notifications.policy.drop": "Ignorar",
"notifications.policy.drop_hint": "Envia al buit, no es tornarà a veure mai més",
"notifications.policy.filter": "Filtrar",
"notifications.policy.filter_hint": "Filtrar",
"notifications.policy.filter_limited_accounts_hint": "Limitat pels moderadors del servidor",
"notifications.policy.filter_limited_accounts_title": "Comptes moderats",
"notifications.policy.filter_new_accounts.hint": "Creat {days, plural, one {ahir} other {durant els # dies passats}}",
@ -576,6 +587,7 @@
"notifications.policy.filter_not_following_title": "Persones que no seguiu",
"notifications.policy.filter_private_mentions_hint": "Filtrat si no és que és en resposta a una menció vostra o si seguiu el remitent",
"notifications.policy.filter_private_mentions_title": "Mencions privades no sol·licitades",
"notifications.policy.title": "Gestiona les notificacions des de…",
"notifications_permission_banner.enable": "Activa les notificacions descriptori",
"notifications_permission_banner.how_to_control": "Per a rebre notificacions quan Mastodon no és obert cal activar les notificacions descriptori. Pots controlar amb precisió quins tipus dinteraccions generen notificacions descriptori després dactivar el botó {icon} de dalt.",
"notifications_permission_banner.title": "No et perdis mai res",

View file

@ -11,6 +11,7 @@
"about.not_available": "Ĉi tiu informo ne estas disponebla ĉe ĉi tiu servilo.",
"about.powered_by": "Malcentrigita socia retejo pere de {mastodon}",
"about.rules": "Regularo de la servilo",
"account.account_note_header": "Personaj notoj",
"account.add_or_remove_from_list": "Aldoni al aŭ forigi el listoj",
"account.badges.bot": "Roboto",
"account.badges.group": "Grupo",
@ -34,7 +35,9 @@
"account.follow_back": "Sekvu reen",
"account.followers": "Sekvantoj",
"account.followers.empty": "Ankoraŭ neniu sekvas ĉi tiun uzanton.",
"account.followers_counter": "{count, plural, one{{counter} sekvanto} other {{counter} sekvantoj}}",
"account.following": "Sekvatoj",
"account.following_counter": "{count, plural, one {{counter} sekvato} other {{counter} sekvatoj}}",
"account.follows.empty": "La uzanto ankoraŭ ne sekvas iun ajn.",
"account.go_to_profile": "Iri al profilo",
"account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
@ -60,6 +63,7 @@
"account.requested_follow": "{name} petis sekvi vin",
"account.share": "Diskonigi la profilon de @{name}",
"account.show_reblogs": "Montri diskonigojn de @{name}",
"account.statuses_counter": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}}",
"account.unblock": "Malbloki @{name}",
"account.unblock_domain": "Malbloki la domajnon {domain}",
"account.unblock_short": "Malbloki",
@ -85,6 +89,9 @@
"announcement.announcement": "Anoncoj",
"attachments_list.unprocessed": "(neprilaborita)",
"audio.hide": "Kaŝi aŭdion",
"block_modal.show_less": "Montri malpli",
"block_modal.show_more": "Montri pli",
"block_modal.title": "Ĉu bloki uzanton?",
"boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
"bundle_column_error.copy_stacktrace": "Kopii la eraran raporton",
"bundle_column_error.error.body": "La petita paĝo ne povas redonitis. Eble estas eraro.",
@ -144,7 +151,10 @@
"compose_form.poll.duration": "Daŭro de la balotenketo",
"compose_form.poll.switch_to_multiple": "Ŝanĝi la balotenketon por permesi multajn elektojn",
"compose_form.poll.switch_to_single": "Ŝanĝi la balotenketon por permesi unu solan elekton",
"compose_form.publish": "Afiŝo",
"compose_form.publish_form": "Afiŝi",
"compose_form.reply": "Respondi",
"compose_form.save_changes": "Ĝisdatigi",
"compose_form.spoiler.marked": "Forigi la averton de enhavo",
"compose_form.spoiler.unmarked": "Aldoni averton de enhavo",
"confirmation_modal.cancel": "Nuligi",

View file

@ -356,6 +356,17 @@
"home.pending_critical_update.link": "Faic na h-ùrachaidhean",
"home.pending_critical_update.title": "Tha ùrachadh tèarainteachd èiginneach ri fhaighinn!",
"home.show_announcements": "Seall na brathan-fios",
"ignore_notifications_modal.disclaimer": "Chan urrainn do Mhastodon innse do cheachdaichean gun do leig thu seachad na brathan uapa. Cha bhac leigeil seachad nam brathan gun dèid na teachdaireachdan fhèin a chur.",
"ignore_notifications_modal.filter_instead": "Criathraich na àite",
"ignore_notifications_modal.filter_to_act_users": "S urrainn dhut gabhail ri cleachdaichean, an diùltadh no gearan a dhèanamh mun dèidhinn fhathast",
"ignore_notifications_modal.filter_to_avoid_confusion": "Cuidichidh criathradh le rù-rà ma dhfhaoidte",
"ignore_notifications_modal.filter_to_review_separately": "S urrainn dhut sùil fa leth a thoirt air na brathran criathraichte",
"ignore_notifications_modal.ignore": "Leig seachad na brathan",
"ignore_notifications_modal.limited_accounts_title": "A bheil thu airson na brathan o chunntasan fo mhaorsainneachd a leigeil seachad?",
"ignore_notifications_modal.new_accounts_title": "A bheil thu airson na brathan o chunntasan ùra a leigeil seachad?",
"ignore_notifications_modal.not_followers_title": "A bheil thu airson na brathan o dhaoine nach eil gad leantainn a leigeil seachad?",
"ignore_notifications_modal.not_following_title": "A bheil thu airson na brathan o dhaoine nach eil thu a leantainn a leigeil seachad?",
"ignore_notifications_modal.private_mentions_title": "A bheil thu airson na brathan o iomraidhean phrìobhaideach gun iarraidh a leigeil seachad?",
"interaction_modal.description.favourite": "Le cunntas air Mastodon, s urrainn dhut am post seo a chur ris na h-annsachdan airson innse dhan ùghdar gu bheil e a còrdadh dhut s a shàbhaladh do uaireigin eile.",
"interaction_modal.description.follow": "Le cunntas air Mastodon, s urrainn dhut {name} a leantainn ach am faigh thu na postaichean aca nad dhachaigh.",
"interaction_modal.description.reblog": "Le cunntas air Mastodon, s urrainn dhut am post seo a bhrosnachadh gus a cho-roinneadh leis an luchd-leantainn agad fhèin.",
@ -482,6 +493,11 @@
"notification.favourite": "Is annsa le {name} am post agad",
"notification.follow": "Tha {name} gad leantainn a-nis",
"notification.follow_request": "Dhiarr {name} gad leantainn",
"notification.label.mention": "Iomradh",
"notification.label.private_mention": "Iomradh prìobhaideach",
"notification.label.private_reply": "Freagairt phrìobhaideach",
"notification.label.reply": "Freagairt",
"notification.mention": "Iomradh",
"notification.moderation-warning.learn_more": "Barrachd fiosrachaidh",
"notification.moderation_warning": "Fhuair thu rabhadh on mhaorsainneachd",
"notification.moderation_warning.action_delete_statuses": "Chaidh cuid dhe na postaichean agad a thoirt air falbh.",
@ -502,11 +518,26 @@
"notification.status": "Phostaich {name} rud",
"notification.update": "Dheasaich {name} post",
"notification_requests.accept": "Gabh ris",
"notification_requests.accept_all": "Gabh ris na h-uile",
"notification_requests.accept_multiple": "{count, plural, one {Gabh ri # iarrtas} two {Gabh ri # iarrtas} few {Gabh ri # iarrtasan} other {Gabh ri # iarrtas}}",
"notification_requests.confirm_accept_all.button": "Gabh ris na h-uile",
"notification_requests.confirm_accept_all.message": "Tha thu gu bhith gabhail ri {count, plural, one {# iarrtas bratha} two {# iarrtas bratha} few {# iarrtasan bratha} other {# iarrtas bratha}} a leigeil seachad. A bheil thu cinnteach gu bheil thu airson leantainn air adhart?",
"notification_requests.confirm_accept_all.title": "A bheil thu airson gabhail ri iarrtasan bratha?",
"notification_requests.confirm_dismiss_all.button": "Leig seachad na h-uile",
"notification_requests.confirm_dismiss_all.message": "Tha thu gu bhith {count, plural, one {# iarrtas bratha} two {# iarrtas bratha} few {# iarrtasan bratha} other {# iarrtas bratha}} a leigeil seachad. Chan fhaigh thu grèim {count, plural, one {air} two {orra} few {orra} other {orra}} a-rithist gun duilgheadas. A bheil thu cinnteach gu bheil thu airson leantainn air adhart?",
"notification_requests.confirm_dismiss_all.title": "A bheil thu airson iarrtasan bratha a leigeil seachad?",
"notification_requests.dismiss": "Leig seachad",
"notification_requests.dismiss_all": "Leig seachad na h-uile",
"notification_requests.dismiss_multiple": "{count, plural, one {Leig seachad # iarrtas} two {Leig seachad # iarrtas} few {Leig seachad # iarrtasan} other {Leig seachad # iarrtas}}",
"notification_requests.enter_selection_mode": "Tagh",
"notification_requests.exit_selection_mode": "Sguir dheth",
"notification_requests.explainer_for_limited_account": "Chaidh na brathan on chunntas seo a chriathradh on a chaidh an cunntas a chuingeachadh le maor.",
"notification_requests.explainer_for_limited_remote_account": "Chaidh na brathan on chunntas seo a chriathradh on a chaidh an cunntas no am frithealaiche aige a chuingeachadh le maor.",
"notification_requests.maximize": "Làn-mheudaich",
"notification_requests.minimize_banner": "Fìor-lùghdaich bratach nam brathan criathraichte",
"notification_requests.notifications_from": "Brathan o {name}",
"notification_requests.title": "Brathan criathraichte",
"notification_requests.view": "Seall na brathan",
"notifications.clear": "Falamhaich na brathan",
"notifications.clear_confirmation": "A bheil thu cinnteach gu bheil thu airson na brathan uile agad fhalamhachadh gu buan?",
"notifications.clear_title": "A bheil thu airson na brathan fhalamhachadh?",
@ -543,6 +574,14 @@
"notifications.permission_denied": "Chan eil brathan deasga ri fhaighinn on a chaidh iarrtas ceadan a bhrabhsair a dhiùltadh cheana",
"notifications.permission_denied_alert": "Cha ghabh brathan deasga a chur an comas on a chaidh iarrtas ceadan a bhrabhsair a dhiùltadh cheana",
"notifications.permission_required": "Chan eil brathan deasga ri fhaighinn on nach deach an cead riatanach a thoirt seachad.",
"notifications.policy.accept": "Gabh ris",
"notifications.policy.accept_hint": "Seall sna brathan",
"notifications.policy.drop": "Leig seachad",
"notifications.policy.drop_hint": "Cuir a-mach à sealladh gu buan",
"notifications.policy.filter": "Criathraich",
"notifications.policy.filter_hint": "Cuir gu bogsa a-steach nam brathan criathraichte",
"notifications.policy.filter_limited_accounts_hint": "Cuingichte le maoir an fhrithealaiche",
"notifications.policy.filter_limited_accounts_title": "Cunntasan fo mhaorsainneachd",
"notifications.policy.filter_new_accounts.hint": "A chaidh a chruthachadh o chionn {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}}",
"notifications.policy.filter_new_accounts_title": "Cunntasan ùra",
"notifications.policy.filter_not_followers_hint": "A gabhail a-staigh an fheadhainn a lean ort nas lugha na {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}} seo chaidh",
@ -551,6 +590,7 @@
"notifications.policy.filter_not_following_title": "Daoine nach eil thu a leantainn",
"notifications.policy.filter_private_mentions_hint": "Criathraichte ach ma tha e a freagairt do dhiomradh agad fhèin no ma tha thu a leantainn an t-seòladair",
"notifications.policy.filter_private_mentions_title": "Iomraidhean prìobhaideach o choigrich",
"notifications.policy.title": "Stiùirich na brathan o…",
"notifications_permission_banner.enable": "Cuir brathan deasga an comas",
"notifications_permission_banner.how_to_control": "Airson brathan fhaighinn nuair nach eil Mastodon fosgailte, cuir na brathan deasga an comas. Tha an smachd agad fhèin air dè na seòrsaichean de chonaltradh a ghineas brathan deasga leis a phutan {icon} gu h-àrd nuair a bhios iad air an cur an comas.",
"notifications_permission_banner.title": "Na caill dad gu bràth tuilleadh",
@ -791,6 +831,7 @@
"timeline_hint.remote_resource_not_displayed": "Cha dèid {resource} o fhrithealaichean eile a shealltainn.",
"timeline_hint.resources.followers": "luchd-leantainn",
"timeline_hint.resources.follows": "an fheadhainn gan leantainn",
"timeline_hint.resources.replies": "Cuid de na freagairtean",
"timeline_hint.resources.statuses": "postaichean nas sine",
"trends.counter_by_accounts": "{count, plural, one {{counter} neach} two {{counter} neach} few {{counter} daoine} other {{counter} duine}} {days, plural, one {san {days} latha} two {san {days} latha} few {sna {days} làithean} other {sna {days} latha}} seo chaidh",
"trends.trending_now": "A treandadh an-dràsta",

View file

@ -23,15 +23,19 @@
"column.notifications": "Nziọkwà",
"column.pins": "Pinned post",
"column_header.pin": "Gbado na profaịlụ gị",
"column_header.show_settings": "Gosi mwube",
"column_subheading.settings": "Mwube",
"community.column_settings.media_only": "Media only",
"compose.language.change": "Gbanwee asụsụ",
"compose.language.search": "Chọọ asụsụ...",
"compose.published.open": "Mepe",
"compose_form.direct_message_warning_learn_more": "Mụtakwuo",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.placeholder": "What is on your mind?",
"compose_form.poll.single": "Họrọ otu",
"compose_form.publish_form": "Publish",
"compose_form.reply": "Zaa",
"compose_form.spoiler.marked": "Text is hidden behind warning",
"compose_form.spoiler.unmarked": "Text is not hidden",
"confirmation_modal.cancel": "Kagbuo",
@ -49,7 +53,9 @@
"domain_pill.username": "Ahaojiaru",
"embed.instructions": "Embed this status on your website by copying the code below.",
"emoji_button.activity": "Mmemme",
"emoji_button.food": "Oriri & Ọṅụṅụ",
"emoji_button.label": "Tibanye emoji",
"emoji_button.people": "Mmadụ",
"emoji_button.search": "Chọọ...",
"emoji_button.symbols": "Ọdịmara",
"empty_column.account_timeline": "No posts found",
@ -95,15 +101,19 @@
"keyboard_shortcuts.toot": "to start a brand new post",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list",
"lightbox.close": "Mechie",
"lists.delete": "Hichapụ ndepụta",
"lists.edit": "Dezie ndepụta",
"lists.subheading": "Ndepụta gị",
"navigation_bar.about": "Maka",
"navigation_bar.bookmarks": "Ebenrụtụakā",
"navigation_bar.discover": "Chọpụta",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.favourites": "Mmasị",
"navigation_bar.lists": "Ndepụta",
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
"notification.reblog": "{name} boosted your status",
"notification_requests.enter_selection_mode": "Họrọ",
"onboarding.actions.go_to_explore": "See what's trending",
"onboarding.actions.go_to_home": "Go to your home feed",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",

View file

@ -356,6 +356,15 @@
"home.pending_critical_update.link": "업데이트 보기",
"home.pending_critical_update.title": "긴급 보안 업데이트가 있습니다!",
"home.show_announcements": "공지사항 보기",
"ignore_notifications_modal.disclaimer": "마스토돈은 당신이 그들의 알림을 무시했다는 걸 알려줄 수 없습니다. 알림을 무시한다고 해서 메시지가 오지 않는 것은 아닙니다.",
"ignore_notifications_modal.filter_instead": "대신 필터로 거르기",
"ignore_notifications_modal.filter_to_act_users": "여전히 사용자를 수락, 거절, 신고할 수 있습니다",
"ignore_notifications_modal.ignore": "알림 무시",
"ignore_notifications_modal.limited_accounts_title": "중재된 계정의 알림을 무시할까요?",
"ignore_notifications_modal.new_accounts_title": "새 계정의 알림을 무시할까요?",
"ignore_notifications_modal.not_followers_title": "나를 팔로우하지 않는 사람들의 알림을 무시할까요?",
"ignore_notifications_modal.not_following_title": "내가 팔로우하지 않는 사람들의 알림을 무시할까요?",
"ignore_notifications_modal.private_mentions_title": "요청하지 않은 개인 멘션 알림을 무시할까요?",
"interaction_modal.description.favourite": "마스토돈 계정을 통해, 게시물을 좋아하는 것으로 작성자에게 호의를 표하고 나중에 보기 위해 저장할 수 있습니다.",
"interaction_modal.description.follow": "마스토돈 계정을 통해, {name} 님을 팔로우 하고 그의 게시물을 홈 피드에서 받아 볼 수 있습니다.",
"interaction_modal.description.reblog": "마스토돈 계정을 통해, 이 게시물을 부스트 하고 자신의 팔로워들에게 공유할 수 있습니다.",
@ -441,7 +450,7 @@
"mute_modal.indefinite": "내가 뮤트를 해제하기 전까지",
"mute_modal.show_options": "옵션 표시",
"mute_modal.they_can_mention_and_follow": "나를 멘션하거나 팔로우 할 수 있습니다, 다만 나에게 안 보일 것입니다.",
"mute_modal.they_wont_know": "내가 차단했다는 사실을 모를 것입니다.",
"mute_modal.they_wont_know": "내가 뮤트했다는 사실을 모를 것입니다.",
"mute_modal.title": "사용자를 뮤트할까요?",
"mute_modal.you_wont_see_mentions": "그를 멘션하는 게시물을 더는 보지 않게 됩니다.",
"mute_modal.you_wont_see_posts": "내가 작성한 게시물을 볼 수는 있지만, 나는 그가 작성한 것을 보지 않게 됩니다.",
@ -482,6 +491,11 @@
"notification.favourite": "{name} 님이 내 게시물을 좋아합니다",
"notification.follow": "{name} 님이 나를 팔로우했습니다",
"notification.follow_request": "{name} 님이 팔로우 요청을 보냈습니다",
"notification.label.mention": "멘션",
"notification.label.private_mention": "개인 멘션",
"notification.label.private_reply": "개인 답글",
"notification.label.reply": "답글",
"notification.mention": "멘션",
"notification.moderation-warning.learn_more": "더 알아보기",
"notification.moderation_warning": "중재 경고를 받았습니다",
"notification.moderation_warning.action_delete_statuses": "게시물 몇 개가 삭제되었습니다.",
@ -502,13 +516,26 @@
"notification.status": "{name} 님이 방금 게시물을 올렸습니다",
"notification.update": "{name} 님이 게시물을 수정했습니다",
"notification_requests.accept": "수락",
"notification_requests.accept_all": "모두 수락",
"notification_requests.accept_multiple": "{count, plural, other {#개의 요청 수락하기}}",
"notification_requests.confirm_accept_all.button": "모두 수락",
"notification_requests.confirm_accept_all.message": "{count, plural, other {#개의 요청}}을 수락하려 합니다. 계속 진행할까요?",
"notification_requests.confirm_accept_all.title": "알림 요청을 수락할까요?",
"notification_requests.confirm_dismiss_all.button": "모두 지우기",
"notification_requests.confirm_dismiss_all.message": "{count, plural, other {#개의 요청}}을 지우려고 합니다. {count, plural, other {}}다시 접근하기 어렵습니다. 계속할까요?",
"notification_requests.confirm_dismiss_all.title": "알림 요청을 지울까요?",
"notification_requests.dismiss": "지우기",
"notification_requests.dismiss_all": "모두 지우기",
"notification_requests.dismiss_multiple": "{count, plural, other {#개의 요청 지우기}}",
"notification_requests.enter_selection_mode": "선택",
"notification_requests.exit_selection_mode": "취소",
"notification_requests.explainer_for_limited_account": "이 계정은 중재자에 의해 제한되었기 때문에 이 계정의 알림은 걸러졌습니다.",
"notification_requests.explainer_for_limited_remote_account": "이 계정 혹은 그가 속한 서버는 중재자에 의해 제한되었기 때문에 이 계정의 알림은 걸러졌습니다.",
"notification_requests.maximize": "최대화",
"notification_requests.minimize_banner": "걸러진 알림 배너 최소화",
"notification_requests.notifications_from": "{name} 님으로부터의 알림",
"notification_requests.title": "걸러진 알림",
"notification_requests.view": "알림 보기",
"notifications.clear": "알림 비우기",
"notifications.clear_confirmation": "정말로 알림을 삭제하시겠습니까?",
"notifications.clear_title": "알림을 모두 지울까요?",
@ -546,8 +573,11 @@
"notifications.permission_denied_alert": "이전에 브라우저 권한이 거부되었기 때문에, 데스크탑 알림이 활성화 될 수 없습니다.",
"notifications.permission_required": "필요한 권한이 승인되지 않아 데스크탑 알림을 사용할 수 없습니다.",
"notifications.policy.accept": "허용",
"notifications.policy.accept_hint": "알림 목록에 표시",
"notifications.policy.drop": "무시",
"notifications.policy.drop_hint": "공허로 보내고, 다시는 보지 않습니다",
"notifications.policy.filter": "필터",
"notifications.policy.filter_hint": "걸러진 알림 목록으로 보내기",
"notifications.policy.filter_limited_accounts_hint": "서버 중재자에 의해 제한됨",
"notifications.policy.filter_limited_accounts_title": "중재된 계정",
"notifications.policy.filter_new_accounts.hint": "{days, plural, one {하루} other {#일}} 안에 만들어진",
@ -558,6 +588,7 @@
"notifications.policy.filter_not_following_title": "내가 팔로우하지 않는 사람들",
"notifications.policy.filter_private_mentions_hint": "내가 한 멘션에 단 답글이거나 내가 발신자를 팔로우 한 것이 아닌 이상 걸러집니다",
"notifications.policy.filter_private_mentions_title": "청하지 않은 개인적인 멘션",
"notifications.policy.title": "…의 알림 설정",
"notifications_permission_banner.enable": "데스크탑 알림 활성화",
"notifications_permission_banner.how_to_control": "마스토돈이 열려 있지 않을 때에도 알림을 받으려면, 데스크탑 알림을 활성화 하세요. 당신은 어떤 종류의 반응이 데스크탑 알림을 발생할 지를 {icon} 버튼을 통해 세세하게 설정할 수 있습니다.",
"notifications_permission_banner.title": "아무것도 놓치지 마세요",
@ -795,11 +826,11 @@
"time_remaining.minutes": "{number} 분 남음",
"time_remaining.moments": "남은 시간",
"time_remaining.seconds": "{number} 초 남음",
"timeline_hint.remote_resource_not_displayed": "다른 서버의 {resource} 표시할 수 없습니다.",
"timeline_hint.resources.followers": "팔로워",
"timeline_hint.resources.follows": "팔로우",
"timeline_hint.resources.replies": "몇몇 답글",
"timeline_hint.resources.statuses": "이전 게시물",
"timeline_hint.remote_resource_not_displayed": "다른 서버의 {resource} 표시할 수 없습니다.",
"timeline_hint.resources.followers": "팔로워",
"timeline_hint.resources.follows": "팔로우",
"timeline_hint.resources.replies": "몇몇 답글",
"timeline_hint.resources.statuses": "이전 게시물",
"trends.counter_by_accounts": "이전 {days}일 동안 {counter} 명의 사용자",
"trends.trending_now": "지금 유행 중",
"ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",

View file

@ -11,6 +11,7 @@
"about.not_available": "Tieto informácie neboli sprístupnené na tomto serveri.",
"about.powered_by": "Decentralizovaná sociálna sieť na základe technológie {mastodon}",
"about.rules": "Pravidlá servera",
"account.account_note_header": "Osobná poznámka",
"account.add_or_remove_from_list": "Pridať alebo odobrať zo zoznamov",
"account.badges.bot": "Bot",
"account.badges.group": "Skupina",

View file

@ -355,6 +355,9 @@
"home.pending_critical_update.link": "Glejte posodobitve",
"home.pending_critical_update.title": "Na voljo je kritična varnostna posodobbitev!",
"home.show_announcements": "Pokaži obvestila",
"ignore_notifications_modal.filter_to_avoid_confusion": "Filtriranje pomaga pri izogibanju morebitni zmedi",
"ignore_notifications_modal.filter_to_review_separately": "Filtrirana obvestila lahko pregledate ločeno",
"ignore_notifications_modal.ignore": "Prezri obvestila",
"interaction_modal.description.favourite": "Z računom na Mastodonu lahko to objavo postavite med priljubljene in tako avtorju nakažete, da jo cenite, in jo shranite za kasneje.",
"interaction_modal.description.follow": "Z računom na Mastodonu lahko sledite {name}, da prejemate njihove objave v svoj domači vir.",
"interaction_modal.description.reblog": "Z računom na Mastodonu lahko izpostavite to objavo, tako da jo delite s svojimi sledilci.",
@ -481,6 +484,9 @@
"notification.favourite": "{name} je vzljubil/a vašo objavo",
"notification.follow": "{name} vam sledi",
"notification.follow_request": "{name} vam želi slediti",
"notification.label.private_mention": "Zasebna omemba",
"notification.label.private_reply": "Zasebni odgovor",
"notification.label.reply": "Odgovori",
"notification.moderation-warning.learn_more": "Več o tem",
"notification.moderation_warning": "Prejeli ste opozorilo moderatorjev",
"notification.moderation_warning.action_delete_statuses": "Nekatere vaše objave so odstranjene.",
@ -501,10 +507,17 @@
"notification.status": "{name} je pravkar objavil/a",
"notification.update": "{name} je uredil(a) objavo",
"notification_requests.accept": "Sprejmi",
"notification_requests.accept_all": "Sprejmi vse",
"notification_requests.confirm_accept_all.button": "Sprejmi vse",
"notification_requests.confirm_dismiss_all.button": "Opusti vse",
"notification_requests.dismiss": "Zavrni",
"notification_requests.dismiss_all": "Opusti vse",
"notification_requests.enter_selection_mode": "Izberi",
"notification_requests.exit_selection_mode": "Prekliči",
"notification_requests.maximize": "Maksimiraj",
"notification_requests.notifications_from": "Obvestila od {name}",
"notification_requests.title": "Filtrirana obvestila",
"notification_requests.view": "Pokaži obvestila",
"notifications.clear": "Počisti obvestila",
"notifications.clear_confirmation": "Ali ste prepričani, da želite trajno izbrisati vsa svoja obvestila?",
"notifications.clear_title": "Želite počistiti obvestila?",
@ -541,6 +554,9 @@
"notifications.permission_denied": "Namizna obvestila niso na voljo zaradi poprej zavrnjene zahteve dovoljenja brskalnika.",
"notifications.permission_denied_alert": "Namiznih obvestil ni mogoče omogočiti, ker je bilo dovoljenje brskalnika že prej zavrnjeno",
"notifications.permission_required": "Namizna obvestila niso na voljo, ker zahtevano dovoljenje ni bilo podeljeno.",
"notifications.policy.accept": "Sprejmi",
"notifications.policy.accept_hint": "Pokaži med obvestili",
"notifications.policy.drop": "Prezri",
"notifications.policy.filter_new_accounts.hint": "Ustvarjen v {days, plural, one {zadnjem # dnevu} two {zadnjih # dnevih} few {zadnjih # dnevih} other {zadnjih # dnevih}}",
"notifications.policy.filter_new_accounts_title": "Novi računi",
"notifications.policy.filter_not_followers_hint": "Vključujoč ljudi, ki vam sledijo manj kot {days, plural, one {# dan} two {# dneva} few {# dni} other {# dni}}",
@ -549,6 +565,7 @@
"notifications.policy.filter_not_following_title": "Ljudje, ki jim ne sledite",
"notifications.policy.filter_private_mentions_hint": "Filtrirano, razen če je odgovor na vašo lastno omembo ali če sledite pošiljatelju",
"notifications.policy.filter_private_mentions_title": "Neželene zasebne omembe",
"notifications.policy.title": "Upravljaj obvestila od ...",
"notifications_permission_banner.enable": "Omogoči obvestila na namizju",
"notifications_permission_banner.how_to_control": "Če želite prejemati obvestila, ko Mastodon ni odprt, omogočite namizna obvestila. Natančno lahko nadzirate, katere vrste interakcij naj tvorijo namizna obvestila; ko so omogočena, za to uporabite gumb {icon} zgoraj.",
"notifications_permission_banner.title": "Nikoli ne zamudite ničesar",
@ -789,6 +806,7 @@
"timeline_hint.remote_resource_not_displayed": "{resource} z drugih strežnikov ni prikazano.",
"timeline_hint.resources.followers": "sledilcev",
"timeline_hint.resources.follows": "Sledi",
"timeline_hint.resources.replies": "Nekaj odgovorov",
"timeline_hint.resources.statuses": "Starejše objave",
"trends.counter_by_accounts": "{count, plural, one {{count} oseba} two {{count} osebi} few {{count} osebe} other {{count} oseb}} v {days, plural, one {zadnjem {day} dnevu} two {zadnjih {days} dneh} few {zadnjih {days} dneh} other {zadnjih {days} dneh}}",
"trends.trending_now": "Zdaj v trendu",

View file

@ -1,5 +1,5 @@
{
"about.blocks": "เซิร์ฟเวอร์ที่มีการกลั่นกรอง",
"about.blocks": "เซิร์ฟเวอร์ที่ได้รับการกลั่นกรอง",
"about.contact": "ติดต่อ:",
"about.disclaimer": "Mastodon เป็นซอฟต์แวร์เสรี โอเพนซอร์ส และเครื่องหมายการค้าของ Mastodon gGmbH",
"about.domain_blocks.no_reason_available": "เหตุผลไม่พร้อมใช้งาน",
@ -357,10 +357,13 @@
"home.pending_critical_update.title": "มีการอัปเดตความปลอดภัยสำคัญพร้อมใช้งาน!",
"home.show_announcements": "แสดงประกาศ",
"ignore_notifications_modal.filter_instead": "กรองแทน",
"ignore_notifications_modal.filter_to_act_users": "คุณจะยังสามารถยอมรับ ปฏิเสธ หรือรายงานผู้ใช้",
"ignore_notifications_modal.ignore": "เพิกเฉยการแจ้งเตือน",
"ignore_notifications_modal.limited_accounts_title": "เพิกเฉยการแจ้งเตือนจากบัญชีที่ได้รับการกลั่นกรอง?",
"ignore_notifications_modal.new_accounts_title": "เพิกเฉยการแจ้งเตือนจากบัญชีใหม่?",
"ignore_notifications_modal.not_followers_title": "เพิกเฉยการแจ้งเตือนจากผู้คนที่ไม่ได้ติดตามคุณ?",
"ignore_notifications_modal.not_following_title": "เพิกเฉยการแจ้งเตือนจากผู้คนที่คุณไม่ได้ติดตาม?",
"ignore_notifications_modal.private_mentions_title": "เพิกเฉยการแจ้งเตือนจากการกล่าวถึงแบบส่วนตัวที่ไม่พึงประสงค์?",
"interaction_modal.description.favourite": "ด้วยบัญชีใน Mastodon คุณสามารถชื่นชอบโพสต์นี้เพื่อแจ้งให้ผู้สร้างทราบว่าคุณชื่นชมโพสต์และบันทึกโพสต์ไว้สำหรับภายหลัง",
"interaction_modal.description.follow": "ด้วยบัญชีใน Mastodon คุณสามารถติดตาม {name} เพื่อรับโพสต์ของเขาในฟีดหน้าแรกของคุณ",
"interaction_modal.description.reblog": "ด้วยบัญชีใน Mastodon คุณสามารถดันโพสต์นี้เพื่อแชร์โพสต์กับผู้ติดตามของคุณเอง",
@ -565,7 +568,9 @@
"notifications.policy.accept": "ยอมรับ",
"notifications.policy.accept_hint": "แสดงในการแจ้งเตือน",
"notifications.policy.drop": "เพิกเฉย",
"notifications.policy.filter": "กรอง",
"notifications.policy.filter_hint": "ส่งไปยังกล่องขาเข้าการแจ้งเตือนที่กรองอยู่",
"notifications.policy.filter_limited_accounts_title": "บัญชีที่ได้รับการกลั่นกรอง",
"notifications.policy.filter_new_accounts.hint": "สร้างขึ้นภายใน {days, plural, other {# วัน}}ที่ผ่านมา",
"notifications.policy.filter_new_accounts_title": "บัญชีใหม่",
"notifications.policy.filter_not_followers_hint": "รวมถึงผู้คนที่ได้ติดตามคุณน้อยกว่า {days, plural, other {# วัน}}",

View file

@ -35,9 +35,9 @@
"account.follow_back": "Стежити також",
"account.followers": "Підписники",
"account.followers.empty": "Ніхто ще не підписаний на цього користувача.",
"account.followers_counter": "{count, plural, one {{counter} підписник} few {{counter} підписники} many {{counter} підписників} other {{counter} підписники}}",
"account.followers_counter": "{count, plural, one {{counter} підписник} few {{counter} підписники} many {{counter} підписників} other {{counter} підписник}}",
"account.following": "Ви стежите",
"account.following_counter": "{count, plural, one {{counter} підписка} few {{counter} підписки} many {{counter} підписок} other {{counter} підписки}}",
"account.following_counter": "{count, plural, one {{counter} підписка} few {{counter} підписки} many {{counter} підписок} other {{counter} підписка}}",
"account.follows.empty": "Цей користувач ще ні на кого не підписався.",
"account.go_to_profile": "Перейти до профілю",
"account.hide_reblogs": "Сховати поширення від @{name}",
@ -356,9 +356,17 @@
"home.pending_critical_update.link": "Переглянути оновлення",
"home.pending_critical_update.title": "Доступне критичне оновлення безпеки!",
"home.show_announcements": "Показати оголошення",
"ignore_notifications_modal.disclaimer": "Mastodon не може повідомити користувачів, що ви проігнорували їх повідомлення. Ігнорування сповіщень не зупинить надсилання повідомлень.",
"ignore_notifications_modal.filter_instead": "Натомість фільтрувати",
"ignore_notifications_modal.filter_to_act_users": "Ви все ще зможете прийняти, відхилити або поскаржитися на користувачів",
"ignore_notifications_modal.filter_to_avoid_confusion": "Фільтрування допомагає уникнути потенційної плутанини",
"ignore_notifications_modal.filter_to_review_separately": "Ви можете переглянути відфільтровані сповіщення окремо",
"ignore_notifications_modal.ignore": "Ігнорувати сповіщення",
"ignore_notifications_modal.limited_accounts_title": "Ігнорувати сповіщення від модерованих облікових записів?",
"ignore_notifications_modal.new_accounts_title": "Ігнорувати сповіщення від нових облікових записів?",
"ignore_notifications_modal.not_followers_title": "Ігнорувати сповіщення від людей, які не підписані на вас?",
"ignore_notifications_modal.not_following_title": "Ігнорувати сповіщення від людей, на яких ви не підписалися?",
"ignore_notifications_modal.private_mentions_title": "Ігнорувати сповіщення від небажаних приватних згадок?",
"interaction_modal.description.favourite": "Маючи обліковий запис на Mastodon, ви можете вподобати цей допис, щоб дати автору знати, що ви його цінуєте, і зберегти його на потім.",
"interaction_modal.description.follow": "Маючи обліковий запис на Mastodon, ви можете підписатися на {name}, щоб отримувати дописи цього користувача у свою стрічку.",
"interaction_modal.description.reblog": "Маючи обліковий запис на Mastodon, ви можете поширити цей допис, щоб поділитися ним зі своїми підписниками.",
@ -485,8 +493,11 @@
"notification.favourite": "Ваш допис сподобався {name}",
"notification.follow": "{name} підписалися на вас",
"notification.follow_request": "{name} відправили запит на підписку",
"notification.label.mention": "Згадка",
"notification.label.private_mention": "Особиста згадка",
"notification.label.private_reply": "Приватна відповідь",
"notification.label.reply": "Відповісти",
"notification.label.reply": "Відповідь",
"notification.mention": "Згадка",
"notification.moderation-warning.learn_more": "Дізнатися більше",
"notification.moderation_warning": "Ви отримали попередження модерації",
"notification.moderation_warning.action_delete_statuses": "Деякі з ваших дописів було видалено.",
@ -508,16 +519,25 @@
"notification.update": "{name} змінює допис",
"notification_requests.accept": "Прийняти",
"notification_requests.accept_all": "Прийняти все",
"notification_requests.accept_multiple": "{count, plural, one {Прийняти # запит} few {Прийняти # запити} many {Прийняти # запитів} other {Прийняти # запит}}",
"notification_requests.confirm_accept_all.button": "Прийняти все",
"notification_requests.confirm_accept_all.message": "Ви збираєтеся прийняти {count, plural, one {запит на сповіщення} few {# запити на сповіщення} many {# запитів на сповіщення} other {# запит на сповіщення}}. Ви впевнені, що хочете продовжити?",
"notification_requests.confirm_accept_all.title": "Прийняти запит на сповіщення?",
"notification_requests.confirm_dismiss_all.button": "Відхили все",
"notification_requests.confirm_dismiss_all.message": "Ви збираєтеся відхилити {count, plural, one {запит на сповіщення} few {# запити на сповіщення} many {# запитів на сповіщення} other {# запит на сповіщення}}. Ви не зможете легко отримати доступ до {count, plural, one {нього} other {них}} again. Ви впевнені, що хочете продовжити?",
"notification_requests.confirm_dismiss_all.title": "Відхилити запити на сповіщення?",
"notification_requests.dismiss": "Відхилити",
"notification_requests.dismiss_all": "Відхили все",
"notification_requests.dismiss_multiple": "{count, plural, one {Відхилити # запит} other {Відхилити # запити}}",
"notification_requests.enter_selection_mode": "Вибрати",
"notification_requests.exit_selection_mode": "Скасувати",
"notification_requests.explainer_for_limited_account": "Сповіщення від цього облікового запису фільтровані, оскільки обліковий запис обмежений модератором.",
"notification_requests.explainer_for_limited_remote_account": "Сповіщення від цього облікового запису фільтровані, оскільки обліковий запис або його сервер обмежений модератором.",
"notification_requests.maximize": "Розгорнути",
"notification_requests.minimize_banner": "Мінімізувати відфільтрований банер сповіщень",
"notification_requests.notifications_from": "Сповіщення від {name}",
"notification_requests.title": "Відфільтровані сповіщення",
"notification_requests.view": "Переглянути сповіщення",
"notifications.clear": "Очистити сповіщення",
"notifications.clear_confirmation": "Ви впевнені, що хочете назавжди видалити всі сповіщення?",
"notifications.clear_title": "Очистити сповіщення?",
@ -555,7 +575,11 @@
"notifications.permission_denied_alert": "Сповіщення не можна ввімкнути оскільки у дозволі вже було відмовлено раніше",
"notifications.permission_required": "Сповіщення на стільниці не доступні, оскільки необхідний дозвіл не надано.",
"notifications.policy.accept": "Прийняти",
"notifications.policy.accept_hint": "Показувати в сповіщеннях",
"notifications.policy.drop": "Ігнорувати",
"notifications.policy.drop_hint": "Відправити в нікуди, щоб більше не бачити",
"notifications.policy.filter": "Фільтрувати",
"notifications.policy.filter_hint": "Надіслати до відфільтрованих вхідних",
"notifications.policy.filter_limited_accounts_hint": "Обмежено модераторами сервера",
"notifications.policy.filter_limited_accounts_title": "Модеровані облікові записи",
"notifications.policy.filter_new_accounts.hint": "Створено впродовж {days, plural, one {одного} few {# днів} many {# днів} other {# дня}}",
@ -566,6 +590,7 @@
"notifications.policy.filter_not_following_title": "Люди, на яких ви не підписані",
"notifications.policy.filter_private_mentions_hint": "Відфільтровується, якщо це не відповідь на вашу власну згадку або якщо ви відстежуєте відправника",
"notifications.policy.filter_private_mentions_title": "Небажані приватні згадки",
"notifications.policy.title": "Керувати сповіщеннями від…",
"notifications_permission_banner.enable": "Увімкнути сповіщення стільниці",
"notifications_permission_banner.how_to_control": "Щоб отримувати сповіщення, коли Mastodon не відкрито, увімкніть сповіщення стільниці. Ви можете контролювати, які типи взаємодій створюють сповіщення через кнопку {icon} вгорі після їхнього увімкнення.",
"notifications_permission_banner.title": "Не проґавте нічого",
@ -726,11 +751,11 @@
"server_banner.about_active_users": "Люди, які використовують цей сервер протягом останніх 30 днів (Щомісячні Активні Користувачі)",
"server_banner.active_users": "активні користувачі",
"server_banner.administered_by": "Адміністратор:",
"server_banner.is_one_of_many": "{domain} - один з багатьох незалежних серверів Mastodon, які ви можете використати, щоб брати участь у федівері.",
"server_banner.is_one_of_many": "{domain} - один з багатьох незалежних серверів Mastodon, які ви можете використати, щоб брати участь у федіверсі.",
"server_banner.server_stats": "Статистика сервера:",
"sign_in_banner.create_account": "Створити обліковий запис",
"sign_in_banner.follow_anyone": "Слідкуйте за ким завгодно у всьому fediverse і дивіться все це в хронологічному порядку. Немає алгоритмів, реклами чи наживок для натискань при перегляді.",
"sign_in_banner.mastodon_is": "Мастодон - найкращий спосіб продовжувати свою справу.",
"sign_in_banner.follow_anyone": "Слідкуйте за ким завгодно у всьому fediverse і дивіться все це в хронологічному порядку. Немає алгоритмів, реклами чи клікбейту.",
"sign_in_banner.mastodon_is": "Mastodon — найкращий спосіб бути в курсі подій.",
"sign_in_banner.sign_in": "Увійти",
"sign_in_banner.sso_redirect": "Увійдіть або зареєструйтесь",
"status.admin_account": "Відкрити інтерфейс модерації для @{name}",

View file

@ -19,6 +19,7 @@ import {
markNotificationsAsRead,
mountNotifications,
unmountNotifications,
refreshStaleNotificationGroups,
} from 'mastodon/actions/notification_groups';
import {
disconnectTimeline,
@ -51,6 +52,7 @@ interface NotificationGroupsState {
readMarkerId: string;
mounted: number;
isTabVisible: boolean;
mergedNotifications: 'ok' | 'pending' | 'needs-reload';
}
const initialState: NotificationGroupsState = {
@ -58,6 +60,8 @@ const initialState: NotificationGroupsState = {
pendingGroups: [], // holds pending groups in slow mode
scrolledToTop: false,
isLoading: false,
// this is used to track whether we need to refresh notifications after accepting requests
mergedNotifications: 'ok',
// The following properties are used to track unread notifications
lastReadId: '0', // used internally for unread notifications
readMarkerId: '0', // user-facing and updated when focus changes
@ -301,6 +305,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
json.type === 'gap' ? json : createNotificationGroupFromJSON(json),
);
state.isLoading = false;
state.mergedNotifications = 'ok';
updateLastReadId(state);
})
.addCase(fetchNotificationsGap.fulfilled, (state, action) => {
@ -455,7 +460,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
state.groups = state.pendingGroups.concat(state.groups);
state.pendingGroups = [];
})
.addCase(updateScrollPosition, (state, action) => {
.addCase(updateScrollPosition.fulfilled, (state, action) => {
state.scrolledToTop = action.payload.top;
updateLastReadId(state);
trimNotifications(state);
@ -482,7 +487,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
action.payload.markers.notifications.last_read_id;
}
})
.addCase(mountNotifications, (state) => {
.addCase(mountNotifications.fulfilled, (state) => {
state.mounted += 1;
commitLastReadId(state);
updateLastReadId(state);
@ -498,6 +503,10 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
.addCase(unfocusApp, (state) => {
state.isTabVisible = false;
})
.addCase(refreshStaleNotificationGroups.fulfilled, (state, action) => {
if (action.payload.deferredRefresh)
state.mergedNotifications = 'needs-reload';
})
.addMatcher(
isAnyOf(authorizeFollowRequestSuccess, rejectFollowRequestSuccess),
(state, action) => {

View file

@ -144,6 +144,7 @@ class Account < ApplicationRecord
scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) }
scope :with_username, ->(value) { where arel_table[:username].lower.eq(value.to_s.downcase) }
scope :with_domain, ->(value) { where arel_table[:domain].lower.eq(value&.to_s&.downcase) }
scope :without_memorial, -> { where(memorial: false) }
after_update_commit :trigger_update_webhooks

View file

@ -31,6 +31,7 @@ class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source
AND accounts.suspended_at IS NULL
AND accounts.silenced_at IS NULL
AND accounts.moved_to_account_id IS NULL
AND accounts.memorial = FALSE
AND follow_recommendation_mutes.target_account_id IS NULL
GROUP BY accounts.id, account_stats.id
ORDER BY frequency DESC, account_stats.followers_count ASC

View file

@ -14,6 +14,7 @@ class AccountSuggestions::Source
.searchable
.where(discoverable: true)
.without_silenced
.without_memorial
.where.not(follows_sql, id: account.id)
.where.not(follow_requests_sql, id: account.id)
.not_excluded_by_account(account)

View file

@ -14,7 +14,7 @@ class Trends::TagFilter
def results
scope = if params[:status] == 'pending_review'
Tag.unscoped
Tag.unscoped.order(id: :desc)
else
trending_scope
end

View file

@ -1,9 +1,21 @@
# frozen_string_literal: true
class AcceptNotificationRequestService < BaseService
include Redisable
def call(request)
NotificationPermission.create!(account: request.account, from_account: request.from_account)
increment_worker_count!(request)
UnfilterNotificationsWorker.perform_async(request.account_id, request.from_account_id)
request.destroy!
end
private
def increment_worker_count!(request)
with_redis do |redis|
redis.incr("notification_unfilter_jobs:#{request.account_id}")
redis.expire("notification_unfilter_jobs:#{request.account_id}", 30.minutes.to_i)
end
end
end

View file

@ -2,6 +2,7 @@
class UnfilterNotificationsWorker
include Sidekiq::Worker
include Redisable
# Earlier versions of the feature passed a `notification_request` ID
# If `to_account_id` is passed, the first argument is an account ID
@ -9,19 +10,20 @@ class UnfilterNotificationsWorker
def perform(notification_request_or_account_id, from_account_id = nil)
if from_account_id.present?
@notification_request = nil
@from_account = Account.find(from_account_id)
@recipient = Account.find(notification_request_or_account_id)
@from_account = Account.find_by(id: from_account_id)
@recipient = Account.find_by(id: notification_request_or_account_id)
else
@notification_request = NotificationRequest.find(notification_request_or_account_id)
@from_account = @notification_request.from_account
@recipient = @notification_request.account
@notification_request = NotificationRequest.find_by(id: notification_request_or_account_id)
@from_account = @notification_request&.from_account
@recipient = @notification_request&.account
end
return if @from_account.nil? || @recipient.nil?
push_to_conversations!
unfilter_notifications!
remove_request!
rescue ActiveRecord::RecordNotFound
true
decrement_worker_count!
end
private
@ -45,4 +47,17 @@ class UnfilterNotificationsWorker
def notifications_with_private_mentions
filtered_notifications.where(type: :mention).joins(mention: :status).merge(Status.where(visibility: :direct)).includes(mention: :status)
end
def decrement_worker_count!
value = redis.decr("notification_unfilter_jobs:#{@recipient.id}")
push_streaming_event! if value <= 0 && subscribed_to_streaming_api?
end
def push_streaming_event!
redis.publish("timeline:#{@recipient.id}:notifications", Oj.dump(event: :notifications_merged, payload: '1'))
end
def subscribed_to_streaming_api?
redis.exists?("subscribed:timeline:#{@recipient.id}") || redis.exists?("subscribed:timeline:#{@recipient.id}:notifications")
end
end

View file

@ -39,6 +39,7 @@ ar:
created_msg: تم إنشاء ملاحظة الإشراف بنجاح!
destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح!
accounts:
add_email_domain_block: حظر نطاق البريد الإلكتروني
approve: صادِق عليه
approved_msg: تمت الموافقة على تسجيل %{username}
are_you_sure: هل أنت متأكد؟
@ -227,6 +228,7 @@ ar:
update_custom_emoji: تحديث الإيموجي المخصص
update_domain_block: تحديث حظر النطاق
update_ip_block: تحديث قاعدة IP
update_report: تحديث التقرير
update_status: تحديث المنشور
update_user_role: تحديث الدور
actions:
@ -559,7 +561,7 @@ ar:
deactivate_all: تعطيلها كافة
filter:
all: الكل
available: المتوفرة
available: متاح
expired: المنتهي صلاحيتها
title: التصفية
title: الدعوات
@ -617,6 +619,7 @@ ar:
resolve_description_html: ولن يُتخذ أي إجراء ضد الحساب المبلّغ عنه، ولن تسلَّط عليه أية عقوبة، وسوف يُغلق التقرير.
silence_description_html: الحساب سيظهر فقط لمن يتابعه أو قام بالبحث عنه بشكل مباشر مما يخفض إمكانية رؤيته بشكل شبه كامل. يمكنك دائما التراجع عن هذا الإجراء. تُغلَق كافة الإبلاغات عن هذا الحساب.
suspend_description_html: سيُمنع الوصول إلى الحساب وجميع محتوياته وتُحذف تدريجياً، وسيكون التفاعل معه مستحيلاً. بالإمكان عكس مفعول ذلك في غضون 30 يوماً. يغلق جميع التبليغات ضد الحساب.
actions_description_html: حدد الإجراء الذي يجب عليك اتخاذه لحل هذا التقرير. إذا اتخذت إجراء عقابيا ضد الحساب المبلغ عنه، فسيتم إرسال إشعار عبر البريد الإلكتروني إليهم، باستثناء عند اختيار فئة <strong>spam</strong>.
actions_description_remote_html: حدّد الإجراءات التي يتعين اتخاذها لحل هذا التقرير. هذا سيؤثر فقط على كيفية اتصال <strong>خادمك</strong> بهذا الحساب البعيد والتعامل مع محتوياته.
add_to_report: أضف المزيد إلى التقرير
are_you_sure: هل أنت متأكد ؟
@ -721,8 +724,8 @@ ar:
invite_users_description: يسمح للمستخدمين بدعوة أشخاص جدد إلى الخادم
manage_announcements: ادارة الاعلانات
manage_announcements_description: يسمح للمستخدمين بإدارة الإعلانات على الخادم
manage_appeals: إدارة الاستئنافات
manage_appeals_description: يسمح للمستخدمين بمراجعة الطعن ضد إجراءات الإشراف
manage_appeals: إدارة الطعون
manage_appeals_description: يسمح للمستخدمين بمراجعة الطعون المقدمة ضد إجراءات الإشراف
manage_blocks: إدارة الحظر
manage_custom_emojis: إدارة الرموز التعبيريّة المخصصة
manage_custom_emojis_description: السماح للمستخدمين بإدارة الرموز التعبيريّة المخصصة على الخادم
@ -899,6 +902,9 @@ ar:
action: تحقق هنا للمزيد من المعلومات
message_html: "<strong>تم تكوين مخزن الكائنات الخاص بك بشكل خاطئ. خصوصية المستخدمين في خطر.</strong>"
tags:
moderation:
title: الحالة
newest: الأحدث
review: حالة المراجعة
search: البحث
title: الوسوم
@ -1062,7 +1068,9 @@ ar:
guide_link_text: يمكن للجميع المساهمة.
sensitive_content: المحتوى الحساس
application_mailer:
notification_preferences: تغيير تفضيلات البريد الإلكتروني
salutation: "%{name}،"
settings: 'تغيير تفضيلات البريد الإلكتروني: %{link}'
unsubscribe: إلغاء الاشتراك
view: 'اعرض:'
view_profile: اعرض الصفحة التعريفية
@ -1460,6 +1468,9 @@ ar:
unsubscribe:
action: نعم، ألغِ الاشتراك
complete: غير مشترك
emails:
notification_emails:
reblog: رسائل البريد الخاصة بالمنشورات المعاد نشرها
title: إلغاء الاشتراك
media_attachments:
validations:
@ -1817,7 +1828,7 @@ ar:
min_age_label: عتبة العمر
min_favs: إبقاء المشاركات المفضلة أكثر من
min_favs_hint: لن تُحذف أي من منشوراتك التي تلقّت على الأقل هذا العدد من المفضلات. اتركه فارغاً لحذف المنشورات مهما كان عدد المفضلات التي تلقتها
min_reblogs: إبقاء المشاركات المعززة أكثر من
min_reblogs: إبقاء المنشورات المعاد نشرها أكثر من
min_reblogs_hint: لن تُحذف أي من منشوراتك التي أعيد مشاركتها أكثر من هذا العدد من المرات. اتركه فارغاً لحذف المنشورات بغض النظر عن عدد إعادات النشر
stream_entries:
sensitive_content: محتوى حساس
@ -1960,6 +1971,7 @@ ar:
invalid_otp_token: رمز المصادقة بخطوتين غير صالح
otp_lost_help_html: إن فقدتَهُما ، يمكنك الاتصال بـ %{email}
rate_limited: عدد محاولات المصادقة كثير جداً، حاول مرة أخرى لاحقاً.
seamless_external_login: لقد تم تسجيل دخولك عبر خدمة خارجية، لذا فإن إعدادات كلمة المرور والبريد الإلكتروني غير متاحة.
signed_in_as: 'تم تسجيل دخولك بصفة:'
verification:
extra_instructions_html: <strong>نصيحة:</strong> يمكن أن يكون الرابط الموجود على موقع الويب الخاص بك غير مرئي. الجزء المهم هو <code>rel="me"</code> الذي يمنع انتحال الهوية على مواقع الويب ذات المحتوى الذي ينشئه المستخدم. يمكنك أيضًا استخدام علامة <code>link</code> في رأس الصفحة بدلاً من <code>a</code>، ولكن يجب أن يكون HTML قابلاً للوصول دون تنفيذ JavaScript.

View file

@ -130,6 +130,7 @@ ca:
resubscribe: Torna a subscriure
role: Rol
search: Cerca
search_same_email_domain: Altres usuaris amb el mateix domini del correu electrònic
search_same_ip: Altres usuaris amb la mateixa IP
security: Seguretat
security_measures:
@ -170,21 +171,26 @@ ca:
approve_appeal: Aprova l'apel·lació
approve_user: Aprova l'usuari
assigned_to_self_report: Assigna un informe
change_email_user: Canvia el correu electrònic per l'usuari
change_role_user: Canvia el Rol del Usuari
confirm_user: Confirma l'usuari
create_account_warning: Crea un avís
create_announcement: Crea un anunci
create_canonical_email_block: Crea un blocatge del correu electrònic
create_custom_emoji: Crea un emoji personalitzat
create_domain_allow: Crea un domini permès
create_domain_block: Crea un bloqueig de domini
create_email_domain_block: Crea un blocatge del domini del correu electrònic
create_ip_block: Crear regla IP
create_unavailable_domain: Crea un domini no disponible
create_user_role: Crea Rol
demote_user: Degrada l'usuari
destroy_announcement: Esborra l'anunci
destroy_canonical_email_block: Elimina el blocatge del correu electrònic
destroy_custom_emoji: Esborra l'emoji personalitzat
destroy_domain_allow: Esborra el permís del domini
destroy_domain_block: Esborra el bloqueig de domini
destroy_email_domain_block: Elimina el blocatge del domini del correu electrònic
destroy_instance: Purga Domini
destroy_ip_block: Eliminar regla IP
destroy_status: Elimina la publicació
@ -223,7 +229,9 @@ ca:
approve_appeal_html: "%{name} ha aprovat l'apel·lació a la decisió de moderació de %{target}"
approve_user_html: "%{name} ha aprovat el registre de %{target}"
assigned_to_self_report_html: "%{name} s'han assignat l'informe %{target} a ells mateixos"
change_email_user_html: "%{name} ha canviat l'adreça del correu electrònic de l'usuari %{target}"
change_role_user_html: "%{name} ha canviat el rol de %{target}"
confirm_user_html: "%{name} ha confirmat l'adreça del correu electrònic de l'usuari %{target}"
create_account_warning_html: "%{name} ha enviat un avís a %{target}"
create_announcement_html: "%{name} ha creat un nou anunci %{target}"
create_custom_emoji_html: "%{name} ha pujat un emoji nou %{target}"
@ -1079,6 +1087,7 @@ ca:
or_log_in_with: O inicia sessió amb
privacy_policy_agreement_html: He llegit i estic d'acord amb la <a href="%{privacy_policy_path}" target="_blank">política de privacitat</a>
progress:
confirm: Confirmar email
details: Els teus detalls
review: La nostra revisió
rules: Accepta les normes
@ -1102,6 +1111,7 @@ ca:
setup:
email_settings_hint_html: Toca l'enllaç que t'hem enviat per a verificar %{email}. Esperarem aquí mateix.
link_not_received: No has rebut l'enllaç?
new_confirmation_instructions_sent: Rebràs un nou correu amb l'enllaç de confirmació en pocs minuts!
title: Comprova la teva safata d'entrada
sign_in:
preamble_html: Inicia la sessió amb les teves credencials de <strong>%{domain}</strong>. Si el teu compte es troba a un servidor diferent, no podràs iniciar sessió aquí.

View file

@ -136,7 +136,7 @@ ar:
mutes: تم كتمها
notifications: الإشعارات
profile: مِلَفّ مَستُدون التعريفي الخاص بك
push: الإشعارات
push: الإشعارات المدفوعة
reports: الشكاوى
search: البحث
statuses: المنشورات

View file

@ -83,6 +83,7 @@ sr-Latn:
access_denied: Vlasnik resursa ili autorizacioni server su odbili zahtev.
credential_flow_not_configured: Tok Resource Owner Password Credentials nije uspeo pošto je Doorkeeper.configure.resource_owner_from_credentials neiskonfigurisan.
invalid_client: Klijentska identifikacija nije uspela zbog nepoznatog klijenta, zato što klijent nije uključio identifikaciju ili zato što je iskorišćen nepodržani identifikacioni metod.
invalid_code_challenge_method: Metod izazova koda mora biti S256, običan nije podržan.
invalid_grant: Zadata identifikaciona dozvola je neispravna, istekla, opozvana, ne poklapa se sa adresom preusmeravanja ili je izdata nekog drugom klijentu.
invalid_redirect_uri: Uključena adresa preusmeravanja nije ispravna.
invalid_request:

View file

@ -83,6 +83,7 @@ sr:
access_denied: Власник ресурса или ауторизациони сервер су одбили захтев.
credential_flow_not_configured: Ток Resource Owner Password Credentials није успео пошто је Doorkeeper.configure.resource_owner_from_credentials неисконфигурисан.
invalid_client: Клијентска идентификација није успела због непознатог клијента, зато што клијент није укључио идентификацију или зато што је искоришћен неподржани идентификациони метод.
invalid_code_challenge_method: Метод изазова кода мора бити S256, обичан није подржан.
invalid_grant: Задата идентификациона дозвола је неисправна, истекла, опозвана, не поклапа се са адресом преусмеравања или је издата неког другом клијенту.
invalid_redirect_uri: Укључена адреса преусмеравања није исправна.
invalid_request:

View file

@ -35,6 +35,7 @@ gd:
created_msg: Chaidh nòta na maorsainneachd a chruthachadh!
destroyed_msg: Chaidh nòta na maorsainneachd a mhilleadh!
accounts:
add_email_domain_block: Bac àrainn a phuist-d
approve: Aontaich ris
approved_msg: Chaidh aontachadh ris an iarrtas clàraidh aig %{username}
are_you_sure: A bheil thu cinnteach?
@ -61,6 +62,7 @@ gd:
demote: Ìslich
destroyed_msg: Chaidh an dàta aig %{username} a chur air a chiutha ach an dèid a sguabadh às an ceann greis bheag
disable: Reòth
disable_sign_in_token_auth: Cuir à comas dearbhadh le tòcan puist-d
disable_two_factor_authentication: Cuir an dearbhadh dà-cheumnach à comas
disabled: Reòthte
display_name: Ainm-taisbeanaidh
@ -69,6 +71,7 @@ gd:
email: Post-d
email_status: Staid a phuist-d
enable: Dì-reòth
enable_sign_in_token_auth: Cuir an comas dearbhadh le tòcan puist-d
enabled: An comas
enabled_msg: Chaidh an cunntas aig %{username} a dhì-reòthadh
followers: Luchd-leantainn
@ -135,6 +138,7 @@ gd:
resubscribe: Fo-sgrìobh a-rithist
role: Dreuchd
search: Lorg
search_same_email_domain: Cleachdaichean eile aig a bheil an aon àrainn puist-d
search_same_ip: Cleachdaichean eile aig a bheil an t-aon IP
security: Tèarainteachd
security_measures:
@ -175,21 +179,26 @@ gd:
approve_appeal: Thoir aonta ris an ath-thagradh
approve_user: Aontaich ris a chleachdaiche
assigned_to_self_report: Iomruin an gearan
change_email_user: Atharraich post-d a chleachdaiche
change_role_user: Atharraich dreuchd a chleachdaiche
confirm_user: Dearbh an cleachdaiche
create_account_warning: Cruthaich rabhadh
create_announcement: Cruthaich brath-fios
create_canonical_email_block: Cruthaich bacadh puist-d
create_custom_emoji: Cruthaich Emoji gnàthaichte
create_domain_allow: Cruthaich ceadachadh àrainne
create_domain_block: Cruthaich bacadh àrainne
create_email_domain_block: Cruthaich bacadh àrainne puist-d
create_ip_block: Cruthaich riaghailt IP
create_unavailable_domain: Cruthaich àrainn nach eil ri fhaighinn
create_user_role: Cruthaich dreuchd
demote_user: Ìslich an cleachdaiche
destroy_announcement: Sguab às am brath-fios
destroy_canonical_email_block: Sguab às bacadh a phuist-d
destroy_custom_emoji: Sguab às an t-Emoji gnàthaichte
destroy_domain_allow: Sguab às ceadachadh na h-àrainne
destroy_domain_block: Sguab às bacadh na h-àrainne
destroy_email_domain_block: Sguab às bacadh na h-àrainne puist-d
destroy_instance: Purgaidich an àrainn
destroy_ip_block: Sguab às an riaghailt IP
destroy_status: Sguab às am post
@ -197,8 +206,10 @@ gd:
destroy_user_role: Mill an dreuchd
disable_2fa_user: Cuir an dearbhadh dà-cheumnach à comas
disable_custom_emoji: Cuir an t-Emoji gnàthaichte à comas
disable_sign_in_token_auth_user: Cuir à comas dearbhadh le tòcan puist-d dhan chleachdaiche
disable_user: Cuir an cleachdaiche à comas
enable_custom_emoji: Cuir an t-Emoji gnàthaichte an comas
enable_sign_in_token_auth_user: Cuir an comas dearbhadh le tòcan puist-d dhan chleachdaiche
enable_user: Cuir an cleachdaiche an comas
memorialize_account: Dèan cuimhneachan dhen chunntas
promote_user: Àrdaich an cleachdaiche
@ -228,20 +239,26 @@ gd:
approve_appeal_html: Dhaontaich %{name} ri ath-thagradh air co-dhùnadh na maorsainneachd o %{target}
approve_user_html: Dhaontaich %{name} ri clàradh o %{target}
assigned_to_self_report_html: Dhiomruin %{name} an gearan %{target} dhaibh fhèin
change_email_user_html: Dhatharraich %{name} seòladh puist-d a chleachdaiche %{target}
change_role_user_html: Atharraich %{name} an dreuchd aig %{target}
confirm_user_html: Dhearbh %{name} seòladh puist-d a chleachdaiche %{target}
create_account_warning_html: Chuir %{name} rabhadh gu %{target}
create_announcement_html: Chruthaich %{name} brath-fios %{target} ùr
create_canonical_email_block_html: Bhac %{name} am post-d air a bheil an hais %{target}
create_custom_emoji_html: Luchdaich %{name} suas Emoji %{target} ùr
create_domain_allow_html: Cheadaich %{name} co-nasgadh leis an àrainn %{target}
create_domain_block_html: Bhac %{name} an àrainn %{target}
create_email_domain_block_html: Bhac %{name} an àrainn puist-d %{target}
create_ip_block_html: Chruthaich %{name} riaghailt dhan IP %{target}
create_unavailable_domain_html: Sguir %{name} ris an lìbhrigeadh dhan àrainn %{target}
create_user_role_html: Chruthaich %{name} an dreuchd %{target}
demote_user_html: Dhìslich %{name} an cleachdaiche %{target}
destroy_announcement_html: Sguab %{name} às am brath-fios %{target}
destroy_canonical_email_block_html: Dhì-bhac %{name} am post-d air a bheil an hais %{target}
destroy_custom_emoji_html: Sguab %{name} às an Emoji %{target}
destroy_domain_allow_html: Dì-cheadaich %{name} co-nasgadh leis an àrainn %{target}
destroy_domain_block_html: Dì-bhac %{name} an àrainn %{target}
destroy_email_domain_block_html: Dì-bhac %{name} an àrainn puist-d %{target}
destroy_instance_html: Purgaidich %{name} an àrainn %{target}
destroy_ip_block_html: Sguab %{name} às riaghailt dhan IP %{target}
destroy_status_html: Thug %{name} post aig %{target} air falbh
@ -249,8 +266,10 @@ gd:
destroy_user_role_html: Sguab %{name} às an dreuchd %{target}
disable_2fa_user_html: Chuir %{name} riatanas an dearbhaidh dà-cheumnaich à comas dhan chleachdaiche %{target}
disable_custom_emoji_html: Chuir %{name} an Emoji %{target} à comas
disable_sign_in_token_auth_user_html: Chuir %{name} à comas dearbhadh le tòcan puist-d dha %{target}
disable_user_html: Chuir %{name} an clàradh a-steach à comas dhan chleachdaiche %{target}
enable_custom_emoji_html: Chuir %{name} an Emoji %{target} an comas
enable_sign_in_token_auth_user_html: Chuir %{name} an comas dearbhadh le tòcan puist-d dha %{target}
enable_user_html: Chuir %{name} an clàradh a-steach an comas dhan chleachdaiche %{target}
memorialize_account_html: Rinn %{name} duilleag cuimhneachain dhen chunntas aig %{target}
promote_user_html: Dhàrdaich %{name} an cleachdaiche %{target}
@ -258,6 +277,7 @@ gd:
reject_user_html: Dhiùlt %{name} an clàradh o %{target}
remove_avatar_user_html: Thug %{name} avatar aig %{target} air falbh
reopen_report_html: Dhfhosgail %{name} an gearan %{target} a-rithist
resend_user_html: Chuir %{name} am post-d dearbhaidh airson %{target} a-rithist
reset_password_user_html: Dhath-shuidhich %{name} am facal-faire aig a chleachdaiche %{target}
resolve_report_html: Dhfhuasgail %{name} an gearan %{target}
sensitive_account_html: Chuir %{name} comharra gu bheil e frionasach ri meadhan aig %{target}
@ -428,6 +448,7 @@ gd:
one: "%{count} oidhirp clàraidh rè na seachdain seo chaidh"
other: "%{count} oidhirp clàraidh rè na seachdain seo chaidh"
two: "%{count} oidhirp clàraidh rè na seachdain seo chaidh"
created_msg: Chaidh àrainn a phuist-d a bhacadh
delete: Sguab às
dns:
types:
@ -436,8 +457,12 @@ gd:
new:
create: Cuir àrainn ris
resolve: Fuasgail an àrainn
title: Bac àrainn puist-d ùr
no_email_domain_block_selected: Cha deach bacadh àrainn puist-d sam bith atharrachadh o nach deach gin dhiubh a thaghadh
not_permitted: Chan eil seo ceadaichte
resolved_dns_records_hint_html: Thèid ainm na h-àrainne fhuasgladh nan àrainnean MX a leanas agus an urra riutha-san gun gabh iad ri post-d. Ma bhacas tu àrainn MX, bacaidh seo an clàradh o sheòladh puist-d sam bith a chleachdas an aon àrainn MX fiù s ma bhios ainm àrainne eadar-dhealaichte ga sealltainn. <strong>Thoir an aire nach bac thu solaraichean puist-d mòra.</strong>
resolved_through_html: Chaidh fuasgladh slighe %{domain}
title: Bacadh àrainnean puist-d
export_domain_allows:
new:
title: Ion-phortaich àrainnean ceadaichte
@ -599,6 +624,7 @@ gd:
resolve_description_html: Cha dèid gnìomh sam bith a ghabhail an aghaidh a chunntais le gearan air agus thèid an gearan a dhùnadh gun rabhadh a chlàradh.
silence_description_html: Chan fhaic ach an fheadhainn a tha ga leantainn mu thràth no a lorgas a làimh e an cunntas seo agus cuingichidh seo uiread nan daoine a ruigeas e gu mòr. Gabhaidh seo a neo-dhèanamh uair sam bith. Dùinidh seo gach gearan mun chunntas seo.
suspend_description_html: Cha ghabh an cunntas seo agus an t-susbaint gu leòr aige inntrigeadh gus an dèid a sguabadh às air deireadh na sgeòil agus cha ghabh eadar-ghabhail a dhèanamh leis. Gabhaidh seo a neo-dhèanamh am broinn 30 latha. Dùinidh seo gach gearan mun chunntas seo.
actions_description_html: Cuir romhad dè nì thu airson an gearan seo fhuasgladh. Ma chuireas tu peanas air a chunntas le gearan air, gheibh iad brath air a phost-d mura tagh thu an roinn-seòrsa <strong>Spama</strong>.
actions_description_remote_html: Cuir romhad dè an gnìomh a ghabhas tu airson an gearan seo fhuasgladh. Cha bheir seo buaidh ach air mar a làimhsicheas am frithealaiche <strong>agadsa</strong> an cunntas cèin seo is mar a nì e conaltradh leis.
add_to_report: Cuir barrachd ris a ghearan
already_suspended_badges:
@ -663,6 +689,7 @@ gd:
delete_data_html: Sguab às a phròifil s an t-susbaint aig <strong>@%{acct}</strong> an ceann 30 latha mura dèid an cur an gnìomh a-rithist roimhe sin
preview_preamble_html: 'Gheibh <strong>@%{acct}</strong> rabhadh leis an t-susbaint seo:'
record_strike_html: Clàraich rabhadh an aghaidh <strong>@%{acct}</strong> airson do chuideachadh ach am bi thu nas teinne le droch-ghiùlan on chunntas seo san àm ri teachd
send_email_html: Cuir post-d rabhaidh gu <strong>@%{acct}</strong>
warning_placeholder: Adhbharan roghainneil eile air gnìomh na maorsainneachd.
target_origin: Tùs cunntas a ghearain
title: Gearanan
@ -706,6 +733,7 @@ gd:
manage_appeals: Stiùireadh ath-thagraidhean
manage_appeals_description: Leigidh seo le cleachdaichean lèirmheas a dhèanamh air ath-thagraidhean an aghaidh gnìomhan mhaor
manage_blocks: Stiùireadh nam bacaidhean
manage_blocks_description: Leigidh seo le cleachdaichean solaraichean puist-d is seòlaidhean IP a bhacadh
manage_custom_emojis: Stiùireadh nan Emojis gnàthaichte
manage_custom_emojis_description: Leigidh seo le cleachdaichean Emojis gnàthaichte a stiùireadh air an fhrithealaiche
manage_federation: Stiùireadh a cho-nasgaidh
@ -723,6 +751,7 @@ gd:
manage_taxonomies: Stiùireadh thacsonamaidhean
manage_taxonomies_description: Leigidh seo le cleachdaichean lèirmheas a dhèanamh air an t-susbaint a tha a treandadh agus roghainnean nan tagaichean hais ùrachadh
manage_user_access: Stiùireadh inntrigeadh chleachdaichean
manage_user_access_description: Leigidh seo le cleachdaichean gun cuir iad à comas dearbhadh dà-cheumnach càich, gun atharraich iad an seòladh puist-d aca is gun ath-shuidhich iad am facal-faire aca
manage_users: Stiùireadh chleachdaichean
manage_users_description: Leigidh seo le cleachdaichean mion-fhiosrachadh càich a shealltainn agus gnìomhan maoir a ghabhail nan aghaidh
manage_webhooks: Stiùireadh nan webhooks
@ -797,6 +826,7 @@ gd:
destroyed_msg: Chaidh an luchdadh suas dhan làrach a sguabadh às!
software_updates:
critical_update: Èiginneach ùraich cho luath s a ghabhas
description: Mholamaid gun cùm thu an stàladh agad de Mhastodon ùraichte ach am faigh thu buannachd às na càraidhean s gleusan as ùire. A bharrachd air sin, bidh e èiginneach aig amannan gun ùraich thu Mastodon gun dàil airson duilgheadasan tèarainteachd a sheachnadh. Seo as adhbhar gun doir Mastodon sùil airson ùrachaidhean gach leth-uair a thìde s gun cuir e brath thugad a-rèir nan roghainnean puist-d agad.
documentation_link: Barrachd fiosrachaidh
release_notes: Nòtaichean sgaoilidh
title: Ùrachaidhean a tha ri fhaighinn
@ -905,10 +935,16 @@ gd:
trends:
allow: Ceadaich
approved: Aontaichte
confirm_allow: A bheil thu cinnteach gu bheil thu airson na tagaichean a thagh thu a cheadachadh?
confirm_disallow: A bheil thu cinnteach gu bheil thu airson na tagaichean a thagh thu a dhì-cheadachadh?
disallow: Na ceadaich
links:
allow: Ceadaich an ceangal
allow_provider: Ceadaich am foillsichear
confirm_allow: A bheil thu cinnteach gu bheil thu airson na ceanglaichean a thagh thu a cheadachadh?
confirm_allow_provider: A bheil thu cinnteach gu bheil thu airson na solaraichean a thagh thu a cheadachadh?
confirm_disallow: A bheil thu cinnteach gu bheil thu airson na ceanglaichean a thagh thu a dhì-cheadachadh?
confirm_disallow_provider: A bheil thu cinnteach gu bheil thu airson na solaraichean a thagh thu a dhì-cheadachadh?
description_html: Seo na ceanglaichean a tha gan co-roinneadh le iomadh cunntas on a chì am frithealaiche agad na postaichean. Faodaidh iad a bhith nan cuideachadh dhan luchd-cleachdaidh ach am faigh iad a-mach dè tha tachairt air an t-saoghal. Cha dèid ceanglaichean a shealltainn gu poblach gus an aontaich thu ris an fhoillsichear. S urrainn dhut ceanglaichean àraidh a cheadachadh no a dhiùltadh cuideachd.
disallow: Na ceadaich an ceangal
disallow_provider: Na ceadaich am foillsichear
@ -934,6 +970,10 @@ gd:
statuses:
allow: Ceadaich am post
allow_account: Ceadaich an t-ùghdar
confirm_allow: A bheil thu cinnteach gu bheil thu airson na puist a thagh thu a cheadachadh?
confirm_allow_account: A bheil thu cinnteach gu bheil thu airson na cunntasan a thagh thu a cheadachadh?
confirm_disallow: A bheil thu cinnteach gu bheil thu airson na puist a thagh thu a dhì-cheadachadh?
confirm_disallow_account: A bheil thu cinnteach gu bheil thu airson na cunntasan a thagh thu a dhì-cheadachadh?
description_html: Seo na postaichean air a bheil am frithealaiche agad eòlach s a tha gan co-roinneadh is nan annsachd gu tric aig an àm seo. Faodaidh iad a bhith nan cuideachadh dhan luchd-cleachdaidh ùr no a thill ach an lorg iad daoine airson an leantainn. Cha dèid postaichean a shealltainn gu poblach gus an gabh thu ris an ùghdar agus gus an aontaich an t-ùghdar gun dèid an cunntas aca a mholadh do dhaoine eile. S urrainn dhut postaichean àraidh a cheadachadh no a dhiùltadh cuideachd.
disallow: Na ceadaich am post
disallow_account: Na ceadaich an t-ùghdar
@ -970,6 +1010,7 @@ gd:
one: Chaidh a chleachdadh le %{count} rè na seachdain seo chaidh
other: Chaidh a chleachdadh le %{count} rè na seachdain seo chaidh
two: Chaidh a chleachdadh le %{count} rè na seachdain seo chaidh
title: Molaidhean ⁊ treandaichean
trending: A treandadh
warning_presets:
add_new: Cuir fear ùr ris
@ -1056,7 +1097,9 @@ gd:
guide_link_text: "S urrainn do neach sam bith cuideachadh."
sensitive_content: Susbaint fhrionasach
application_mailer:
notification_preferences: Atharraich roghainnean a phuist-d
salutation: "%{name},"
settings: 'Atharraich roghainnean a phuist-d: %{link}'
unsubscribe: Cuir crìoch air an fho-sgrìobhadh
view: 'Faic:'
view_profile: Seall a phròifil
@ -1076,6 +1119,7 @@ gd:
hint_html: Dìreach aon rud eile! Feumaidh sinn dearbhadh gu bheil thu daonna (ach am fàg sinn an spama aig an doras!). Fuasgail an CAPTCHA gu h-ìosal is briog air “Lean air adhart”.
title: Deuchainn tèarainteachd
confirmations:
awaiting_review: Chaidh am post-d agad a dhearbhadh! Nì an sgioba aig %{domain} lèirmheas air a chlàradh agad a-nis. Gheibh thu post-d nuair a bhios iad air aontachadh ris a chunntas agad!
awaiting_review_title: Tha an cunntas agad ga sgrùdadh
clicking_this_link: briogadh air a cheangal seo
login_link: clàradh a-steach
@ -1083,6 +1127,7 @@ gd:
redirect_to_app_html: Bu chòir dhuinn d ath-stiùireadh gu aplacaid <strong>%{app_name}</strong>. Mur an do dhobraich sin, feuch %{clicking_this_link} no till dhan aplacaid a làimh.
registration_complete: Tha an clàradh agad air %{domain} deiseil a-nis!
welcome_title: Fàilte ort, %{name}!
wrong_email_hint: Mur eil an seòladh puist-d seo mar bu chòir, s urrainn dhut atharrachadh ann an roghainnean a chunntais.
delete_account: Sguab às an cunntas
delete_account_html: Nam bu mhiann leat an cunntas agad a sguabadh às, <a href="%{path}">nì thu an-seo e</a>. Thèid dearbhadh iarraidh ort.
description:
@ -1103,6 +1148,7 @@ gd:
or_log_in_with: No clàraich a-steach le
privacy_policy_agreement_html: Leugh mi is tha mi ag aontachadh ris a <a href="%{privacy_policy_path}" target="_blank">phoileasaidh prìobhaideachd</a>
progress:
confirm: Dearbh am post-d
details: Am fiosrachadh agad
review: An lèirmheas againn
rules: Gabh ris na riaghailtean
@ -1124,8 +1170,10 @@ gd:
security: Tèarainteachd
set_new_password: Suidhich facal-faire ùr
setup:
email_below_hint_html: Thoir sùil air pasgan an spama agad no iarr fear eile. S urrainn dhut an seòladh puist-d agad a chur ceart ma tha e ceàrr.
email_settings_hint_html: Briog air a cheangal a chuir sinn thugad a dhearbhadh %{email}. Fuirichidh sinn ort an-seo.
link_not_received: Nach dfhuair thu ceangal?
new_confirmation_instructions_sent: Gheibh thu post-d ùr le ceangal dearbhaidh an ceann corra mionaid!
title: Thoir sùil air a bhogsa a-steach agad
sign_in:
preamble_html: Clàraich a-steach le do theisteas <strong>%{domain}</strong>. Ma tha an cunntas agad ga òstadh air frithealaiche eile, chan urrainn dhut clàradh a-steach an-seo.
@ -1136,7 +1184,9 @@ gd:
title: Suidhicheamaid %{domain} dhut.
status:
account_status: Staid a chunntais
confirming: A feitheamh air coileanadh an dearbhaidh on phost-d.
functional: Tha an cunntas agad ag obair gu slàn.
pending: Feumaidh an sgioba againn lèirmheas a dhèanamh air d iarrtas. Dhfhaoidte gun doir seo greis. Gheibh thu post-d nuair a bhios sinn air aontachadh ri d iarrtas.
redirecting_to: Chan eil an cunntas gad gnìomhach on a tha e ga ath-stiùireadh gu %{acct}.
self_destruct: On a tha %{domain} gu bhith dùnadh, chan fhaigh thu ach inntrigeadh cuingichte dhan chunntas agad.
view_strikes: Seall na rabhaidhean a fhuair an cunntas agad roimhe
@ -1179,6 +1229,9 @@ gd:
before: 'Mus lean thu air adhart, leugh na nòtaichean seo gu cùramach:'
caches: Dhfhaoidte gum mair susbaint ann an tasgadain fhrithealaichean eile
data_removal: Thèid na postaichean agad s dàta eile a thoirt air falbh gu buan
email_change_html: S urrainn dhut <a href="%{path}">an seòladh puist-d agad atharrachadh</a> gun a bhith a sguabadh às a chunntais agad
email_contact_html: Mura faigh thu fhathast e, s urrainn dhut post-d a chur gu <a href="mailto:%{email}">%{email}</a> airson cuideachaidh
email_reconfirmation_html: Mur an d fhuair thu am post-d dearbhaidh, s urrainn dhut <a href="%{path}">iarraidh a-rithist</a>
irreversible: Chan urrainn dhut an cunntas agad aiseag no ath-ghnìomhachadh
more_details_html: Airson barrachd fiosrachaidh faic am <a href="%{terms_path}">poileasaidh prìobhaideachd</a>.
username_available: Bidh an t-ainm-cleachdaiche agad ri fhaighinn a-rithist
@ -1427,6 +1480,7 @@ gd:
authentication_methods:
otp: aplacaid dearbhaidh dhà-cheumnaich
password: facal-faire
sign_in_token: cuir còd tèarainteachd air a phost-d
webauthn: iuchraichean tèarainteachd
description_html: Ma chì thu gnìomhachd nach aithnich thu, mholamaid gun atharraich thu am facal-faire agad s gun cuir thu an dearbhadh dà-cheumnach an comas.
empty: Chan eil eachdraidh an dearbhaidh ri fhaighinn
@ -1437,6 +1491,16 @@ gd:
unsubscribe:
action: Tha, cuir crìoch air an fho-sgrìobhadh
complete: Chaidh crìoch a chur air an fho-sgrìobhadh
confirmation_html: A bheil thu cinnteach nach eil thu airson %{type} fhaighinn tuilleadh o Mhastodon air %{domain} dhan post-d agad aig %{email}? S urrainn dhut fo-sgrìobhadh a-rithist uair sam bith o <a href="%{settings_path}">roghainnean a puist-d agad</a>.
emails:
notification_emails:
favourite: puist-d le brathan mu annsachdan
follow: puist-d le brathan mu leantainn
follow_request: puist-d le brathan mu iarrtasan leantainn
mention: puist-d le brathan mu iomraidhean
reblog: puist-d le brathan mu bhrosnachaidhean
resubscribe_html: Ma chuir thu crìoch air an fho-sgrìobhadh le mearachd, s urrainn dhut fo-sgrìobhadh a-rithist o <a href="%{settings_path}">roghainnean a puist-d agad</a>.
success_html: Chan fhaigh thu %{type} o Mhastodon air %{domain} dhan phost-d agad aig %{email} tuilleadh.
title: Cuir crìoch air an fho-sgrìobhadh
media_attachments:
validations:
@ -1517,6 +1581,8 @@ gd:
update:
subject: Dheasaich %{name} post
notifications:
administration_emails: Brathan puist-d na rianachd
email_events: Tachartasan nam brathan puist-d
email_events_hint: 'Tagh na tachartasan dhan a bheil thu airson brathan fhaighinn:'
number:
human:
@ -1675,6 +1741,7 @@ gd:
import: Ion-phortadh
import_and_export: Ion-phortadh ⁊ às-phortadh
migrate: Imrich cunntais
notifications: Brathan puist-d
preferences: Roghainnean
profile: Pròifil phoblach
relationships: Dàimhean leantainn
@ -1935,6 +2002,7 @@ gd:
invalid_otp_token: Còd dà-cheumnach mì-dhligheach
otp_lost_help_html: Ma chaill thu an t-inntrigeadh dhan dà chuid diubh, s urrainn dhut fios a chur gu %{email}
rate_limited: Cus oidhirpean dearbhaidh, feuch ris a-rithist an ceann greis.
seamless_external_login: Rinn thu clàradh a-steach le seirbheis on taobh a-muigh, mar sin chan eil roghainnean an fhacail-fhaire s a phuist-d ri làimh dhut.
signed_in_as: 'Chlàraich thu a-steach mar:'
verification:
extra_instructions_html: <strong>Gliocas:</strong>Faodaidh an ceangal air an làrach-lìn agad a bhith do-fhaicsinneach. S e <code>rel="me"</code> a tha sa phàirt chudromach a bhacas riochd cuideigin eile air làraichean-lìn le susbaint air a gintinn o chleachdaiche. S urrainn dhut fiù taga <code>link</code> a chleachdadh ann am bann-cinn na duilleige seach <code>a</code> ach feumaidh sinn an HTML ruigsinn gun a bhith a ruith JavaScript.

View file

@ -29,6 +29,7 @@ ko:
created_msg: 중재 참고사항을 만들었습니다!
destroyed_msg: 중재 참고사항을 지웠습니다!
accounts:
add_email_domain_block: 이메일 도메인 차단
approve: 허가
approved_msg: 성공적으로 %{username}의 가입 신청서를 승인했습니다
are_you_sure: 확실합니까?
@ -55,6 +56,7 @@ ko:
demote: 강등
destroyed_msg: "%{username}의 데이터는 곧 삭제되도록 대기열에 들어갔습니다"
disable: 동결
disable_sign_in_token_auth: 이메일 토큰 인증 비활성화
disable_two_factor_authentication: 2단계 인증을 비활성화
disabled: 동결됨
display_name: 표시되는 이름
@ -63,6 +65,7 @@ ko:
email: 이메일
email_status: 이메일 상태
enable: 동결 해제
enable_sign_in_token_auth: 이메일 토큰 인증 활성화
enabled: 활성
enabled_msg: "%{username}의 동결을 성공적으로 해제 했습니다."
followers: 팔로워
@ -126,6 +129,7 @@ ko:
resubscribe: 다시 구독
role: 역할
search: 검색
search_same_email_domain: 같은 이메일 도메인을 가진 다른 사용자들
search_same_ip: 같은 IP의 다른 사용자들
security: 보안
security_measures:
@ -166,21 +170,26 @@ ko:
approve_appeal: 이의제기 승인
approve_user: 사용자 승인
assigned_to_self_report: 신고 맡기
change_email_user: 사용자 이메일 변경
change_role_user: 사용자 역할 변경
confirm_user: 사용자 확인
create_account_warning: 경고 생성
create_announcement: 공지사항 생성
create_canonical_email_block: 이메일 차단 생성
create_custom_emoji: 커스텀 에모지 생성
create_domain_allow: 도메인 허용 생성
create_domain_block: 도메인 차단 추가
create_email_domain_block: 이메일 도메인 차단 생성
create_ip_block: IP 규칙 만들기
create_unavailable_domain: 사용 불가능한 도메인 생성
create_user_role: 역할 생성
demote_user: 사용자 강등
destroy_announcement: 공지사항 삭제
destroy_canonical_email_block: 이메일 차단 삭제
destroy_custom_emoji: 커스텀 에모지 삭제
destroy_domain_allow: 도메인 허용 삭제
destroy_domain_block: 도메인 차단 삭제
destroy_email_domain_block: 이메일 도메인 차단 삭제
destroy_instance: 도메인 제거
destroy_ip_block: IP 규칙 삭제
destroy_status: 게시물 삭제
@ -188,8 +197,10 @@ ko:
destroy_user_role: 역할 삭제
disable_2fa_user: 2단계 인증 비활성화
disable_custom_emoji: 커스텀 에모지 비활성화
disable_sign_in_token_auth_user: 사용자의 이메일 토큰 인증 비활성화
disable_user: 사용자 비활성화
enable_custom_emoji: 커스텀 에모지 활성화
enable_sign_in_token_auth_user: 사용자의 이메일 토큰 인증 활성화
enable_user: 사용자 활성화
memorialize_account: 고인의 계정으로 전환
promote_user: 사용자 승급
@ -219,20 +230,26 @@ ko:
approve_appeal_html: "%{name} 님이 %{target}의 중재 결정에 대한 이의 제기를 승인했습니다"
approve_user_html: "%{name} 님이 %{target} 님의 가입을 승인했습니다"
assigned_to_self_report_html: "%{name} 님이 신고 %{target}을 자신에게 할당했습니다"
change_email_user_html: "%{name} 님이 %{target} 님의 이메일 주소를 변경했습니다"
change_role_user_html: "%{name} 님이 %{target} 님의 역할을 수정했습니다"
confirm_user_html: "%{name} 님이 %{target} 님의 이메일 주소를 승인했습니다"
create_account_warning_html: "%{name} 님이 %{target}에게 경고를 보냈습니다"
create_announcement_html: "%{name} 님이 새 공지 %{target}을 만들었습니다"
create_canonical_email_block_html: "%{name} 님이 %{target} 해시를 가진 이메일을 차단했습니다"
create_custom_emoji_html: "%{name} 님이 새로운 에모지 %{target}를 업로드 했습니다"
create_domain_allow_html: "%{name} 님이 %{target} 도메인을 허용리스트에 넣었습니다"
create_domain_block_html: "%{name} 님이 도메인 %{target}를 차단했습니다"
create_email_domain_block_html: "%{name} 님이 이메일 도메인 %{target}를 차단했습니다"
create_ip_block_html: "%{name} 님이 IP 규칙 %{target}을 만들었습니다"
create_unavailable_domain_html: "%{name} 님이 도메인 %{target}에 대한 전달을 중지했습니다"
create_user_role_html: "%{name} 님이 %{target} 역할을 생성했습니다"
demote_user_html: "%{name} 님이 사용자 %{target} 님을 강등했습니다"
destroy_announcement_html: "%{name} 님이 공지 %{target}을 삭제했습니다"
destroy_canonical_email_block_html: "%{name} 님이 %{target} 해시를 가진 이메일을 차단 해제했습니다"
destroy_custom_emoji_html: "%{name} 님이 에모지 %{target}를 삭제했습니다"
destroy_domain_allow_html: "%{name} 님이 %{target} 도메인과의 연합을 금지했습니다"
destroy_domain_block_html: "%{name} 님이 도메인 %{target}의 차단을 해제했습니다"
destroy_email_domain_block_html: "%{name} 님이 이메일 도메인 %{target}을 차단 해제하였습니다"
destroy_instance_html: "%{name} 님이 도메인 %{target}를 제거했습니다"
destroy_ip_block_html: "%{name} 님이 IP 규칙 %{target}을 삭제하였습니다"
destroy_status_html: "%{name} 님이 %{target} 님의 게시물을 삭제했습니다"

View file

@ -449,7 +449,7 @@ lt:
moderation:
all: Visi
limited: Limituotas
title: Moderacija
title: Prižiūrėjimas
public_comment: Viešas komentaras
title: Federacija
total_blocked_by_us: Mes užblokavome
@ -1116,6 +1116,7 @@ lt:
keep_self_bookmark: Laikyti įrašus, kuriuos pažymėjai
keep_self_bookmark_hint: Neištrina tavo pačių įrašų, jei esi juos pažymėjęs (-usi)
keep_self_fav_hint: Neištrina tavo pačių įrašų, jei esi juos pamėgęs (-usi)
min_age_label: Amžiaus riba
stream_entries:
sensitive_content: Jautrus turinys
themes:

View file

@ -211,6 +211,7 @@ ar:
setting_default_privacy: خصوصية المنشور
setting_default_sensitive: اعتبر الوسائط دائما كمحتوى حساس
setting_delete_modal: إظهار مربع حوار التأكيد قبل حذف أي منشور
setting_disable_hover_cards: تعطيل معاينة الملف الشخصي عند التمرير
setting_disable_swiping: تعطيل حركات التمرير
setting_display_media: عرض الوسائط
setting_display_media_default: افتراضي
@ -294,7 +295,7 @@ ar:
follow_request: ابعث بريدا إلكترونيا عندما يقوم أحدهم بإرسال طلب بالمتابعة
mention: ابعث بريداً إلكترونيًا عندما يُشير إليك أو يذكُرك أحدهم
pending_account: ابعث رسالة إلكترونية إن كان هناك حساب جديد بحاجة إلى مراجعة
reblog: ابعث بريداً إلكترونيًا عندما يقوم أحدهم بترقية منشورك
reblog: عندما يقوم أحدهم بإعادة نشر منشورك
report: هناك إبلاغ جديد تم إرساله
software_updates:
all: إشعاري عند توفّر كافة التحديثات

View file

@ -314,6 +314,7 @@ sr-Latn:
listable: Dozvoli da se ova heš oznaka pojavljuje u pretragama i predlozima
name: Heš oznaka
trendable: Dozvoli da se ova heš oznaka pojavi u okviru trendova
usable: Dozvoli objavama da lokalno koriste ovu heš oznaku
user:
role: Uloga
time_zone: Vremenska zona

View file

@ -314,6 +314,7 @@ sr:
listable: Дозволи да се ова хеш ознака појављује у претрагама и предлозима
name: Хеш ознака
trendable: Дозволи да се ова хеш ознака појави у оквиру трендова
usable: Дозволи објавама да локално користе ову хеш ознаку
user:
role: Улога
time_zone: Временска зона

View file

@ -314,6 +314,7 @@ uk:
listable: Дозволити появу цього хештеґа у каталозі пошуку і пропозицій
name: Хештеґ
trendable: Дозволити появу цього хештеґа у списку популярних хештеґів
usable: Дозволити дописам використовувати цей хештег локально
user:
role: Роль
time_zone: Часовий пояс

View file

@ -35,6 +35,7 @@ sl:
created_msg: Opomba moderiranja je uspešno ustvarjena!
destroyed_msg: Opomba moderiranja je uspešno uničena!
accounts:
add_email_domain_block: Blokiraj domeno e-pošte
approve: Odobri
approved_msg: Uspešno odobrena vloga prijave uporabnika %{username}
are_you_sure: Ali ste prepričani?
@ -61,6 +62,7 @@ sl:
demote: Ponižaj
destroyed_msg: Podatki uporabnika %{username} so zdaj v vrsti za trajen izbris
disable: Zamrzni
disable_sign_in_token_auth: Onemogoči overjanje z žetonom po e-pošti
disable_two_factor_authentication: Onemogoči 2FA
disabled: Zamrznjeno
display_name: Pojavno ime
@ -69,6 +71,7 @@ sl:
email: E-naslov
email_status: Stanje e-naslova
enable: Odmrzni
enable_sign_in_token_auth: Omogoči overjanje z žetonom po e-pošti
enabled: Omogočeno
enabled_msg: Uspešno odmrznjen račun uporabnika %{username}
followers: Sledilci
@ -135,6 +138,7 @@ sl:
resubscribe: Ponovno se naroči
role: Vloga
search: Iskanje
search_same_email_domain: Drugi uporabniki z isto e-poštno domeno
search_same_ip: Drugi uporabniki z istim IP
security: Varnost
security_measures:
@ -175,21 +179,26 @@ sl:
approve_appeal: Odobri pritožbo
approve_user: Odobri uporabnika
assigned_to_self_report: Dodeli prijavo
change_email_user: Spremeni e-naslov uporabnika
change_role_user: Spremeni vlogo uporabnika
confirm_user: Potrdi uporabnika
create_account_warning: Ustvari opozorilo
create_announcement: Ustvari obvestilo
create_canonical_email_block: Ustvari blokado e-naslova
create_custom_emoji: Ustvari emotikon po meri
create_domain_allow: Ustvari odobritev domene
create_domain_block: Ustvari blokado domene
create_email_domain_block: Ustvari blokado domene e-pošte
create_ip_block: Ustvari pravilo IP
create_unavailable_domain: Ustvari domeno, ki ni na voljo
create_user_role: Ustvari vlogo
demote_user: Ponižaj uporabnika
destroy_announcement: Izbriši obvestilo
destroy_canonical_email_block: Izbriši blokado e-naslova
destroy_custom_emoji: Izbriši emotikon po meri
destroy_domain_allow: Izbriši odobritev domene
destroy_domain_block: Izbriši blokado domene
destroy_email_domain_block: Izbriši blokado domene e-pošte
destroy_instance: Očisti domeno
destroy_ip_block: Izbriši pravilo IP
destroy_status: Izbriši objavo
@ -197,8 +206,10 @@ sl:
destroy_user_role: Uniči vlogo
disable_2fa_user: Onemogoči
disable_custom_emoji: Onemogoči emotikon po meri
disable_sign_in_token_auth_user: Onemogoči overjanje z žetonom po e-pošti za uporabnika
disable_user: Onemogoči uporabnika
enable_custom_emoji: Omogoči emotikon po meri
enable_sign_in_token_auth_user: Omogoči overjanje z žetonom po e-pošti za uporabnika
enable_user: Omogoči uporabnika
memorialize_account: Spomenificiraj račun
promote_user: Povišaj uporabnika
@ -228,20 +239,26 @@ sl:
approve_appeal_html: "%{name} je ugodil pritožbi uporabnika %{target} na moderatorsko odločitev"
approve_user_html: "%{name} je odobril/a registracijo iz %{target}"
assigned_to_self_report_html: "%{name} je dodelil/a prijavo %{target} sebi"
change_email_user_html: "%{name} je spremenil/a naslov e-pošte uporabnika %{target}"
change_role_user_html: "%{name} je spremenil/a vlogo %{target}"
confirm_user_html: "%{name} je potrdil/a naslov e-pošte uporabnika %{target}"
create_account_warning_html: "%{name} je poslal/a opozorilo %{target}"
create_announcement_html: "%{name} je ustvarila/a novo obvestilo %{target}"
create_canonical_email_block_html: "%{name} je dal/a na črni seznam e-pošto s ključnikom %{target}"
create_custom_emoji_html: "%{name} je posodobil/a emotikone %{target}"
create_domain_allow_html: "%{name} je dovolil/a federacijo z domeno %{target}"
create_domain_block_html: "%{name} je blokiral/a domeno %{target}"
create_email_domain_block_html: "%{name} je dal/a na črni seznam e-pošto domene %{target}"
create_ip_block_html: "%{name} je ustvaril/a pravilo za IP %{target}"
create_unavailable_domain_html: "%{name} je prekinil/a dostavo v domeno %{target}"
create_user_role_html: "%{name} je ustvaril/a vlogo %{target}"
demote_user_html: "%{name} je ponižal/a uporabnika %{target}"
destroy_announcement_html: "%{name} je izbrisal/a obvestilo %{target}"
destroy_canonical_email_block_html: "%{name} je odstranil/a s črnega seznama e-pošto s ključnikom %{target}"
destroy_custom_emoji_html: "%{name} je izbrisal/a emotikon %{target}"
destroy_domain_allow_html: "%{name} ni dovolil/a federacije z domeno %{target}"
destroy_domain_block_html: "%{name} je odblokiral/a domeno %{target}"
destroy_email_domain_block_html: "%{name} je odblokiral/a e-pošto domene %{target}"
destroy_instance_html: "%{name} je očistil/a domeno %{target}"
destroy_ip_block_html: "%{name} je izbrisal/a pravilo za IP %{target}"
destroy_status_html: "%{name} je odstranil/a objavo uporabnika %{target}"
@ -249,8 +266,10 @@ sl:
destroy_user_role_html: "%{name} je izbrisal/a vlogo %{target}"
disable_2fa_user_html: "%{name} je onemogočil/a dvofaktorsko zahtevo za uporabnika %{target}"
disable_custom_emoji_html: "%{name} je onemogočil/a emotikone %{target}"
disable_sign_in_token_auth_user_html: "%{name} je onemogočil/a overjanje z žetonom po e-pošti za uporabnika %{target}"
disable_user_html: "%{name} je onemogočil/a prijavo za uporabnika %{target}"
enable_custom_emoji_html: "%{name} je omogočil/a emotikone %{target}"
enable_sign_in_token_auth_user_html: "%{name} je omogočil/a overjanje z žetonom po e-pošti za uporabnika %{target}"
enable_user_html: "%{name} je omogočil/a prijavo za uporabnika %{target}"
memorialize_account_html: "%{name} je spremenil/a račun uporabnika %{target} v spominsko stran"
promote_user_html: "%{name} je povišal/a uporabnika %{target}"
@ -258,6 +277,7 @@ sl:
reject_user_html: "%{name} je zavrnil/a registracijo iz %{target}"
remove_avatar_user_html: "%{name} je odstranil podobo (avatar) uporabnika %{target}"
reopen_report_html: "%{name} je ponovno odprl/a prijavo %{target}"
resend_user_html: "%{name} je ponovno poslal_a potrditveno e-sporočilo za %{target}"
reset_password_user_html: "%{name} je ponastavil/a geslo uporabnika %{target}"
resolve_report_html: "%{name} je razrešil/a prijavo %{target}"
sensitive_account_html: "%{name} je označil/a medije računa %{target}'s kot občutljive"
@ -428,6 +448,7 @@ sl:
one: "%{count} poskus prijave zadnji teden"
other: "%{count} poskusov prijave zadnji teden"
two: "%{count} poskusa prijave zadnji teden"
created_msg: Domena e-pošte je bila uspešno dodana na črni seznam
delete: Izbriši
dns:
types:
@ -436,8 +457,12 @@ sl:
new:
create: Dodaj domeno
resolve: Razreši domeno
title: Nov vnos e-pošte na črni seznam
no_email_domain_block_selected: Nobena domena e-računa ni bila spremenjena, ker nobena ni bila izbrana
not_permitted: Ni dovoljeno
resolved_dns_records_hint_html: Ime domene se razreši na naslednje domene MX, ki so končno odgovorne za sprejemanje e-pošte. Blokiranje domene MX bo blokiralo prijave s poljubnega e-poštnega naslova, ki uporablja isto domeno MX, tudi če je vidno ime domene drugačno. <strong>Pazite, da ne blokirate večjih ponudnikov e-pošte.</strong>
resolved_through_html: Razrešeno prek %{domain}
title: Črni seznam e-pošt
export_domain_allows:
new:
title: Uvozi prepustnice domen
@ -596,6 +621,7 @@ sl:
resolve_description_html: Proti prijavljenemu računu ne bo izvedeno nobeno dejanje, noben ukrep ne bo zabeležen in prijava bo zaprta.
silence_description_html: Račun bo viden samo tistim, ki mu že sled ijo ali ga ročno poiščejo, s čimer bo resno omejen njegov doseg. To je vedno možno povrniti. Zaključi vse prijave zoper ta račun.
suspend_description_html: Račun in vsa njegova vsebina ne bo dostopna in bo postopoma izbrisana, interakcija z njim pa ne bo več možna. Dejanje je moč povrniti v roku 30 dni. Zaključi vse prijave zoper ta račun.
actions_description_html: Odločite se, katere ukrepe boste sprejeli za rešitev te prijave. Če sprejmete kazenski ukrep proti prijavljenemu računu, mu bo poslano e-poštno obvestilo, razen če je izbrana kategorija <strong>Neželena pošta</strong>.
actions_description_remote_html: Odločite se za dejanje, ki bo odločilo o tej prijavi. To bo vplivalo le na to, kako <strong>vaš</strong> strežnik komunicira s tem oddaljenim računom in obravnava njegovo vsebino.
add_to_report: Dodaj več v prijavo
already_suspended_badges:
@ -660,6 +686,7 @@ sl:
delete_data_html: Izbriši profil in vsebine <strong>@%{acct}</strong> čez 30 dni, razen če suspenz v tem času ni preklican
preview_preamble_html: 'Oseba <strong>@%{acct}</strong> bo prejela opozorilo z naslednjo vsebino:'
record_strike_html: Izdajte opomin računu <strong>@%{acct}</strong>, da boste lažje stopnjevali svoj odziv ob prihodnjih kršitvah s tega računa
send_email_html: Pošlji <strong>@%{acct}</strong> opozorilno e-sporočilo
warning_placeholder: Neobvezna dodatna utemeljitev dejanja moderiranja.
target_origin: Izvor prijavljenega računa
title: Prijave
@ -703,6 +730,7 @@ sl:
manage_appeals: Upravljaj pritožbe
manage_appeals_description: Omogoča uporabnikom, da pregledajo pritožbe glede dejanj moderiranja
manage_blocks: Upravljaj blokirano
manage_blocks_description: Omogoča uporabnikom, da blokirajo ponudnike e-pošte in naslove IP
manage_custom_emojis: Upravljaj emotikone po meri
manage_custom_emojis_description: Omogoča uporabnikom, da upravljajo emotikone po meri na strežniku
manage_federation: Upravljaj beli seznam
@ -720,6 +748,7 @@ sl:
manage_taxonomies: Upravljaj taksonomije
manage_taxonomies_description: Omogoča uporabnikom, da preverijo vsebino v trendu in posodobijo nastavitve ključnikov
manage_user_access: Upravljaj dostop uporabnikov
manage_user_access_description: Omogoča uporabnikom, da onemogočijo drugim uporabnikom dvofazno overjanje, spremenijo njihov e-naslov ter ponastavijo njihovo geslo
manage_users: Upravljaj uporabnike
manage_users_description: Omogoča uporabnikom, da vidijo podrobnosti drugih uporabnikov in nad njimi izvedejo dejanja moderiranja
manage_webhooks: Upravljaj spletne zanke
@ -794,6 +823,7 @@ sl:
destroyed_msg: Prenos na strežnik uspešno izbrisan!
software_updates:
critical_update: Kritično — čim prej posodobite
description: Vašo namestitev Mastodona je priporočeno vedno imeti posodobljeno in tako koristiti najnovejše popravke ter zmožnosti. Poleg tega je včasih nujno čim prej posodobiti Mastodon in se s tem izogniti varnostnim težavam. Zato Mastodon vsakih 30 minut preverja razpoložljivost posodobitev in vas o njih obvešča glede na vaše nastavitve obveščanja po e-pošti.
documentation_link: Več o tem
release_notes: Opombe ob izdaji
title: Razpoložljive posodobitve
@ -881,11 +911,13 @@ sl:
message_html: "<strong>Vaša predmetna shramba je napačno nastavljena. Zasebnost vaših uporabnikov je izpostavljena tveganjem.</strong>"
tags:
moderation:
not_trendable: Ni v trendu
not_usable: Ni uporabno
pending_review: Čakajoče na pregled
review_requested: Zahtevan pregled
reviewed: Pregledano
title: Stanje
trendable: V trendu
unreviewed: Nepregledano
usable: Uporabno
name: Ime
@ -900,10 +932,16 @@ sl:
trends:
allow: Dovoli
approved: Odobren
confirm_allow: Ali ste prepričani, da želite dopustiti izbrane oznake?
confirm_disallow: Ali ste prepričani, da želite prepovedati izbrane oznake?
disallow: Ne dovoli
links:
allow: Dovoli povezavo
allow_provider: Dovoli izdajatelja
confirm_allow: Ali ste prepričani, da želite dopustiti izbrane povezave?
confirm_allow_provider: Ali ste prepričani, da želite dopustiti izbrane ponudnike?
confirm_disallow: Ali ste prepričani, da želite prepovedati izbrane povezave?
confirm_disallow_provider: Ali ste prepričani, da želite prepovedati izbrane ponudnike?
description_html: To so povezave, ki jih trenutno veliko delijo računi, iz katerih vaš strežnik vidi objave. Vašim uporabnikom lahko pomaga izvedeti, kaj se dogaja po svetu. Nobene povezave niso javno prikazane, dokler ne odobrite izdajatelja. Posamezne povezave lahko tudi dovolite ali zavrnete.
disallow: Ne dovoli povezave
disallow_provider: Ne dovoli izdajatelja
@ -929,6 +967,10 @@ sl:
statuses:
allow: Dovoli objavo
allow_account: Dovoli avtorja
confirm_allow: Ali ste prepričani, da želite dopustiti izbrana stanja?
confirm_allow_account: Ali ste prepričani, da želite dopustiti izbrane račune?
confirm_disallow: Ali ste prepričani, da želite prepovedati izbrana stanja?
confirm_disallow_account: Ali ste prepričani, da želite prepovedati izbrane račune?
description_html: To so objave, za katere vaš strežnik ve, da so trenutno v skupni rabi in med priljubljenimi. Vašim novim uporabnikom in uporabnikom, ki se vračajo, lahko pomaga najti več oseb, ki jim bodo sledili. Nobena objava ni javno prikazana, dokler avtorja ne odobrite in avtor ne dovoli, da se njegov račun predlaga drugim. Posamezne objave lahko tudi dovolite ali zavrnete.
disallow: Ne dovoli objave
disallow_account: Ne dovoli avtorja
@ -965,6 +1007,7 @@ sl:
one: Uporabila %{count} oseba v zadnjem tednu
other: Uporabilo %{count} oseb v zadnjem tednu
two: Uporabili %{count} osebi v zadnjem tednu
title: Priporočila in trendi
trending: V porastu
warning_presets:
add_new: Dodaj novo
@ -1051,7 +1094,9 @@ sl:
guide_link_text: Vsakdo lahko prispeva.
sensitive_content: Občutljiva vsebina
application_mailer:
notification_preferences: Spremenite e-poštne nastavitve
salutation: "%{name},"
settings: 'Spremenite e-poštne nastavitve: %{link}'
unsubscribe: Odjavi od naročnine
view: 'Pogled:'
view_profile: Ogled profila
@ -1071,6 +1116,7 @@ sl:
hint_html: Samo še nekaj. Moramo se prepričati, da ste človek (to nam pomaga pri preprečevanju neželenih vsebin). Rešite spodnji CAPTCHA in kliknite »Nadaljuj«.
title: Varnostno preverjanje
confirmations:
awaiting_review: Vaš e-poštni naslov je potrjen. Skrbniki %{domain} bodo pregledali vašo prijavo. Če odobrijo vaš račun, boste o tem prejeli e-pošto.
awaiting_review_title: Vaša prijava se pregleduje
clicking_this_link: s klikom na to povezavo
login_link: prijavo
@ -1078,6 +1124,7 @@ sl:
redirect_to_app_html: Morali bi biti preusmerjeni na aplikacijo <strong>%{app_name}</strong>. Če se to ni zgodilo, poskusite %{clicking_this_link} ali pa se ročno vrnite na aplikacijo.
registration_complete: Vaša prijava na %{domain} je sedaj zaključena.
welcome_title: Pozdravljeni, %{name}!
wrong_email_hint: Če ta e-poštni naslov ni pravilen, ga lahko spremenite v nastavitvah računa.
delete_account: Izbriši račun
delete_account_html: Če želite izbrisati svoj račun, lahko nadaljujete <a href="%{path}">tukaj</a>. Prosili vas bomo za potrditev.
description:
@ -1098,6 +1145,7 @@ sl:
or_log_in_with: Ali se prijavite z
privacy_policy_agreement_html: Prebral_a sem in se strinjam s <a href="%{privacy_policy_path}" target="_blank">pravilnikom o zasebnosti</a>.
progress:
confirm: Potrdi e-pošto
details: Vaši podatki
review: Naš pregled
rules: Sprejmi pravila
@ -1119,8 +1167,10 @@ sl:
security: Varnost
set_new_password: Nastavi novo geslo
setup:
email_below_hint_html: Poglejte v mapo neželene pošte ali zaprosite za novega. Če ste podali napačen e-naslov, ga lahko popravite.
email_settings_hint_html: Kliknite povezavo, ki smo vam jo poslali, da overite %{email}. Počakali bomo.
link_not_received: Ali ste prejeli povezavo?
new_confirmation_instructions_sent: Čez nekaj minut boste prejeli novo e-sporočilo s potrditveno povezavo!
title: Preverite svojo dohodno e-pošto
sign_in:
preamble_html: Prijavite se s svojimi poverilnicami <strong>%{domain}</strong>. Če vaš račun gostuje na drugem strežniku, se tukaj ne boste mogli prijaviti.
@ -1131,7 +1181,9 @@ sl:
title: Naj vas namestimo na %{domain}.
status:
account_status: Stanje računa
confirming: Čakanje na potrditev e-pošte.
functional: Vaš račun je polno opravilen.
pending: Naše osebje preverja vašo prijavo. To lahko traja nekaj časa. Če bo vaša prijava odobrena, boste prejeli e-pošto.
redirecting_to: Vaš račun ni dejaven, ker trenutno preusmerja na račun %{acct}.
self_destruct: Ker se %{domain} zapira, boste imeli omejen dostop da svojega računa.
view_strikes: Pokaži pretekle ukrepe proti mojemu računu
@ -1174,6 +1226,9 @@ sl:
before: 'Pred nadaljevanjem previdno preberite naslednje opombe:'
caches: Vsebina, ki jo medpomnijo drugi strežniki, lahko vztraja
data_removal: Vaše objave in drugi podatki bodo trajno odstranjeni
email_change_html: <a href="%{path}">Svoj e-naslov lahko spremenite</a> brez izbrisa svojega računa
email_contact_html: Če še vedno ni dostavljeno, lahko za pomoč pošljete e-sporočilo na naslov <a href="mailto:%{email}">%{email}</a>
email_reconfirmation_html: Če niste prejeli potrditvenega e-sporočila, lahko <a href="%{path}">znova zaprosite zanj</a>
irreversible: Vašega računa ne boste mogli obnoviti ali ponovno aktivirati
more_details_html: Za podrobnosti glejte <a href="%{terms_path}">politiko zasebnosti</a>.
username_available: Vaše uporabniško ime bo znova na voljo
@ -1422,6 +1477,7 @@ sl:
authentication_methods:
otp: aplikacija za dvoravenjsko overjanje
password: geslo
sign_in_token: varnostna koda po e-pošti
webauthn: varnostni ključi
description_html: Če opazite dejavnost, ki je ne prepoznate kot svoje, razmislite o spremembi svojega gesla in omogočanju dvoravenskega overjanja.
empty: Zgodovina overjanja ni na voljo
@ -1432,6 +1488,16 @@ sl:
unsubscribe:
action: Da, odjavi me
complete: Odjavljeni
confirmation_html: Ali se res želite odjaviti od prejemanja %{type} za Mastodon na %{domain} na svojo e-pošto %{email}? Kadarkoli se lahko znova prijavite iz svojih <a href="%{settings_path}">nastavitev e-poštnih obvestil</a>.
emails:
notification_emails:
favourite: e-sporočil z obvestili o priljubljenosti
follow: e-sporočil z obvestili o sledenju
follow_request: e-sporočil o zahtevah za sledenje
mention: e-sporočil z obvestili o omembah
reblog: e-sporočil z obvestili o izpostavljanju
resubscribe_html: Če ste se odjavili po pomoti, se lahko znova prijavite iz svojih <a href="%{settings_path}">nastavitev e-poštnih obvestil</a>.
success_html: Nič več ne boste prejemali %{type} za Mastodon na %{domain} na svoj e-naslov %{email}.
title: Odjavi od naročnine
media_attachments:
validations:
@ -1512,6 +1578,8 @@ sl:
update:
subject: "%{name} je uredil(a) objavo"
notifications:
administration_emails: E-poštna obvestila skrbnika
email_events: Dogodki za e-obvestila
email_events_hint: 'Izberite dogodke, za katere želite prejmati obvestila:'
number:
human:
@ -1670,6 +1738,7 @@ sl:
import: Uvozi
import_and_export: Uvoz in izvoz
migrate: Selitev računa
notifications: E-poštna obvestila
preferences: Nastavitve
profile: Profil
relationships: Sledenja in sledilci
@ -1930,6 +1999,7 @@ sl:
invalid_otp_token: Neveljavna dvofaktorska koda
otp_lost_help_html: Če ste izgubili dostop do obeh, stopite v stik z %{email}
rate_limited: Preveč poskusov preverjanja pristnosti, poskusite kasneje.
seamless_external_login: Prijavljeni ste prek zunanje storitve, tako da nastavitve gesla in e-pošte niso na voljo.
signed_in_as: 'Vpisani kot:'
verification:
extra_instructions_html: <strong>Nasvet:</strong> Povezava na vaši spletni strani je lahko nevidna. Pomembni del je atribut <code>rel="me"</code>, ki preprečuje lažno predstavljanje na spletnih straneh z uporabniško ustvarjeno vsebino. Namesto oznake <code>a</code> lahko uporabite tudi oznako <code>link</code> znotraj glave (<code>head</code>) spletne strani, vendar mora biti HTML dosegljiv brez izvajanja skript JavaScript.

View file

@ -1431,6 +1431,14 @@ sq:
unsubscribe:
action: Po, shpajtomëni
complete: U shpajtuat
confirmation_html: Jeni i sigurt se doni të shpajtoheni nga marrje %{type} për Mastodon te %{domain} në email-in tuaj %{email}? Mundeni përherë të ripajtoheni që nga <a href="%{settings_path}">rregullimet tuaja për njoftime me email</a>.
emails:
notification_emails:
favourite: email-e njoftimesh parapëlqimesh
follow: email-e njoftimesh ndjekjeje
follow_request: email-e kërkesash ndjekjeje
mention: email-e njoftimesh përmendjesh
reblog: email-e njoftimesh përforcimesh
resubscribe_html: Nëse u shpajtuat gabimisht, mund të ripajtoheni që nga <a href="%{settings_path}">rregullimet tuaja për njoftime me email</a>.
success_html: Sdo të merrni më %{type} për Mastodon te %{domain} në email-in tuaj te %{email}.
title: Shpajtohuni
@ -1513,6 +1521,8 @@ sq:
update:
subject: "%{name} përpunoi një postim"
notifications:
administration_emails: Njoftime email përgjegjësi
email_events: Akte për njoftime email
email_events_hint: 'Përzgjidhni akte për të cilët doni të merrni njoftime:'
number:
human:
@ -1671,6 +1681,7 @@ sq:
import: Importo
import_and_export: Importim dhe eksportim
migrate: Migrim llogarie
notifications: Njoftime me email
preferences: Parapëlqime
profile: Profil
relationships: Ndjekje dhe ndjekës

View file

@ -1885,7 +1885,7 @@ sr-Latn:
verification:
extra_instructions_html: <strong>Savet:</strong>Veza na vašem veb sajtu može da bude nevidljiva. Važan deo je <code>rel="me"</code> koji sprečava lažno predstavljanje na veb sajtovima sa sadržajem koji generiše korisnik. Možete čak da koristite oznaku <code>veze</code> u zaglavlju stranice umesto <code>a</code>, ali HTML mora biti dostupan bez izvršavanja JavaScript-a.
here_is_how: Evo kako
hint_html: "<strong>Verifikacija vašeg identiteta na Mastodon-u je za svakoga.</strong> Zasnovano na otvorenim veb standardima, sada i zauvek besplatno. Sve što vam treba je lični veb sajt po kome vas ljudi prepoznaju. Kada se povežete sa ovim veb sajtom sa svog profila, proverićemo da li je veb sajt povezan sa vašim profilom i na njemu ćemo prikazati vizuelni indikator."
hint_html: "<strong>Svako može da verifikuje svoj identitet na Mastodon-u.</strong> Zasnovano na otvorenim veb standardima, sada i zauvek besplatno. Sve što vam treba je lični veb sajt po kome vas ljudi prepoznaju. Kada se povežete sa ovim veb sajtom sa svog profila, proverićemo da li je veb sajt povezan sa vašim profilom i na njemu ćemo prikazati vizuelni indikator."
instructions_html: Kopirajte i nalepite kod ispod u HTML svog veb sajta. Zatim dodajte adresu svog veb sajta u jedno od dodatnih polja na svom profilu sa kartice „Uredi profil” i sačuvajte promene.
verification: Verifikacija
verified_links: Vaše verifikovane veze

View file

@ -33,6 +33,7 @@ sr:
created_msg: Модераторска белешка успешно направљена!
destroyed_msg: Модераторска белешка успешно обрисана!
accounts:
add_email_domain_block: Блокирај домен е-поште
approve: Одобри
approved_msg: Захтев за регистрацију корисника %{username} је успешно одобрен
are_you_sure: Да ли сте сигурни?
@ -59,6 +60,7 @@ sr:
demote: Ражалуј
destroyed_msg: Подаци корисника %{username} су неповратно стављени у ред за брисање
disable: Замрзни
disable_sign_in_token_auth: Онемогући аутентификацију токена е-поште
disable_two_factor_authentication: Искључи 2FA
disabled: Замрзнут
display_name: Име за приказ
@ -67,6 +69,7 @@ sr:
email: Е-пошта
email_status: Статус е-поште
enable: Омогући
enable_sign_in_token_auth: Омогући аутентификацију токена е-поште
enabled: Омогућен
enabled_msg: Успешно одлеђен налог корисника %{username}
followers: Пратиоци
@ -132,6 +135,7 @@ sr:
resubscribe: Поново се претплати
role: Улога
search: Претрага
search_same_email_domain: Остали корисници са истим доменом е-поште
search_same_ip: Остали корисници са истом IP адресом
security: Безбедност
security_measures:
@ -172,21 +176,26 @@ sr:
approve_appeal: Уважи жалбу
approve_user: Одобри корисника
assigned_to_self_report: Додели пријаву
change_email_user: Промени e-адресу за корисника
change_role_user: Промени улогу корисника
confirm_user: Потврди корисника
create_account_warning: Креирај упозорење
create_announcement: Креирај најаву
create_canonical_email_block: Креирај блок е-поште
create_custom_emoji: Направи прилагођени емоџи
create_domain_allow: Додај дозвољени домен
create_domain_block: Додај блокирани домен
create_email_domain_block: Креирај блок домена е-поште
create_ip_block: Направи IP услов
create_unavailable_domain: Додај домен као недоступан
create_user_role: Креирај улогу
demote_user: Смањи овлашћења корисника
destroy_announcement: Избриши најаву
destroy_canonical_email_block: Избриши блок е-поште
destroy_custom_emoji: Обриши прилагођени емоџи
destroy_domain_allow: Обриши дозвољени домен
destroy_domain_block: Обриши блокирани домен
destroy_email_domain_block: Избриши блок домена е-поште
destroy_instance: Очисти домен
destroy_ip_block: Обриши IP услов
destroy_status: Избриши пост
@ -194,8 +203,10 @@ sr:
destroy_user_role: Уништи позицију
disable_2fa_user: Онемогући двофакторску аутентификацију
disable_custom_emoji: Онемогући прилагођене емоџије
disable_sign_in_token_auth_user: Онемогући аутентификацију токена е-поште за корисника
disable_user: Онемогући корисника
enable_custom_emoji: Омогући прилагођене емоџије
enable_sign_in_token_auth_user: Омогући аутентификацију токена е-поште за корисника
enable_user: Омогући корисника
memorialize_account: Претвори у меморијални налог
promote_user: Унапреди корисника
@ -218,26 +229,33 @@ sr:
update_custom_emoji: Ажурирај прилагођене емоџије
update_domain_block: Ажурирај домен блок
update_ip_block: Ажурирај IP услов
update_report: Ажурирај извештај
update_status: Уреди објаву
update_user_role: Уреди улогу
actions:
approve_appeal_html: "%{name} је уважио жалбу корисника %{target} на одлуку модератора"
approve_user_html: "%{name} је одобрио/-ла регистрацију корисника %{target}"
assigned_to_self_report_html: "%{name} је себи доделио/-ла пријаву %{target}"
change_email_user_html: "%{name} је променио/ла адресу е-поште за корисника %{target}"
change_role_user_html: "%{name} је променио/-ла овлашћења корисника %{target}"
confirm_user_html: "%{name} је потврдио/ла адресу е-поште за корисника %{target}"
create_account_warning_html: "%{name} је послао/-ла упозорење кориснику %{target}"
create_announcement_html: "%{name} је направио/-ла ново саопштење %{target}"
create_canonical_email_block_html: "%{name} је блокирао/ла адресу е-поште са хешом %{target}"
create_custom_emoji_html: "%{name} је отпремио/-ла нове емоџије %{target}"
create_domain_allow_html: "%{name} је дозволио/-ла федерацију са доменом %{target}"
create_domain_block_html: "%{name} је блокирао/-ла домен %{target}"
create_email_domain_block_html: "%{name} је блокирао/ла домен е-поште %{target}"
create_ip_block_html: "%{name} је направио/-ла услов за IP адресе %{target}"
create_unavailable_domain_html: "%{name} је обуставио/-ла испоручивање домену %{target}"
create_user_role_html: "%{name} је направио/-ла %{target} позицију"
demote_user_html: "%{name} је смањио овлашћења корисника %{target}"
destroy_announcement_html: "%{name} је обрисао/-ла саопштење %{target}"
destroy_canonical_email_block_html: "%{name} је одблокирао/ла адресу е-поште са хешом %{target}"
destroy_custom_emoji_html: "%{name} је обрисао/-ла емоџи %{target}"
destroy_domain_allow_html: "%{name} је забранио/-ла федерацију са доменом %{target}"
destroy_domain_block_html: "%{name} је одблокирао/-ла домен %{target}"
destroy_email_domain_block_html: "%{name} је одблокирао/ла домен е-поште %{target}"
destroy_instance_html: "%{name} је очистио/-ла домен %{target}"
destroy_ip_block_html: "%{name} је обрисао/-ла услов за IP адресе %{target}"
destroy_status_html: "%{name} је избрисао/-ла објаву корисника %{target}"
@ -245,8 +263,10 @@ sr:
destroy_user_role_html: "%{name} је избрисао/-ла %{target} позицију"
disable_2fa_user_html: "%{name} је онемогућио/-ла двофакторску аутентификацију за корисника %{target}"
disable_custom_emoji_html: "%{name} је онемогућио/-ла емоџи %{target}"
disable_sign_in_token_auth_user_html: "%{name} је онемогућио/ла аутентификацију токена е-поште за %{target}"
disable_user_html: "%{name} је онемогућио/-ла пријављивање за корисника %{target}"
enable_custom_emoji_html: "%{name} је омогућио/-ла емоџи %{target}"
enable_sign_in_token_auth_user_html: "%{name} је омогућио/ла аутентификацију токена е-поште за %{target}"
enable_user_html: "%{name} је омогућио/-ла пријављивање кориснику %{target}"
memorialize_account_html: "%{name} је претворио/-ла налог корисника %{target} у меморијалну страницу"
promote_user_html: "%{name} је унапредио/-ла корисника %{target}"
@ -254,6 +274,7 @@ sr:
reject_user_html: "%{name} је одбио/-ла регистрацију корисника %{target}"
remove_avatar_user_html: "%{name} је уклонио аватар корисника %{target}"
reopen_report_html: "%{name} је поново отворио/-ла пријаву %{target}"
resend_user_html: "%{name} је поништио/ла е-пошту за потврду за %{target}"
reset_password_user_html: "%{name} је ресетовао/-ла лозинку корисника %{target}"
resolve_report_html: "%{name} је решио/-ла пријаву %{target}"
sensitive_account_html: "%{name} је означио/-ла медије налога %{target} као осетљиве"
@ -419,6 +440,7 @@ sr:
few: "%{count} покушаја током претходне недеље"
one: "%{count} покушај током претходне недеље"
other: "%{count} покушаја регистрације током претходне недеље"
created_msg: Успешно блокиран домен е-поште
delete: Обриши
dns:
types:
@ -427,8 +449,12 @@ sr:
new:
create: Додај домен
resolve: Претвори домен
title: Блокирај нови домен е-поште
no_email_domain_block_selected: Ниједан блок домена е-поште није промењен јер ниједан није изабран
not_permitted: Није дозвољено
resolved_dns_records_hint_html: Име домена се претвара у следеће MX домене, који су напослетку одговорни за прихватање е-поште. Блокирање MX домена ће блокирати регистрације са сваке адресе е-поште која користи тај MX домен, чак и у случају када се видљиво име домена разликује. <strong>Водите рачуна о томе да не блокирате главне добављаче е-поште.</strong>
resolved_through_html: Преусмерено кроз %{domain}
title: Блокирани домени е-поште
export_domain_allows:
new:
title: Увези дозвољене домене
@ -453,6 +479,9 @@ sr:
title: Препоруке за праћење
unsuppress: Врати препоруку за праћење
instances:
audit_log:
title: Недавни записници
view_all: Погледај пуне записнике
availability:
description_html:
few: Уколико испорука домену не успе ниједном током <strong>%{count} различитих дана</strong>, даљи покушаји испоруке неће бити иницирани осим уколико се не прими испорука <em>са</em> домена.
@ -583,6 +612,7 @@ sr:
resolve_description_html: Ниједна радња неће бити предузета против пријављеног налога, ниједан преступ није уписан и пријава ће бити затворена.
silence_description_html: Налог ће бити видљив само онима који га већ прате или који га ручно потраже, што ће значајно ограничити његов домет. Ограничење се може повући у сваком тренутку. Затвара све пријаве поднете против овог налога.
suspend_description_html: Налог и сви његови садржаји ће постати недоступни и у једном тренутку избрисани, а интеракција са налогом више неће бити могућа. Суспензија се може повући у року од 30 дана. Затвара све пријаве поднете против овог налога.
actions_description_html: Одлучите коју радњу да спроведете ради решавања ове пријаве. Уколико спроведете казнену радњу против пријављеног налога, власник налога ће бити обавештен путем е-поште, осим уколико ознака <strong>„Нежељене поруке”</strong> није одабрана.
actions_description_remote_html: Одлучите коју радњу да предузмете ради решавања ове пријаве. Ово ће утицати само на то како <strong>Ваш</strong> сервер комуницира са овим удаљеним налогом и обрађује његов садржај.
add_to_report: Додај још у пријаву
already_suspended_badges:
@ -1885,7 +1915,7 @@ sr:
verification:
extra_instructions_html: <strong>Савет:</strong>Веза на вашем веб сајту може да буде невидљива. Важан део је <code>rel="me"</code> који спречава лажно представљање на веб сајтовима са садржајем који генерише корисник. Можете чак да користите ознаку <code>везе</code> у заглављу странице уместо <code>а</code>, али HTML мора бити доступан без извршавања JavaScript-а.
here_is_how: Ево како
hint_html: "<strong>Верификација вашег идентитета на Mastodon-у је за свакога.</strong> Засновано на отвореним веб стандардима, сада и заувек бесплатно. Све што вам треба је лични веб сајт по коме вас људи препознају. Када се повежете са овим веб сајтом са свог профила, проверићемо да ли је веб сајт повезан са вашим профилом и на њему ћемо приказати визуелни индикатор."
hint_html: "<strong>Свако може да верификује свој идентитет на Mastodon-у.</strong> Засновано на отвореним веб стандардима, сада и заувек бесплатно. Све што вам треба је лични веб сајт по коме вас људи препознају. Када се повежете са овим веб сајтом са свог профила, проверићемо да ли је веб сајт повезан са вашим профилом и на њему ћемо приказати визуелни индикатор."
instructions_html: Копирајте и налепите код испод у HTML свог веб сајта. Затим додајте адресу свог веб сајта у једно од додатних поља на свом профилу са картице „Уреди профил” и сачувајте промене.
verification: Верификација
verified_links: Ваше верификоване везе

View file

@ -56,6 +56,7 @@ th:
demote: ลดขั้น
destroyed_msg: ตอนนี้จัดคิวเพื่อลบข้อมูลของ %{username} ในเร็ว ๆ นี้แล้ว
disable: อายัด
disable_sign_in_token_auth: ปิดใช้งานการรับรองความถูกต้องด้วยโทเคนอีเมล
disable_two_factor_authentication: ปิดใช้งาน 2FA
disabled: อายัดอยู่
display_name: ชื่อที่แสดง
@ -64,6 +65,7 @@ th:
email: อีเมล
email_status: สถานะอีเมล
enable: เลิกอายัด
enable_sign_in_token_auth: เปิดใช้งานการรับรองความถูกต้องด้วยโทเคนอีเมล
enabled: เปิดใช้งานอยู่
enabled_msg: เลิกอายัดบัญชีของ %{username} สำเร็จ
followers: ผู้ติดตาม
@ -127,6 +129,7 @@ th:
resubscribe: บอกรับใหม่
role: บทบาท
search: ค้นหา
search_same_email_domain: ผู้ใช้อื่น ๆ ที่มีโดเมนอีเมลเดียวกัน
search_same_ip: ผู้ใช้อื่น ๆ ที่มี IP เดียวกัน
security: ความปลอดภัย
security_measures:
@ -194,8 +197,10 @@ th:
destroy_user_role: ทำลายบทบาท
disable_2fa_user: ปิดใช้งาน 2FA
disable_custom_emoji: ปิดใช้งานอีโมจิที่กำหนดเอง
disable_sign_in_token_auth_user: ปิดใช้งานการรับรองความถูกต้องด้วยโทเคนอีเมลสำหรับผู้ใช้
disable_user: ปิดใช้งานผู้ใช้
enable_custom_emoji: เปิดใช้งานอีโมจิที่กำหนดเอง
enable_sign_in_token_auth_user: เปิดใช้งานการรับรองความถูกต้องด้วยโทเคนอีเมลสำหรับผู้ใช้
enable_user: เปิดใช้งานผู้ใช้
memorialize_account: ทำให้บัญชีเป็นอนุสรณ์
promote_user: เลื่อนขั้นผู้ใช้
@ -225,20 +230,26 @@ th:
approve_appeal_html: "%{name} ได้อนุมัติการอุทธรณ์การตัดสินใจในการกลั่นกรองจาก %{target}"
approve_user_html: "%{name} ได้อนุมัติการลงทะเบียนจาก %{target}"
assigned_to_self_report_html: "%{name} ได้มอบหมายรายงาน %{target} ให้กับตนเอง"
change_email_user_html: "%{name} ได้เปลี่ยนที่อยู่อีเมลของผู้ใช้ %{target}"
change_role_user_html: "%{name} ได้เปลี่ยนบทบาทของ %{target}"
confirm_user_html: "%{name} ได้ยืนยันที่อยู่อีเมลของผู้ใช้ %{target}"
create_account_warning_html: "%{name} ได้ส่งคำเตือนไปยัง %{target}"
create_announcement_html: "%{name} ได้สร้างประกาศใหม่ %{target}"
create_canonical_email_block_html: "%{name} ได้ปิดกั้นอีเมลที่มีแฮช %{target}"
create_custom_emoji_html: "%{name} ได้อัปโหลดอีโมจิใหม่ %{target}"
create_domain_allow_html: "%{name} ได้อนุญาตการติดต่อกับภายนอกกับโดเมน %{target}"
create_domain_block_html: "%{name} ได้ปิดกั้นโดเมน %{target}"
create_email_domain_block_html: "%{name} ได้ปิดกั้นโดเมนอีเมล %{target}"
create_ip_block_html: "%{name} ได้สร้างกฎสำหรับ IP %{target}"
create_unavailable_domain_html: "%{name} ได้หยุดการจัดส่งไปยังโดเมน %{target}"
create_user_role_html: "%{name} ได้สร้างบทบาท %{target}"
demote_user_html: "%{name} ได้ลดขั้นผู้ใช้ %{target}"
destroy_announcement_html: "%{name} ได้ลบประกาศ %{target}"
destroy_canonical_email_block_html: "%{name} ได้เลิกปิดกั้นอีเมลที่มีแฮช %{target}"
destroy_custom_emoji_html: "%{name} ได้ลบอีโมจิ %{target}"
destroy_domain_allow_html: "%{name} ได้ไม่อนุญาตการติดต่อกับภายนอกกับโดเมน %{target}"
destroy_domain_block_html: "%{name} ได้เลิกปิดกั้นโดเมน %{target}"
destroy_email_domain_block_html: "%{name} ได้เลิกปิดกั้นโดเมนอีเมล %{target}"
destroy_instance_html: "%{name} ได้ล้างข้อมูลโดเมน %{target}"
destroy_ip_block_html: "%{name} ได้ลบกฎสำหรับ IP %{target}"
destroy_status_html: "%{name} ได้เอาโพสต์โดย %{target} ออก"
@ -246,8 +257,10 @@ th:
destroy_user_role_html: "%{name} ได้ลบบทบาท %{target}"
disable_2fa_user_html: "%{name} ได้ปิดใช้งานความต้องการสองปัจจัยสำหรับผู้ใช้ %{target}"
disable_custom_emoji_html: "%{name} ได้ปิดใช้งานอีโมจิ %{target}"
disable_sign_in_token_auth_user_html: "%{name} ได้ปิดใช้งานการรับรองความถูกต้องด้วยโทเคนอีเมลสำหรับ %{target}"
disable_user_html: "%{name} ได้ปิดใช้งานการเข้าสู่ระบบสำหรับผู้ใช้ %{target}"
enable_custom_emoji_html: "%{name} ได้เปิดใช้งานอีโมจิ %{target}"
enable_sign_in_token_auth_user_html: "%{name} ได้เปิดใช้งานการรับรองความถูกต้องด้วยโทเคนอีเมลสำหรับ %{target}"
enable_user_html: "%{name} ได้เปิดใช้งานการเข้าสู่ระบบสำหรับผู้ใช้ %{target}"
memorialize_account_html: "%{name} ได้เปลี่ยนบัญชีของ %{target} เป็นหน้าอนุสรณ์"
promote_user_html: "%{name} ได้เลื่อนขั้นผู้ใช้ %{target}"
@ -255,6 +268,7 @@ th:
reject_user_html: "%{name} ได้ปฏิเสธการลงทะเบียนจาก %{target}"
remove_avatar_user_html: "%{name} ได้เอาภาพประจำตัวของ %{target} ออก"
reopen_report_html: "%{name} ได้เปิดรายงาน %{target} ใหม่"
resend_user_html: "%{name} ได้ส่งอีเมลการยืนยันสำหรับ %{target} ใหม่"
reset_password_user_html: "%{name} ได้ตั้งรหัสผ่านของผู้ใช้ %{target} ใหม่"
resolve_report_html: "%{name} ได้แก้ปัญหารายงาน %{target}"
sensitive_account_html: "%{name} ได้ทำเครื่องหมายสื่อของ %{target} ว่าละเอียดอ่อน"
@ -410,6 +424,7 @@ th:
allow_registrations_with_approval: อนุญาตการลงทะเบียนด้วยการอนุมัติ
attempts_over_week:
other: "%{count} ความพยายามในการลงทะเบียนในช่วงสัปดาห์ที่ผ่านมา"
created_msg: ปิดกั้นโดเมนอีเมลสำเร็จ
delete: ลบ
dns:
types:
@ -418,8 +433,12 @@ th:
new:
create: เพิ่มโดเมน
resolve: แปลงที่อยู่โดเมน
title: ปิดกั้นโดเมนอีเมลใหม่
no_email_domain_block_selected: ไม่มีการเปลี่ยนแปลงการปิดกั้นโดเมนอีเมลเนื่องจากไม่มีการเลือก
not_permitted: ไม่ได้รับอนุญาต
resolved_dns_records_hint_html: ชื่อโดเมนแปลงที่อยู่เป็นโดเมน MX ดังต่อไปนี้ ซึ่งท้ายที่สุดแล้วจะรับผิดชอบสำหรับการยอมรับอีเมล การปิดกั้นโดเมน MX จะปิดกั้นการลงทะเบียนจากที่อยู่อีเมลใด ๆ ซึ่งใช้โดเมน MX เดียวกัน แม้ว่าชื่อโดเมนที่ปรากฏจะแตกต่างกันก็ตาม <strong>ระวังอย่าปิดกั้นผู้ให้บริการอีเมลรายใหญ่</strong>
resolved_through_html: แปลงที่อยู่ผ่าน %{domain}
title: โดเมนอีเมลที่ปิดกั้นอยู่
export_domain_allows:
new:
title: นำเข้าการอนุญาตโดเมน
@ -569,6 +588,7 @@ th:
resolve_description_html: จะไม่ใช้การกระทำต่อบัญชีที่รายงาน ไม่มีการบันทึกการดำเนินการ และจะปิดรายงาน
silence_description_html: บัญชีจะปรากฏแก่เฉพาะผู้ที่ติดตามโปรไฟล์อยู่แล้วหรือค้นหาโปรไฟล์ด้วยตนเองเท่านั้น จำกัดการเข้าถึงของโปรไฟล์อย่างมาก สามารถแปลงกลับได้เสมอ ปิดรายงานต่อบัญชีนี้ทั้งหมด
suspend_description_html: บัญชีและเนื้อหาของบัญชีทั้งหมดจะเข้าถึงไม่ได้และได้รับการลบในที่สุด และการโต้ตอบกับบัญชีจะเป็นไปไม่ได้ แปลงกลับได้ภายใน 30 วัน ปิดรายงานต่อบัญชีนี้ทั้งหมด
actions_description_html: ตัดสินใจว่าการกระทำใดที่จะใช้เพื่อแก้ปัญหารายงานนี้ หากคุณใช้การกระทำที่เป็นการลงโทษต่อบัญชีที่รายงาน จะส่งการแจ้งเตือนอีเมลถึงเขา ยกเว้นเมื่อมีการเลือกหมวดหมู่ <strong>สแปม</strong>
actions_description_remote_html: ตัดสินใจว่าการกระทำใดที่จะใช้เพื่อแก้ปัญหารายงานนี้ นี่จะมีผลต่อวิธีที่เซิร์ฟเวอร์ <strong>ของคุณ</strong> สื่อสารกับบัญชีระยะไกลนี้และจัดการเนื้อหาของบัญชีเท่านั้น
add_to_report: เพิ่มข้อมูลเพิ่มเติมไปยังรายงาน
already_suspended_badges:
@ -633,6 +653,7 @@ th:
delete_data_html: ลบโปรไฟล์และเนื้อหาของ <strong>@%{acct}</strong> ในอีก 30 วันนับจากนี้เว้นแต่มีการเลิกระงับเขาในระหว่างนี้
preview_preamble_html: "<strong>@%{acct}</strong> จะได้รับคำเตือนโดยมีเนื้อหาดังต่อไปนี้:"
record_strike_html: บันทึกการดำเนินการต่อ <strong>@%{acct}</strong> เพื่อช่วยให้คุณเลื่อนระดับการละเมิดในอนาคตจากบัญชีนี้
send_email_html: ส่งอีเมลคำเตือนถึง <strong>@%{acct}</strong>
warning_placeholder: การให้เหตุผลเพิ่มเติมที่ไม่จำเป็นสำหรับการกระทำการกลั่นกรอง
target_origin: จุดเริ่มต้นของบัญชีที่ได้รับการรายงาน
title: รายงาน
@ -670,6 +691,7 @@ th:
manage_appeals: จัดการการอุทธรณ์
manage_appeals_description: อนุญาตให้ผู้ใช้ตรวจทานการอุทธรณ์ต่อการกระทำการกลั่นกรอง
manage_blocks: จัดการการปิดกั้น
manage_blocks_description: อนุญาตให้ผู้ใช้ปิดกั้นผู้ให้บริการอีเมลและที่อยู่ IP
manage_custom_emojis: จัดการอีโมจิที่กำหนดเอง
manage_custom_emojis_description: อนุญาตให้ผู้ใช้จัดการอีโมจิที่กำหนดเองในเซิร์ฟเวอร์
manage_federation: จัดการการติดต่อกับภายนอก
@ -687,6 +709,7 @@ th:
manage_taxonomies: จัดการอนุกรมวิธาน
manage_taxonomies_description: อนุญาตให้ผู้ใช้ตรวจทานเนื้อหาที่กำลังนิยมและอัปเดตการตั้งค่าแฮชแท็ก
manage_user_access: จัดการการเข้าถึงของผู้ใช้
manage_user_access_description: อนุญาตให้ผู้ใช้ปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยของผู้ใช้อื่น ๆ เปลี่ยนที่อยู่อีเมลของเขา และตั้งรหัสผ่านของเขาใหม่
manage_users: จัดการผู้ใช้
manage_users_description: อนุญาตให้ผู้ใช้ดูรายละเอียดของผู้ใช้อื่น ๆ และทำการกระทำการกลั่นกรองต่อผู้ใช้เหล่านั้น
manage_webhooks: จัดการเว็บฮุค
@ -761,6 +784,7 @@ th:
destroyed_msg: ลบการอัปโหลดไซต์สำเร็จ!
software_updates:
critical_update: สำคัญ — โปรดอัปเดตอย่างรวดเร็ว
description: ขอแนะนำให้ทำให้การติดตั้ง Mastodon ของคุณทันสมัยอยู่เสมอเพื่อรับประโยชน์จากการแก้ไขและคุณลักษณะล่าสุด ยิ่งไปกว่านั้น บางครั้งก็เป็นสิ่งสำคัญที่จะอัปเดต Mastodon อย่างทันท่วงทีเพื่อหลีกเลี่ยงปัญหาความปลอดภัย ด้วยเหตุผลเหล่านี้ Mastodon จึงตรวจสอบการอัปเดตทุก 30 นาที และจะแจ้งเตือนคุณตามการกำหนดลักษณะการแจ้งเตือนอีเมลของคุณ
documentation_link: เรียนรู้เพิ่มเติม
release_notes: บันทึกประจำรุ่น
title: การอัปเดตที่พร้อมใช้งาน
@ -867,10 +891,16 @@ th:
trends:
allow: อนุญาต
approved: อนุมัติแล้ว
confirm_allow: คุณแน่ใจหรือไม่ว่าต้องการอนุญาตแท็กที่เลือก?
confirm_disallow: คุณแน่ใจหรือไม่ว่าต้องการไม่อนุญาตแท็กที่เลือก?
disallow: ไม่อนุญาต
links:
allow: อนุญาตลิงก์
allow_provider: อนุญาตผู้เผยแพร่
confirm_allow: คุณแน่ใจหรือไม่ว่าต้องการอนุญาตลิงก์ที่เลือก?
confirm_allow_provider: คุณแน่ใจหรือไม่ว่าต้องการอนุญาตผู้ให้บริการที่เลือก?
confirm_disallow: คุณแน่ใจหรือไม่ว่าต้องการไม่อนุญาตลิงก์ที่เลือก?
confirm_disallow_provider: คุณแน่ใจหรือไม่ว่าต้องการไม่อนุญาตผู้ให้บริการที่เลือก?
description_html: นี่คือลิงก์ที่กำลังได้รับการแบ่งปันเป็นจำนวนมากโดยบัญชีที่เซิร์ฟเวอร์ของคุณเห็นโพสต์จากในปัจจุบัน ลิงก์สามารถช่วยให้ผู้ใช้ของคุณค้นหาสิ่งที่กำลังเกิดขึ้นในโลก จะไม่แสดงลิงก์เป็นสาธารณะจนกว่าคุณจะอนุมัติผู้เผยแพร่ คุณยังสามารถอนุญาตหรือปฏิเสธลิงก์แต่ละรายการ
disallow: ไม่อนุญาตลิงก์
disallow_provider: ไม่อนุญาตผู้เผยแพร่
@ -893,6 +923,10 @@ th:
statuses:
allow: อนุญาตโพสต์
allow_account: อนุญาตผู้สร้าง
confirm_allow: คุณแน่ใจหรือไม่ว่าต้องการอนุญาตสถานะที่เลือก?
confirm_allow_account: คุณแน่ใจหรือไม่ว่าต้องการอนุญาตบัญชีที่เลือก?
confirm_disallow: คุณแน่ใจหรือไม่ว่าต้องการไม่อนุญาตสถานะที่เลือก?
confirm_disallow_account: คุณแน่ใจหรือไม่ว่าต้องการไม่อนุญาตบัญชีที่เลือก?
description_html: นี่คือโพสต์ที่เซิร์ฟเวอร์ของคุณทราบเกี่ยวกับที่กำลังได้รับการแบ่งปันและชื่นชอบเป็นจำนวนมากในปัจจุบันในขณะนี้ โพสต์สามารถช่วยให้ผู้ใช้ใหม่และที่กลับมาของคุณค้นหาผู้คนเพิ่มเติมที่จะติดตาม จะไม่แสดงโพสต์เป็นสาธารณะจนกว่าคุณจะอนุมัติผู้สร้าง และผู้สร้างอนุญาตให้เสนอแนะบัญชีของเขาแก่ผู้อื่น คุณยังสามารถอนุญาตหรือปฏิเสธโพสต์แต่ละรายการ
disallow: ไม่อนุญาตโพสต์
disallow_account: ไม่อนุญาตผู้สร้าง

View file

@ -460,7 +460,9 @@ uk:
title: Заблокувати новий домен е-пошти
no_email_domain_block_selected: Налаштування блокування доменів електронної пошти не змінено, оскільки жоден домен вибрано
not_permitted: Не дозволено
resolved_dns_records_hint_html: Доменне ім'я розпізнається на наступних MX-доменах, які в результаті відповідають за приймання електронної пошти. Блокування MX-домену заблокує реєстрацію з будь-якої адреси електронної пошти, яка використовує той самий MX-домен, навіть якщо видиме ім'я домену відрізняється. <strong>Будьте обережні, щоб не заблокувати основних постачальників послуг електронної пошти.</strong>
resolved_through_html: Розв'язано через %{domain}
title: Заблоковані домени електронної пошти
export_domain_allows:
new:
title: Імпорт дозволів домену
@ -622,6 +624,7 @@ uk:
resolve_description_html: Не буде застосовано жодних дій проти облікового запису, на який скаржилися, не буде записано попередження, а скаргу буде закрито.
silence_description_html: Обліковий запис буде видно лише тим, хто вже за ним слідкує, або знайде його вручну, що значно обмежує його охоплення. Може завжди бути повернуто. Закриває всі скарги на цей обліковий запис.
suspend_description_html: Обліковий запис і весь його вміст будуть недоступними й врешті-решт видалені, і взаємодіяти з ним буде неможливо. Відновлення можливе протягом 30 днів. Закриває всі скарги на цей обліковий запис.
actions_description_html: Визначте, які дії слід вжити для розв'язання цієї скарги. Якщо ви оберете каральні дії проти зареєстрованого облікового запису, про них буде надіслано сповіщення електронним листом, крім випадків, коли вибрано категорію <strong>Спам</strong>.
actions_description_remote_html: Визначте, які дії слід вжити для розв'язання цього звіту. Це вплине тільки на те, як <strong>ваш</strong> сервер з'єднується з цим віддаленим обліковим записом і обробляє його вміст.
add_to_report: Додати ще подробиць до скарги
already_suspended_badges:
@ -686,6 +689,7 @@ uk:
delete_data_html: Видаліть профіль <strong>@%{acct}</strong> і вміст за останні 30 днів, якщо вони не дія не скасується тим часом
preview_preamble_html: "<strong>@%{acct}</strong> отримає попередження з таким вмістом:"
record_strike_html: Запис попередження проти <strong>@%{acct}</strong>, що допоможе вам посилити ваші майбутні санкції проти цього облікового запису
send_email_html: Надіслати <strong>"%{acct}</strong> попереджувального електронного листа
warning_placeholder: Додаткові причини дії модерації.
target_origin: Походження облікового запису, на який скаржаться
title: Скарги
@ -729,6 +733,7 @@ uk:
manage_appeals: Керувати оскарженнями
manage_appeals_description: Дозволяє користувачам розглядати оскарження дій модерації
manage_blocks: Керувати блокуваннями
manage_blocks_description: Дозволяє користувачам блокувати постачальників е-пошти та IP-адреси
manage_custom_emojis: Керувати користувацькими емоджі
manage_custom_emojis_description: Дозволяє користувачам керувати користувацькими емоджі на сервері
manage_federation: Керувати федерацією
@ -746,6 +751,7 @@ uk:
manage_taxonomies: Керувати таксономіями
manage_taxonomies_description: Дозволяє користувачам переглядати актуальні налаштування вмісту й оновити хештеґ
manage_user_access: Керувати доступом користувачів
manage_user_access_description: Дозволяє користувачам вимкнути двоетапну перевірку інших користувачів, змінити їхню адресу електронної пошти та відновити пароль
manage_users: Керувати користувачами
manage_users_description: Дозволяє користувачам переглядати подробиці інших користувачів і виконувати їхню модерацію
manage_webhooks: Керувати Webhooks
@ -820,6 +826,7 @@ uk:
destroyed_msg: Завантаження сайту успішно видалено!
software_updates:
critical_update: Критично — оновіться якнайшвидше
description: Радимо постійно оновлювати інсталяцію Mastodon, щоб мати змогу користуватися найновішими виправленнями та функціями. На додаток, іноді дуже важливо вчасно оновлювати Mastodon, щоб уникнути проблем з безпекою. З цих причин Mastodon перевіряє наявність оновлень що 30 хвилин і сповіщає вас про це відповідно до ваших налаштувань сповіщень на електронну пошту.
documentation_link: Докладніше
release_notes: Примітки до випуску
title: Доступні оновлення
@ -906,16 +913,38 @@ uk:
action: Перегляньте подробиці тут
message_html: "<strong>Ваше сховище об'єктів неправильно налаштоване. Приватність ваших користувачів піддається ризику</strong>"
tags:
moderation:
not_trendable: Не трендові
not_usable: Невикористовувані
pending_review: Очікує розгляду
review_requested: Запит на розгляд
reviewed: Розглянуто
title: Статус
trendable: У тренді
unreviewed: Не розглянуто
usable: Можна використати
name: Назва
newest: Найновіші
oldest: Найдавніші
reset: Скинути
review: Переглянути допис
search: Пошук
title: Хештеги
updated_msg: Параметри хештеґів успішно оновлені
title: Адміністрування
trends:
allow: Дозволити
approved: Схвалено
confirm_allow: Ви впевнені, що хочете дозволити вибрані теги?
confirm_disallow: Ви впевнені, що хочете скасувати дозвіл для вибраних тегів?
disallow: Заборонити
links:
allow: Дозволити посилання
allow_provider: Дозволити публікатора
confirm_allow: Ви впевнені, що хочете дозволити вибрані посилання?
confirm_allow_provider: Ви впевнені, що хочете дозволити вибраних постачальників?
confirm_disallow: Ви впевнені, що хочете скасувати дозвіл вибраним посиланням?
confirm_disallow_provider: Ви впевнені, що хочете скасувати дозвіл вибраним постачальникам?
description_html: Це посилання, з яких наразі багаторазово поширюються записи, з яких ваш сервер бачить дописи. Це може допомогти вашим користувачам дізнатися, що відбувається у світі. Посилання не показується публічно, поки ви не затверджуєте його публікацію. Ви також можете дозволити або відхилити окремі посилання.
disallow: Заборонити посилання
disallow_provider: Заборонити публікатора
@ -941,6 +970,10 @@ uk:
statuses:
allow: Дозволити оприлюднення
allow_account: Дозволити автора
confirm_allow: Ви впевнені, що хочете дозволити вибрані статуси?
confirm_allow_account: Впевнені, що хочете дозволити вибрані облікові записи?
confirm_disallow: Ви впевнені, що хочете скасувати дозвіл на вибрані статуси?
confirm_disallow_account: Впевнені, що хочете скасувати дозвіл вибраним обліковим записам?
description_html: Це дописи, про які ваш сервер знає як такі, що в даний час є спільні і навіть ті, які зараз є дуже популярними. Це може допомогти вашим новим та старим користувачам, щоб знайти більше людей для слідування. Жоден запис не відображається публічно, поки ви не затверджуєте автора, і автор дозволяє іншим користувачам підписатися на це. Ви також можете дозволити або відхилити окремі повідомлення.
disallow: Заборонити допис
disallow_account: Заборонити автора
@ -1064,7 +1097,9 @@ uk:
guide_link_text: Кожен може взяти участь.
sensitive_content: Дражливий зміст
application_mailer:
notification_preferences: Змінити налаштування електронної пошти
salutation: "%{name},"
settings: 'Змінити налаштування електронної пошти: %{link}'
unsubscribe: Відписатися
view: 'Перегляд:'
view_profile: Показати профіль
@ -1084,6 +1119,7 @@ uk:
hint_html: Ще одне! Ми повинні пересвідчитись, що ви людина (щоб ми могли уникнути спаму!). Розв'яжіть CAPTCHA внизу і натисніть кнопку "Продовжити".
title: Перевірка безпеки
confirmations:
awaiting_review: Ваша електронна адреса підтверджена! Наразі співробітники %{domain} розглядають вашу реєстрацію. Ви отримаєте електронний лист, якщо вони затвердять ваш обліковий запис!
awaiting_review_title: Ваша реєстрація розглядається
clicking_this_link: натисніть це посилання
login_link: увійти
@ -1091,6 +1127,7 @@ uk:
redirect_to_app_html: Вас мало переспрямувати до програми <strong>%{app_name}</strong>. Якщо цього не сталося, спробуйте %{clicking_this_link} або вручну поверніться до програми.
registration_complete: Ваша реєстрація на %{domain} завершена!
welcome_title: Ласкаво просимо, %{name}!
wrong_email_hint: Якщо ця адреса електронної пошти неправильна, можна змінити її в налаштуваннях облікового запису.
delete_account: Видалити обліковий запис
delete_account_html: Якщо ви хочете видалити свій обліковий запис, ви можете <a href="%{path}">перейти сюди</a>. Вас попросять підтвердити дію.
description:
@ -1111,6 +1148,7 @@ uk:
or_log_in_with: Або увійдіть з
privacy_policy_agreement_html: Мною прочитано і я погоджуюся з <a href="%{privacy_policy_path}" target="_blank">політикою приватності</a>
progress:
confirm: Підтвердити електронну адресу
details: Ваші дані
review: Наш відгук
rules: Погодитися з правилами
@ -1132,8 +1170,10 @@ uk:
security: Зміна паролю
set_new_password: Встановити новий пароль
setup:
email_below_hint_html: Перевірте теку "Спам", або зробіть ще один запит. Ви можете виправити свою електронну адресу, якщо вона неправильна.
email_settings_hint_html: Натисніть на посилання, яке ми надіслали вам, щоб підтвердити %{email}. Ми чекатимемо прямо тут.
link_not_received: Не отримали посилання?
new_confirmation_instructions_sent: Ви отримаєте новий лист із посиланням для підтвердження протягом кількох хвилин!
title: Перевірте вашу поштову скриньку
sign_in:
preamble_html: Увійдіть за допомогою облікових даних <strong>%{domain}</strong>. Якщо ваш обліковий запис розміщений на іншому сервері, ви не зможете увійти тут.
@ -1144,7 +1184,9 @@ uk:
title: Налаштуймо вас на %{domain}.
status:
account_status: Стан облікового запису
confirming: Очікуємо завершення підтвердження за допомогою електронної пошти.
functional: Ваш обліковий запис повністю робочий.
pending: Ваша заява очікує розгляду нашим персоналом. Це може тривати деякий час. Ви отримаєте електронний лист, якщо ваша заява буде схвалена.
redirecting_to: Ваш обліковий запис наразі неактивний, тому що він перенаправлений до %{acct}.
self_destruct: Оскільки %{domain} закривається, ви отримаєте тільки обмежений доступ до вашого облікового запису.
view_strikes: Переглянути попередні попередження вашому обліковому запису
@ -1187,6 +1229,9 @@ uk:
before: 'До того як продовжити, будь ласка уважно прочитайте це:'
caches: Інформація, кешована іншими серверами, може залишитися
data_removal: Ваші дописи й інші дані будуть вилучені назавжди
email_change_html: Ви можете <a href="%{path}">змінити вашу електронну адресу</a>, не видаляючи ваш обліковий запис
email_contact_html: Якщо його все ще немає, ви можете написати до <a href="mailto:%{email}">%{email}</a> для допомоги
email_reconfirmation_html: Якщо ви не отримали електронного листа з підтвердженням, ви можете <a href="%{path}">попросити його знову</a>
irreversible: Буде неможливо відновити ваш обліковий запис
more_details_html: Подробиці за посиланням <a href="%{terms_path}">політика конфіденційності</a>.
username_available: Ваше ім'я користувача стане доступним для використання
@ -1446,6 +1491,7 @@ uk:
unsubscribe:
action: Так, відписатися
complete: Відписалися
confirmation_html: Ви впевнені, що хочете відписатися від отримання %{type} для Mastodon на %{domain} до своєї скриньки %{email}? Ви можете повторно підписатися у <a href="%{settings_path}">налаштуваннях сповіщень електронною поштою</a>.
emails:
notification_emails:
favourite: отримувати сповіщення про вподобання електронною поштою

View file

@ -159,6 +159,7 @@ namespace :api, format: false do
collection do
post :accept, to: 'requests#accept_bulk'
post :dismiss, to: 'requests#dismiss_bulk'
get :merged, to: 'requests#merged?'
end
member do

View file

@ -23,7 +23,7 @@
"lint:css": "stylelint \"**/*.{css,scss}\"",
"lint": "yarn lint:js && yarn lint:css",
"postversion": "git push --tags",
"prepare": "husky",
"postinstall": "test -d node_modules/husky && husky || echo \"husky is not installed\"",
"start": "node ./streaming/index.js",
"test": "yarn lint && yarn run typecheck && yarn jest",
"typecheck": "tsc --noEmit"

View file

@ -15,6 +15,7 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do
let!(:john) { Fabricate(:account, discoverable: true, hide_collections: false) }
let!(:jerk) { Fabricate(:account, discoverable: true, hide_collections: false) }
let!(:larry) { Fabricate(:account, discoverable: true, hide_collections: false) }
let!(:morty) { Fabricate(:account, discoverable: true, hide_collections: false, memorial: true) }
context 'with follows and blocks' do
before do
@ -27,8 +28,8 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do
# alice follows eve and mallory
[john, mallory].each { |account| alice.follow!(account) }
# eugen follows eve, john, jerk, larry and neil
[eve, mallory, jerk, larry, neil].each { |account| eugen.follow!(account) }
# eugen follows eve, john, jerk, larry, neil and morty
[eve, mallory, jerk, larry, neil, morty].each { |account| eugen.follow!(account) }
end
it 'returns eligible accounts', :aggregate_failures do
@ -51,6 +52,9 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do
# the suggestion for neil has already been rejected
expect(results).to_not include([neil.id, :friends_of_friends])
# morty is not included because his account is in memoriam
expect(results).to_not include([morty.id, :friends_of_friends])
end
end

View file

@ -21,6 +21,7 @@ RSpec.describe AccountSuggestions::Source do
let!(:moved_account) { Fabricate(:account, moved_to_account: Fabricate(:account), discoverable: true) }
let!(:silenced_account) { Fabricate(:account, silenced: true, discoverable: true) }
let!(:undiscoverable_account) { Fabricate(:account, discoverable: false) }
let!(:memorial_account) { Fabricate(:account, memorial: true, discoverable: true) }
before do
Fabricate :account_domain_block, account: account, domain: account_domain_blocked_account.domain
@ -44,6 +45,7 @@ RSpec.describe AccountSuggestions::Source do
.and not_include(moved_account)
.and not_include(silenced_account)
.and not_include(undiscoverable_account)
.and not_include(memorial_account)
end
end
end

View file

@ -120,4 +120,34 @@ RSpec.describe 'Requests' do
expect(response).to have_http_status(200)
end
end
describe 'GET /api/v1/notifications/requests/merged' do
subject do
get '/api/v1/notifications/requests/merged', headers: headers
end
it_behaves_like 'forbidden for wrong scope', 'write write:notifications'
context 'when the user has no accepted request pending merge' do
it 'returns http success and returns merged: true' do
subject
expect(response).to have_http_status(200)
expect(body_as_json).to eq({ merged: true })
end
end
context 'when the user has an accepted request pending merge' do
before do
redis.set("notification_unfilter_jobs:#{user.account_id}", 1)
end
it 'returns http success and returns merged: false' do
subject
expect(response).to have_http_status(200)
expect(body_as_json).to eq({ merged: false })
end
end
end
end

View file

@ -185,7 +185,7 @@ RSpec.describe 'Notifications' do
it 'returns the requested number of notifications paginated', :aggregate_failures do
subject
notifications = user.account.notifications.browserable
notifications = user.account.notifications.browserable.order(id: :asc)
expect(body_as_json.size)
.to eq(params[:limit])

View file

@ -8,10 +8,11 @@ RSpec.describe AcceptNotificationRequestService do
let(:notification_request) { Fabricate(:notification_request) }
describe '#call' do
it 'destroys the notification request, creates a permission, and queues a worker' do
it 'destroys the notification request, creates a permission, increases the jobs count and queues a worker' do
expect { subject.call(notification_request) }
.to change { NotificationRequest.exists?(notification_request.id) }.to(false)
.and change { NotificationPermission.exists?(account_id: notification_request.account_id, from_account_id: notification_request.from_account_id) }.to(true)
.and change { redis.get("notification_unfilter_jobs:#{notification_request.account_id}").to_i }.by(1)
expect(UnfilterNotificationsWorker).to have_enqueued_sidekiq_job(notification_request.account_id, notification_request.from_account_id)
end

View file

@ -13,13 +13,56 @@ describe UnfilterNotificationsWorker do
Fabricate(:notification, filtered: true, from_account: sender, account: recipient, type: :mention, activity: mention)
follow_request = sender.request_follow!(recipient)
Fabricate(:notification, filtered: true, from_account: sender, account: recipient, type: :follow_request, activity: follow_request)
allow(redis).to receive(:publish)
allow(redis).to receive(:exists?).and_return(false)
end
shared_examples 'shared behavior' do
it 'unfilters notifications and adds private messages to conversations' do
expect { subject }
.to change { recipient.notifications.where(from_account_id: sender.id).pluck(:filtered) }.from([true, true]).to([false, false])
.and change { recipient.conversations.exists?(last_status_id: sender.statuses.first.id) }.to(true)
context 'when this is the last pending merge job and the user is subscribed to streaming' do
before do
redis.set("notification_unfilter_jobs:#{recipient.id}", 1)
allow(redis).to receive(:exists?).with("subscribed:timeline:#{recipient.id}").and_return(true)
end
it 'unfilters notifications, adds private messages to conversations, and pushes to redis' do
expect { subject }
.to change { recipient.notifications.where(from_account_id: sender.id).pluck(:filtered) }.from([true, true]).to([false, false])
.and change { recipient.conversations.exists?(last_status_id: sender.statuses.first.id) }.to(true)
.and change { redis.get("notification_unfilter_jobs:#{recipient.id}").to_i }.by(-1)
expect(redis).to have_received(:publish).with("timeline:#{recipient.id}:notifications", '{"event":"notifications_merged","payload":"1"}')
end
end
context 'when this is not last pending merge job and the user is subscribed to streaming' do
before do
redis.set("notification_unfilter_jobs:#{recipient.id}", 2)
allow(redis).to receive(:exists?).with("subscribed:timeline:#{recipient.id}").and_return(true)
end
it 'unfilters notifications, adds private messages to conversations, and does not push to redis' do
expect { subject }
.to change { recipient.notifications.where(from_account_id: sender.id).pluck(:filtered) }.from([true, true]).to([false, false])
.and change { recipient.conversations.exists?(last_status_id: sender.statuses.first.id) }.to(true)
.and change { redis.get("notification_unfilter_jobs:#{recipient.id}").to_i }.by(-1)
expect(redis).to_not have_received(:publish).with("timeline:#{recipient.id}:notifications", '{"event":"notifications_merged","payload":"1"}')
end
end
context 'when this is the last pending merge job and the user is not subscribed to streaming' do
before do
redis.set("notification_unfilter_jobs:#{recipient.id}", 1)
end
it 'unfilters notifications, adds private messages to conversations, and does not push to redis' do
expect { subject }
.to change { recipient.notifications.where(from_account_id: sender.id).pluck(:filtered) }.from([true, true]).to([false, false])
.and change { recipient.conversations.exists?(last_status_id: sender.statuses.first.id) }.to(true)
.and change { redis.get("notification_unfilter_jobs:#{recipient.id}").to_i }.by(-1)
expect(redis).to_not have_received(:publish).with("timeline:#{recipient.id}:notifications", '{"event":"notifications_merged","payload":"1"}')
end
end
end

619
yarn.lock

File diff suppressed because it is too large Load diff