+
+
{{ i18n.ts._announcement.tooManyActiveAnnouncementDescription }}
+
+
+ {{ announcement.title }}
+
+
+
+
+
+
+ {{ announcement.text }}
+
+
{{ i18n.ts.title }}
@@ -14,13 +30,36 @@
{{ i18n.ts.imageUrl }}
+
+ {{ i18n.ts.icon }}
+
+
+
+
+
+
+ {{ i18n.ts.display }}
+
+
+
+
+
+ {{ i18n.ts._announcement.forExistingUsers }}
+
+
+ {{ i18n.ts._announcement.needConfirmationToRead }}
+
{{ i18n.t('nUsersRead', { n: announcement.reads }) }}
{{ i18n.ts.save }}
- {{ i18n.ts.remove }}
+ {{ i18n.ts._announcement.end }} ({{ i18n.ts.archive }})
+ {{ i18n.ts.delete }}
-
+
+
+ {{ i18n.ts.more }}
+
@@ -32,9 +71,13 @@ import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
import MkTextarea from '@/components/MkTextarea.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import MkSwitch from '@/components/MkSwitch.vue';
+import MkRadios from '@/components/MkRadios.vue';
+import MkInfo from '@/components/MkInfo.vue';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import MkFolder from '@/components/MkFolder.vue';
let announcements: any[] = $ref([]);
@@ -44,17 +87,22 @@ os.api('admin/announcements/list').then(announcementResponse => {
function add() {
announcements.unshift({
+ _id: Math.random().toString(36),
id: null,
- title: '',
+ title: 'New announcement',
text: '',
imageUrl: null,
+ icon: 'info',
+ display: 'normal',
+ forExistingUsers: false,
+ needConfirmationToRead: false,
});
}
-function remove(announcement) {
+function del(announcement) {
os.confirm({
type: 'warning',
- text: i18n.t('removeAreYouSure', { x: announcement.title }),
+ text: i18n.t('deleteAreYouSure', { x: announcement.title }),
}).then(({ canceled }) => {
if (canceled) return;
announcements = announcements.filter(x => x !== announcement);
@@ -62,35 +110,29 @@ function remove(announcement) {
});
}
-function save(announcement) {
+async function archive(announcement) {
+ await os.apiWithDialog('admin/announcements/update', {
+ ...announcement,
+ isActive: false,
+ });
+ refresh();
+}
+
+async function save(announcement) {
if (announcement.id == null) {
- os.api('admin/announcements/create', announcement).then(() => {
- os.alert({
- type: 'success',
- text: i18n.ts.saved,
- });
- refresh();
- }).catch(err => {
- os.alert({
- type: 'error',
- text: err,
- });
- });
+ await os.apiWithDialog('admin/announcements/create', announcement);
+ refresh();
} else {
- os.api('admin/announcements/update', announcement).then(() => {
- os.alert({
- type: 'success',
- text: i18n.ts.saved,
- });
- }).catch(err => {
- os.alert({
- type: 'error',
- text: err,
- });
- });
+ os.apiWithDialog('admin/announcements/update', announcement);
}
}
+function more() {
+ os.api('admin/announcements/list', { untilId: announcements.reduce((acc, announcement) => announcement.id != null ? announcement : acc).id }).then(announcementResponse => {
+ announcements = announcements.concat(announcementResponse);
+ });
+}
+
function refresh() {
os.api('admin/announcements/list').then(announcementResponse => {
announcements = announcementResponse;
diff --git a/packages/frontend/src/pages/admin/bot-protection.vue b/packages/frontend/src/pages/admin/bot-protection.vue
index 83a322a242..4d441a7770 100644
--- a/packages/frontend/src/pages/admin/bot-protection.vue
+++ b/packages/frontend/src/pages/admin/bot-protection.vue
@@ -1,3 +1,8 @@
+
+
@@ -65,9 +70,9 @@ import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue';
import FormSuspense from '@/components/form/suspense.vue';
import FormSlot from '@/components/form/slot.vue';
-import * as os from '@/os';
-import { fetchInstance } from '@/instance';
-import { i18n } from '@/i18n';
+import * as os from '@/os.js';
+import { fetchInstance } from '@/instance.js';
+import { i18n } from '@/i18n.js';
const MkCaptcha = defineAsyncComponent(() => import('@/components/MkCaptcha.vue'));
diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue
index 65ce9e0068..0733959319 100644
--- a/packages/frontend/src/pages/admin/branding.vue
+++ b/packages/frontend/src/pages/admin/branding.vue
@@ -1,3 +1,8 @@
+
+
@@ -7,7 +12,29 @@
- {{ i18n.ts.iconUrl }}
+ {{ i18n.ts._serverSettings.iconUrl }}
+
+
+
+
+ {{ i18n.ts._serverSettings.iconUrl }} (App/192px)
+
+ {{ i18n.t('_serverSettings.appIconDescription', { host: instance.name ?? host }) }}
+ ({{ i18n.ts._serverSettings.appIconUsageExample }})
+ {{ i18n.ts._serverSettings.appIconStyleRecommendation }}
+ {{ i18n.t('_serverSettings.appIconResolutionMustBe', { resolution: '192x192px' }) }}
+
+
+
+
+
+ {{ i18n.ts._serverSettings.iconUrl }} (App/512px)
+
+ {{ i18n.t('_serverSettings.appIconDescription', { host: instance.name ?? host }) }}
+ ({{ i18n.ts._serverSettings.appIconUsageExample }})
+ {{ i18n.ts._serverSettings.appIconStyleRecommendation }}
+ {{ i18n.t('_serverSettings.appIconResolutionMustBe', { resolution: '512x512px' }) }}
+
@@ -48,6 +75,10 @@
{{ i18n.ts.instanceDefaultDarkTheme }}
{{ i18n.ts.instanceDefaultThemeDescription }}
+
+
+ {{ i18n.ts._serverSettings.manifestJsonOverride }}
+
@@ -64,6 +95,7 @@
+
+
diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue
index e36c9ac91d..5faf70d9c9 100644
--- a/packages/frontend/src/pages/admin/moderation.vue
+++ b/packages/frontend/src/pages/admin/moderation.vue
@@ -1,3 +1,8 @@
+
+
@@ -24,7 +29,7 @@
{{ i18n.ts.preservedUsernames }}
{{ i18n.ts.preservedUsernamesDescription }}
-
+
{{ i18n.ts.sensitiveWords }}
{{ i18n.ts.sensitiveWordsDescription }}
{{ i18n.ts.sensitiveWordsDescription2 }}
@@ -52,10 +57,10 @@ import MkTextarea from '@/components/MkTextarea.vue';
import FormSection from '@/components/form/section.vue';
import FormSplit from '@/components/form/split.vue';
import FormSuspense from '@/components/form/suspense.vue';
-import * as os from '@/os';
-import { fetchInstance } from '@/instance';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import * as os from '@/os.js';
+import { fetchInstance } from '@/instance.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
import FormLink from '@/components/form/link.vue';
diff --git a/packages/frontend/src/pages/admin/modlog.ModLog.vue b/packages/frontend/src/pages/admin/modlog.ModLog.vue
new file mode 100644
index 0000000000..a77bf21b90
--- /dev/null
+++ b/packages/frontend/src/pages/admin/modlog.ModLog.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
+ {{ i18n.ts._moderationLogTypes[log.type] }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : {{ log.info.role.name }}
+ : {{ log.info.before.name }}
+ : {{ log.info.role.name }}
+ : {{ log.info.before.name }}
+ : @{{ log.info.fileUserUsername }}{{ log.info.fileUserHost ? '@' + log.info.fileUserHost : '' }}
+ : @{{ log.info.fileUserUsername }}{{ log.info.fileUserHost ? '@' + log.info.fileUserHost : '' }}
+ : {{ log.info.host }}
+ : {{ log.info.host }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+ : @{{ log.info.noteUserUsername }}{{ log.info.noteUserHost ? '@' + log.info.noteUserHost : '' }}
+ : @{{ log.info.fileUserUsername }}{{ log.info.fileUserHost ? '@' + log.info.fileUserHost : '' }}
+
+
+
+
+
+
+
+
+
+
+
{{ i18n.ts.moderator }}: @{{ log.user?.username }}
+
{{ i18n.ts.dateAndTime }}:
+
+
+
+
+
+
+
+
+ {{ i18n.ts.user }}: {{ log.info.userId }}
+
+
+
+
+
+ {{ i18n.ts.user }}: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+
+
+ {{ i18n.ts.user }}: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}
+
+
+
+
+
+
+
+ {{ i18n.ts.user }}: {{ log.info.userId }}
+ {{ i18n.ts.role }}: {{ log.info.roleName }} [{{ log.info.roleId }}]
+
+
+ {{ i18n.ts.user }}: {{ log.info.userId }}
+ {{ i18n.ts.role }}: {{ log.info.roleName }} [{{ log.info.roleId }}]
+
+
+ {{ i18n.ts.emoji }}: {{ log.info.emojiId }}
+
+
+
+
+
+
+ raw
+ {{ JSON5.stringify(log, null, '\t') }}
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/pages/admin/modlog.vue b/packages/frontend/src/pages/admin/modlog.vue
new file mode 100644
index 0000000000..e3e545fc1c
--- /dev/null
+++ b/packages/frontend/src/pages/admin/modlog.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+ {{ i18n.ts.type }}
+
+
+
+
+ {{ i18n.ts.moderator }}(ID)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/pages/admin/object-storage.vue b/packages/frontend/src/pages/admin/object-storage.vue
index e569aad1b8..ce9501697f 100644
--- a/packages/frontend/src/pages/admin/object-storage.vue
+++ b/packages/frontend/src/pages/admin/object-storage.vue
@@ -1,69 +1,147 @@
+
+
-
{{ i18n.ts.useObjectStorage }}
-
-
-
- {{ i18n.ts.objectStorageBaseUrl }}
- {{ i18n.ts.objectStorageBaseUrlDesc }}
-
-
-
- {{ i18n.ts.objectStorageBucket }}
- {{ i18n.ts.objectStorageBucketDesc }}
-
-
-
- {{ i18n.ts.objectStoragePrefix }}
- {{ i18n.ts.objectStoragePrefixDesc }}
-
-
-
- {{ i18n.ts.objectStorageEndpoint }}
- https://
- {{ i18n.ts.objectStorageEndpointDesc }}
-
-
-
- {{ i18n.ts.objectStorageRegion }}
- {{ i18n.ts.objectStorageRegionDesc }}
-
-
-
-
-
- Access key
-
-
-
-
- Secret key
-
-
-
-
- {{ i18n.ts.objectStorageUseSSL }}
- {{ i18n.ts.objectStorageUseSSLDesc }}
-
-
-
- {{ i18n.ts.objectStorageUseProxy }}
- {{ i18n.ts.objectStorageUseProxyDesc }}
-
-
-
- {{ i18n.ts.objectStorageSetPublicRead }}
-
-
-
- s3ForcePathStyle
- {{ i18n.ts.s3ForcePathStyleDesc }}
-
-
+
+ {{ i18n.ts.objectStorage }}
+
+
+ {{ i18n.ts.useObjectStorage }}
+
+
+
+ {{ i18n.ts.objectStorageBaseUrl }}
+ {{ i18n.ts.objectStorageBaseUrlDesc }}
+
+
+
+ {{ i18n.ts.objectStorageBucket }}
+ {{ i18n.ts.objectStorageBucketDesc }}
+
+
+
+ {{ i18n.ts.objectStoragePrefix }}
+ {{ i18n.ts.objectStoragePrefixDesc }}
+
+
+
+ {{ i18n.ts.objectStorageEndpoint }}
+ https://
+ {{ i18n.ts.objectStorageEndpointDesc }}
+
+
+
+ {{ i18n.ts.objectStorageRegion }}
+ {{ i18n.ts.objectStorageRegionDesc }}
+
+
+
+
+
+ Access key
+
+
+
+
+ Secret key
+
+
+
+
+ {{ i18n.ts.objectStorageUseSSL }}
+ {{ i18n.ts.objectStorageUseSSLDesc }}
+
+
+
+ {{ i18n.ts.objectStorageUseProxy }}
+ {{ i18n.ts.objectStorageUseProxyDesc }}
+
+
+
+ {{ i18n.ts.objectStorageSetPublicRead }}
+
+
+
+ s3ForcePathStyle
+ {{ i18n.ts.s3ForcePathStyleDesc }}
+
+
+
+
+
+
+ {{ i18n.ts.objectStorage }} (Remote)
+
+
+ {{ i18n.ts.useObjectStorage }}
+
+
+
+ {{ i18n.ts.objectStorageBaseUrl }}
+ {{ i18n.ts.objectStorageBaseUrlDesc }}
+
+
+
+ {{ i18n.ts.objectStorageBucket }}
+ {{ i18n.ts.objectStorageBucketDesc }}
+
+
+
+ {{ i18n.ts.objectStoragePrefix }}
+ {{ i18n.ts.objectStoragePrefixDesc }}
+
+
+
+ {{ i18n.ts.objectStorageEndpoint }}
+ https://
+ {{ i18n.ts.objectStorageEndpointDesc }}
+
+
+
+ {{ i18n.ts.objectStorageRegion }}
+ {{ i18n.ts.objectStorageRegionDesc }}
+
+
+
+
+
+ Access key
+
+
+
+
+ Secret key
+
+
+
+
+ {{ i18n.ts.objectStorageUseSSL }}
+ {{ i18n.ts.objectStorageUseSSLDesc }}
+
+
+
+ {{ i18n.ts.objectStorageUseProxy }}
+ {{ i18n.ts.objectStorageUseProxyDesc }}
+
+
+
+ {{ i18n.ts.objectStorageSetPublicRead }}
+
+
+
+ s3ForcePathStyle
+ {{ i18n.ts.s3ForcePathStyleDesc }}
+
+
+
+
@@ -80,14 +158,15 @@
diff --git a/packages/frontend/src/pages/admin/overview.federation.vue b/packages/frontend/src/pages/admin/overview.federation.vue
index ab78c4c393..cf0d9fe799 100644
--- a/packages/frontend/src/pages/admin/overview.federation.vue
+++ b/packages/frontend/src/pages/admin/overview.federation.vue
@@ -1,3 +1,8 @@
+
+
@@ -43,11 +48,11 @@
-
diff --git a/packages/frontend/src/pages/antenna-timeline.vue b/packages/frontend/src/pages/antenna-timeline.vue
index a22714791f..d3d6f573d7 100644
--- a/packages/frontend/src/pages/antenna-timeline.vue
+++ b/packages/frontend/src/pages/antenna-timeline.vue
@@ -1,3 +1,8 @@
+
+
@@ -21,11 +26,11 @@
diff --git a/packages/frontend/src/pages/channels.vue b/packages/frontend/src/pages/channels.vue
index 0c4ccc1bcd..58071dce5b 100644
--- a/packages/frontend/src/pages/channels.vue
+++ b/packages/frontend/src/pages/channels.vue
@@ -1,10 +1,15 @@
+
+
-
+
@@ -53,9 +58,9 @@ import MkInput from '@/components/MkInput.vue';
import MkRadios from '@/components/MkRadios.vue';
import MkButton from '@/components/MkButton.vue';
import MkFoldableSection from '@/components/MkFoldableSection.vue';
-import { useRouter } from '@/router';
-import { definePageMetadata } from '@/scripts/page-metadata';
-import { i18n } from '@/i18n';
+import { useRouter } from '@/router.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { i18n } from '@/i18n.js';
const router = useRouter();
diff --git a/packages/frontend/src/pages/clicker.vue b/packages/frontend/src/pages/clicker.vue
index 69ecc9e772..2f8fef72ac 100644
--- a/packages/frontend/src/pages/clicker.vue
+++ b/packages/frontend/src/pages/clicker.vue
@@ -1,3 +1,8 @@
+
+
@@ -9,7 +14,7 @@
+
+
diff --git a/packages/frontend/src/pages/list.vue b/packages/frontend/src/pages/list.vue
index 40934fb71d..8bab8ebb22 100644
--- a/packages/frontend/src/pages/list.vue
+++ b/packages/frontend/src/pages/list.vue
@@ -1,3 +1,8 @@
+
+
@@ -30,13 +35,13 @@
diff --git a/packages/frontend/src/pages/messaging/messaging-room.form.vue b/packages/frontend/src/pages/messaging/messaging-room.form.vue
index cf034d85a5..d4f0a7447b 100644
--- a/packages/frontend/src/pages/messaging/messaging-room.form.vue
+++ b/packages/frontend/src/pages/messaging/messaging-room.form.vue
@@ -1,3 +1,8 @@
+
+
();
-let textEl = $shallowRef
();
-let fileEl = $shallowRef();
+const textEl = $shallowRef(null);
+const fileEl = $shallowRef(null);
let text = $ref('');
let file = $ref(null);
@@ -144,15 +148,7 @@ function onDrop(ev: DragEvent): void {
function onKeydown(ev: KeyboardEvent) {
typing();
- if (defaultStore.state.useEnterToSend && !ev.shiftKey) {
- if ((ev.key === 'Enter') && canSend) {
- send();
- }
- } else {
- if ((ev.key === 'Enter') && (ev.ctrlKey || ev.metaKey) && canSend) {
- send();
- }
- }
+ if ((ev.key === 'Enter') && !ev.shiftKey && canSend) send();
}
function onCompositionUpdate() {
@@ -228,8 +224,7 @@ onMounted(() => {
autosize(textEl);
// TODO: detach when unmount
- // TODO
- //new Autocomplete(textEl, this, { model: 'text' });
+ new Autocomplete(textEl, $$(text));
// 書きかけの投稿を復元
const draft = JSON.parse(miLocalStorage.getItem('message_drafts') ?? '{}')[draftKey];
@@ -282,7 +277,7 @@ defineExpose({
background: transparent;
cursor: pointer;
}
-/*
+
.files {
display: block;
margin: 0;
@@ -316,7 +311,7 @@ defineExpose({
}
}
-.file-remove {
+.fileRemove {
display: none;
position: absolute;
right: -6px;
@@ -330,7 +325,6 @@ defineExpose({
box-shadow: none;
cursor: pointer;
}
-*/
.buttons {
display: flex;
diff --git a/packages/frontend/src/pages/messaging/messaging-room.message.vue b/packages/frontend/src/pages/messaging/messaging-room.message.vue
index 2d4d172539..1d1b00e87c 100644
--- a/packages/frontend/src/pages/messaging/messaging-room.message.vue
+++ b/packages/frontend/src/pages/messaging/messaging-room.message.vue
@@ -1,3 +1,8 @@
+
+
@@ -22,13 +27,14 @@
@@ -39,13 +45,13 @@
import { } from 'vue';
import * as mfm from 'cherrypick-mfm-js';
import * as Misskey from 'cherrypick-js';
-import * as os from '@/os';
+import * as os from '@/os.js';
import MkUrlPreview from '@/components/MkUrlPreview.vue';
import MkAvatar from '@/components/global/MkAvatar.vue';
import MkTime from '@/components/global/MkTime.vue';
-import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm';
-import { i18n } from '@/i18n';
-import { $i } from '@/account';
+import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
+import { i18n } from '@/i18n.js';
+import { $i } from '@/account.js';
const props = defineProps<{
message: Misskey.entities.MessagingMessage;
@@ -204,7 +210,7 @@ function del(): void {
font-size: 0.65em;
> .read {
- margin: 0 8px;
+ margin: 0 4px;
}
> i {
@@ -266,7 +272,7 @@ function del(): void {
::selection {
color: var(--accent);
background-color: #fff;
- }
+ }
&.noText {
background: transparent;
diff --git a/packages/frontend/src/pages/messaging/messaging-room.vue b/packages/frontend/src/pages/messaging/messaging-room.vue
index ed2867fa0e..317e2a1351 100644
--- a/packages/frontend/src/pages/messaging/messaging-room.vue
+++ b/packages/frontend/src/pages/messaging/messaging-room.vue
@@ -1,76 +1,86 @@
+
+
-
-
-
+
-
-
-
-
-
-
{{ i18n.ts.noMessagesYet }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ typer.username }}
+
+
+
+
+
+
+
{{ i18n.ts.noMessagesYet }}
+
+
+
+
+
+
-
-
+
-
-
-
+
+
+
+
-
-
diff --git a/packages/frontend/src/pages/my-clips/index.vue b/packages/frontend/src/pages/my-clips/index.vue
index 9e356f2ef9..ade8dad424 100644
--- a/packages/frontend/src/pages/my-clips/index.vue
+++ b/packages/frontend/src/pages/my-clips/index.vue
@@ -1,3 +1,8 @@
+
+
@@ -22,9 +27,9 @@
import { watch } from 'vue';
import MkPagination from '@/components/MkPagination.vue';
import MkClipPreview from '@/components/MkClipPreview.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
import { clipsCache } from '@/cache';
const pagination = {
diff --git a/packages/frontend/src/pages/my-groups/group.vue b/packages/frontend/src/pages/my-groups/group.vue
index 4ffd6222f2..d25c15e05e 100644
--- a/packages/frontend/src/pages/my-groups/group.vue
+++ b/packages/frontend/src/pages/my-groups/group.vue
@@ -1,3 +1,8 @@
+
+
@@ -35,13 +40,13 @@
diff --git a/packages/frontend/src/pages/my-lists/index.vue b/packages/frontend/src/pages/my-lists/index.vue
index 894d65ae99..84cf913ab4 100644
--- a/packages/frontend/src/pages/my-lists/index.vue
+++ b/packages/frontend/src/pages/my-lists/index.vue
@@ -1,37 +1,48 @@
+
+
-
-
-
- {{ list.name }}
-
-
+
+
+
+
{{ i18n.ts.nothing }}
-
+
+
+
+
+ {{ list.name }} ({{ i18n.t('nUsers', { n: `${list.userIds.length}/${$i?.policies['userEachUserListsLimit']}` }) }})
+
+
+
@@ -74,4 +93,9 @@ definePageMetadata({
text-decoration: none;
}
}
+
+.nUsers {
+ font-size: .9em;
+ opacity: .7;
+}
diff --git a/packages/frontend/src/pages/my-lists/list.vue b/packages/frontend/src/pages/my-lists/list.vue
index dd431e8dc0..a8c320be0e 100644
--- a/packages/frontend/src/pages/my-lists/list.vue
+++ b/packages/frontend/src/pages/my-lists/list.vue
@@ -1,3 +1,8 @@
+
+
@@ -20,6 +25,7 @@
{{ i18n.ts.members }}
+ {{ i18n.t('nUsers', { n: `${list.userIds.length}/${$i?.policies['userEachUserListsLimit']}` }) }}
{{ i18n.ts.addUser }}
@@ -29,6 +35,10 @@
+
+ {{ i18n.ts.loadMore }}
+
+
@@ -38,45 +48,68 @@
+
+
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue
index eca3feda62..dbbe3081db 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue
@@ -1,3 +1,8 @@
+
+
$emit('remove')">
@@ -19,8 +24,8 @@
import { onMounted } from 'vue';
import XContainer from '../page-editor.container.vue';
import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
const props = defineProps<{
modelValue: any
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue
index a388a8d0c1..b223c73abf 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue
@@ -1,3 +1,8 @@
+
+
$emit('remove')">
@@ -24,8 +29,8 @@ import MkInput from '@/components/MkInput.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkNote from '@/components/MkNote.vue';
import MkNoteDetailed from '@/components/MkNoteDetailed.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
const props = defineProps<{
modelValue: any
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue
index 27324bdaef..207858ffe7 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue
@@ -1,3 +1,8 @@
+
+
$emit('remove')">
@@ -20,9 +25,9 @@
import { defineAsyncComponent, inject, onMounted, watch } from 'vue';
import { v4 as uuid } from 'uuid';
import XContainer from '../page-editor.container.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
-import { deepClone } from '@/scripts/clone';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
+import { deepClone } from '@/scripts/clone.js';
import MkButton from '@/components/MkButton.vue';
const XBlocks = defineAsyncComponent(() => import('../page-editor.blocks.vue'));
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
index 3b15c17747..87ff8b8bb8 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
@@ -1,3 +1,8 @@
+
+
$emit('remove')">
@@ -13,7 +18,7 @@
/* eslint-disable vue/no-mutating-props */
import { watch } from 'vue';
import XContainer from '../page-editor.container.vue';
-import { i18n } from '@/i18n';
+import { i18n } from '@/i18n.js';
const props = defineProps<{
modelValue: any
diff --git a/packages/frontend/src/pages/page-editor/page-editor.blocks.vue b/packages/frontend/src/pages/page-editor/page-editor.blocks.vue
index fc945b3d63..8f66457bcf 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.blocks.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.blocks.vue
@@ -1,3 +1,8 @@
+
+
$emit('update:modelValue', v)">
diff --git a/packages/frontend/src/pages/page-editor/page-editor.container.vue b/packages/frontend/src/pages/page-editor/page-editor.container.vue
index 0842b4fd26..d8528a2e0c 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.container.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.container.vue
@@ -1,3 +1,8 @@
+
+
@@ -24,7 +29,7 @@
diff --git a/packages/frontend/src/pages/settings/2fa.vue b/packages/frontend/src/pages/settings/2fa.vue
index 527164ae0e..28394b9fd7 100644
--- a/packages/frontend/src/pages/settings/2fa.vue
+++ b/packages/frontend/src/pages/settings/2fa.vue
@@ -1,22 +1,36 @@
+
+
{{ i18n.ts['2fa'] }}
-
+
+ {{ i18n.ts._2fa.backupCodeUsedWarning }}
+
+
+ {{ i18n.ts._2fa.backupCodesExhaustedWarning }}
+
+
+
{{ i18n.ts.totp }}
{{ i18n.ts.totpDescription }}
+
+
{{ i18n.ts._2fa.renewTOTP }}
{{ i18n.ts._2fa.whyTOTPOnlyRenew }}
-
{{ i18n.ts.unregister }}
+
{{ i18n.ts.unregister }}
- {{ i18n.ts._2fa.registerTOTP }}
+ {{ i18n.ts._2fa.registerTOTP }}
@@ -24,16 +38,14 @@
{{ i18n.ts.securityKeyAndPasskey }}
- {{ i18n.ts._2fa.securityKeyInfo }}
-
- {{ i18n.ts._2fa.chromePasskeyNotSupported }}
+ {{ i18n.ts._2fa.securityKeyInfo }}
-
+
{{ i18n.ts._2fa.securityKeyNotSupported }}
-
+
{{ i18n.ts._2fa.registerTOTPBeforeKey }}
@@ -61,16 +73,15 @@
diff --git a/packages/frontend/src/pages/settings/sounds.sound.vue b/packages/frontend/src/pages/settings/sounds.sound.vue
index c1a333548d..c8e42ad422 100644
--- a/packages/frontend/src/pages/settings/sounds.sound.vue
+++ b/packages/frontend/src/pages/settings/sounds.sound.vue
@@ -1,3 +1,8 @@
+
+
@@ -20,8 +25,8 @@ import { } from 'vue';
import MkSelect from '@/components/MkSelect.vue';
import MkButton from '@/components/MkButton.vue';
import MkRange from '@/components/MkRange.vue';
-import { i18n } from '@/i18n';
-import { playFile, soundsTypes } from '@/scripts/sound';
+import { i18n } from '@/i18n.js';
+import { playFile, soundsTypes } from '@/scripts/sound.js';
const props = defineProps<{
type: string;
diff --git a/packages/frontend/src/pages/settings/statusbar.statusbar.vue b/packages/frontend/src/pages/settings/statusbar.statusbar.vue
index c73ff7c075..622db59036 100644
--- a/packages/frontend/src/pages/settings/statusbar.statusbar.vue
+++ b/packages/frontend/src/pages/settings/statusbar.statusbar.vue
@@ -1,3 +1,8 @@
+
+
@@ -88,9 +93,9 @@ import MkSwitch from '@/components/MkSwitch.vue';
import MkRadios from '@/components/MkRadios.vue';
import MkButton from '@/components/MkButton.vue';
import MkRange from '@/components/MkRange.vue';
-import { defaultStore } from '@/store';
-import { i18n } from '@/i18n';
-import { deepClone } from '@/scripts/clone';
+import { defaultStore } from '@/store.js';
+import { i18n } from '@/i18n.js';
+import { deepClone } from '@/scripts/clone.js';
const props = defineProps<{
_id: string;
diff --git a/packages/frontend/src/pages/settings/statusbar.vue b/packages/frontend/src/pages/settings/statusbar.vue
index bfb69936e1..49a8e2f4a2 100644
--- a/packages/frontend/src/pages/settings/statusbar.vue
+++ b/packages/frontend/src/pages/settings/statusbar.vue
@@ -1,3 +1,8 @@
+
+
@@ -15,10 +20,10 @@ import { v4 as uuid } from 'uuid';
import XStatusbar from './statusbar.statusbar.vue';
import MkFolder from '@/components/MkFolder.vue';
import MkButton from '@/components/MkButton.vue';
-import * as os from '@/os';
-import { defaultStore } from '@/store';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import * as os from '@/os.js';
+import { defaultStore } from '@/store.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
const statusbars = defaultStore.reactiveState.statusbars;
diff --git a/packages/frontend/src/pages/settings/theme.install.vue b/packages/frontend/src/pages/settings/theme.install.vue
index 416464ceca..64f230f529 100644
--- a/packages/frontend/src/pages/settings/theme.install.vue
+++ b/packages/frontend/src/pages/settings/theme.install.vue
@@ -1,3 +1,8 @@
+
+
@@ -16,11 +21,11 @@ import { } from 'vue';
import JSON5 from 'json5';
import MkTextarea from '@/components/MkTextarea.vue';
import MkButton from '@/components/MkButton.vue';
-import { applyTheme, validateTheme } from '@/scripts/theme';
-import * as os from '@/os';
+import { applyTheme, validateTheme } from '@/scripts/theme.js';
+import * as os from '@/os.js';
import { addTheme, getThemes } from '@/theme-store';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
let installThemeCode = $ref(null);
diff --git a/packages/frontend/src/pages/settings/theme.manage.vue b/packages/frontend/src/pages/settings/theme.manage.vue
index 0255435112..1faf36d65b 100644
--- a/packages/frontend/src/pages/settings/theme.manage.vue
+++ b/packages/frontend/src/pages/settings/theme.manage.vue
@@ -1,3 +1,8 @@
+
+
@@ -32,12 +37,12 @@ import MkTextarea from '@/components/MkTextarea.vue';
import MkSelect from '@/components/MkSelect.vue';
import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue';
-import { Theme, getBuiltinThemesRef } from '@/scripts/theme';
-import copyToClipboard from '@/scripts/copy-to-clipboard';
-import * as os from '@/os';
+import { Theme, getBuiltinThemesRef } from '@/scripts/theme.js';
+import copyToClipboard from '@/scripts/copy-to-clipboard.js';
+import * as os from '@/os.js';
import { getThemes, removeTheme } from '@/theme-store';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
const installedThemes = ref(getThemes());
const builtinThemes = getBuiltinThemesRef();
diff --git a/packages/frontend/src/pages/settings/theme.vue b/packages/frontend/src/pages/settings/theme.vue
index aec92c2d1d..1cbc582d90 100644
--- a/packages/frontend/src/pages/settings/theme.vue
+++ b/packages/frontend/src/pages/settings/theme.vue
@@ -1,3 +1,8 @@
+
+
@@ -73,16 +78,16 @@ import MkSelect from '@/components/MkSelect.vue';
import FormSection from '@/components/form/section.vue';
import FormLink from '@/components/form/link.vue';
import MkButton from '@/components/MkButton.vue';
-import { getBuiltinThemesRef } from '@/scripts/theme';
-import { selectFile } from '@/scripts/select-file';
-import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
-import { ColdDeviceStorage, defaultStore } from '@/store';
-import { i18n } from '@/i18n';
-import { instance } from '@/instance';
-import { uniqueBy } from '@/scripts/array';
+import { getBuiltinThemesRef } from '@/scripts/theme.js';
+import { selectFile } from '@/scripts/select-file.js';
+import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js';
+import { ColdDeviceStorage, defaultStore } from '@/store.js';
+import { i18n } from '@/i18n.js';
+import { instance } from '@/instance.js';
+import { uniqueBy } from '@/scripts/array.js';
import { fetchThemes, getThemes } from '@/theme-store';
-import { definePageMetadata } from '@/scripts/page-metadata';
-import { miLocalStorage } from '@/local-storage';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { miLocalStorage } from '@/local-storage.js';
const installedThemes = ref(getThemes());
const builtinThemes = getBuiltinThemesRef();
diff --git a/packages/frontend/src/pages/settings/timeline.vue b/packages/frontend/src/pages/settings/timeline.vue
new file mode 100644
index 0000000000..dff16468b4
--- /dev/null
+++ b/packages/frontend/src/pages/settings/timeline.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+ {{ i18n.ts.timeline }}
+
+ {{ i18n.ts._timelines.home }}
+ {{ i18n.ts._timelines.local }}
+ {{ i18n.ts._timelines.media }}
+ {{ i18n.ts._timelines.social }}
+ {{ i18n.ts._timelines.cat }}
+ {{ i18n.ts._timelines.global }}
+
+
+
+
+
+ {{ i18n.ts.lists }}
+ {{ i18n.ts.antennas }}
+ {{ i18n.ts.channel }}
+
+
+
+
{{ i18n.ts.save }}
+
+
+
+
diff --git a/packages/frontend/src/pages/settings/webhook.edit.vue b/packages/frontend/src/pages/settings/webhook.edit.vue
index 3c782973ae..05117896c5 100644
--- a/packages/frontend/src/pages/settings/webhook.edit.vue
+++ b/packages/frontend/src/pages/settings/webhook.edit.vue
@@ -1,3 +1,8 @@
+
+
@@ -42,10 +47,10 @@ import MkInput from '@/components/MkInput.vue';
import FormSection from '@/components/form/section.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkButton from '@/components/MkButton.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
-import { useRouter } from '@/router';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { useRouter } from '@/router.js';
const router = useRouter();
diff --git a/packages/frontend/src/pages/settings/webhook.new.vue b/packages/frontend/src/pages/settings/webhook.new.vue
index 6eb8a654f5..f15a3ab045 100644
--- a/packages/frontend/src/pages/settings/webhook.new.vue
+++ b/packages/frontend/src/pages/settings/webhook.new.vue
@@ -1,3 +1,8 @@
+
+
@@ -39,9 +44,9 @@ import MkInput from '@/components/MkInput.vue';
import FormSection from '@/components/form/section.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkButton from '@/components/MkButton.vue';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import * as os from '@/os.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
let name = $ref('');
let url = $ref('');
diff --git a/packages/frontend/src/pages/settings/webhook.vue b/packages/frontend/src/pages/settings/webhook.vue
index 4f702758f4..b1aa0dda11 100644
--- a/packages/frontend/src/pages/settings/webhook.vue
+++ b/packages/frontend/src/pages/settings/webhook.vue
@@ -1,3 +1,8 @@
+
+
@@ -32,8 +37,8 @@ import { } from 'vue';
import MkPagination from '@/components/MkPagination.vue';
import FormSection from '@/components/form/section.vue';
import FormLink from '@/components/form/link.vue';
-import { definePageMetadata } from '@/scripts/page-metadata';
-import { i18n } from '@/i18n';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { i18n } from '@/i18n.js';
const pagination = {
endpoint: 'i/webhooks/list' as const,
diff --git a/packages/frontend/src/pages/settings/word-mute.vue b/packages/frontend/src/pages/settings/word-mute.vue
index 576e6c828b..a45c1518e3 100644
--- a/packages/frontend/src/pages/settings/word-mute.vue
+++ b/packages/frontend/src/pages/settings/word-mute.vue
@@ -1,3 +1,8 @@
+
+
@@ -35,12 +40,12 @@ import MkKeyValue from '@/components/MkKeyValue.vue';
import MkButton from '@/components/MkButton.vue';
import MkInfo from '@/components/MkInfo.vue';
import MkTab from '@/components/MkTab.vue';
-import * as os from '@/os';
-import number from '@/filters/number';
-import { defaultStore } from '@/store';
-import { $i } from '@/account';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import * as os from '@/os.js';
+import number from '@/filters/number.js';
+import { defaultStore } from '@/store.js';
+import { $i } from '@/account.js';
+import { i18n } from '@/i18n.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
const render = (mutedWords) => mutedWords.map(x => {
if (Array.isArray(x)) {
diff --git a/packages/frontend/src/pages/share.vue b/packages/frontend/src/pages/share.vue
index c355bd8d4c..7e8f7235c5 100644
--- a/packages/frontend/src/pages/share.vue
+++ b/packages/frontend/src/pages/share.vue
@@ -1,3 +1,8 @@
+
+
@@ -28,19 +33,17 @@
// SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html
import { } from 'vue';
-import { noteVisibilities } from 'cherrypick-js';
-import * as Acct from 'cherrypick-js/built/acct';
import * as Misskey from 'cherrypick-js';
import MkButton from '@/components/MkButton.vue';
import MkPostForm from '@/components/MkPostForm.vue';
-import * as os from '@/os';
-import { mainRouter } from '@/router';
-import { definePageMetadata } from '@/scripts/page-metadata';
-import { i18n } from '@/i18n';
+import * as os from '@/os.js';
+import { mainRouter } from '@/router.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { i18n } from '@/i18n.js';
const urlParams = new URLSearchParams(window.location.search);
const localOnlyQuery = urlParams.get('localOnly');
-const visibilityQuery = urlParams.get('visibility') as typeof noteVisibilities[number];
+const visibilityQuery = urlParams.get('visibility') as typeof Misskey.noteVisibilities[number];
let state = $ref('fetching' as 'fetching' | 'writing' | 'posted');
let title = $ref(urlParams.get('title'));
@@ -49,7 +52,7 @@ const url = urlParams.get('url');
let initialText = $ref();
let reply = $ref();
let renote = $ref();
-let visibility = $ref(noteVisibilities.includes(visibilityQuery) ? visibilityQuery : undefined);
+let visibility = $ref(Misskey.noteVisibilities.includes(visibilityQuery) ? visibilityQuery : undefined);
let localOnly = $ref(localOnlyQuery === '0' ? false : localOnlyQuery === '1' ? true : undefined);
let files = $ref([] as Misskey.entities.DriveFile[]);
let visibleUsers = $ref([] as Misskey.entities.User[]);
@@ -69,7 +72,7 @@ async function init() {
await Promise.all(
[
...(visibleUserIds ? visibleUserIds.split(',').map(userId => ({ userId })) : []),
- ...(visibleAccts ? visibleAccts.split(',').map(Acct.parse) : []),
+ ...(visibleAccts ? visibleAccts.split(',').map(Misskey.acct.parse) : []),
]
// TypeScriptの指示通りに変換する
.map(q => 'username' in q ? { username: q.username, host: q.host === null ? undefined : q.host } : q)
diff --git a/packages/frontend/src/pages/signup-complete.vue b/packages/frontend/src/pages/signup-complete.vue
index 61d7eb24fd..86c000c8b5 100644
--- a/packages/frontend/src/pages/signup-complete.vue
+++ b/packages/frontend/src/pages/signup-complete.vue
@@ -1,3 +1,8 @@
+
+
@@ -23,9 +28,9 @@
import { } from 'vue';
import MkButton from '@/components/MkButton.vue';
import MkAnimBg from '@/components/MkAnimBg.vue';
-import { login } from '@/account';
-import { i18n } from '@/i18n';
-import * as os from '@/os';
+import { login } from '@/account.js';
+import { i18n } from '@/i18n.js';
+import * as os from '@/os.js';
let submitting = $ref(false);
diff --git a/packages/frontend/src/pages/tag.vue b/packages/frontend/src/pages/tag.vue
index 104e738866..a1fd64577b 100644
--- a/packages/frontend/src/pages/tag.vue
+++ b/packages/frontend/src/pages/tag.vue
@@ -1,3 +1,8 @@
+
+
@@ -18,11 +23,11 @@
import { computed, ref } from 'vue';
import MkNotes from '@/components/MkNotes.vue';
import MkButton from '@/components/MkButton.vue';
-import { definePageMetadata } from '@/scripts/page-metadata';
-import { i18n } from '@/i18n';
-import { $i } from '@/account';
-import { defaultStore } from '@/store';
-import * as os from '@/os';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
+import { i18n } from '@/i18n.js';
+import { $i } from '@/account.js';
+import { defaultStore } from '@/store.js';
+import * as os from '@/os.js';
const props = defineProps<{
tag: string;
diff --git a/packages/frontend/src/pages/theme-editor.vue b/packages/frontend/src/pages/theme-editor.vue
index f942b5005b..6096da53a3 100644
--- a/packages/frontend/src/pages/theme-editor.vue
+++ b/packages/frontend/src/pages/theme-editor.vue
@@ -1,3 +1,8 @@
+
+
@@ -78,17 +83,17 @@ import MkButton from '@/components/MkButton.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import MkFolder from '@/components/MkFolder.vue';
-import { $i } from '@/account';
-import { Theme, applyTheme } from '@/scripts/theme';
+import { $i } from '@/account.js';
+import { Theme, applyTheme } from '@/scripts/theme.js';
import lightTheme from '@/themes/_light.json5';
import darkTheme from '@/themes/_dark.json5';
-import { host } from '@/config';
-import * as os from '@/os';
-import { ColdDeviceStorage, defaultStore } from '@/store';
+import { host } from '@/config.js';
+import * as os from '@/os.js';
+import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { addTheme } from '@/theme-store';
-import { i18n } from '@/i18n';
-import { useLeaveGuard } from '@/scripts/use-leave-guard';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import { i18n } from '@/i18n.js';
+import { useLeaveGuard } from '@/scripts/use-leave-guard.js';
+import { definePageMetadata } from '@/scripts/page-metadata.js';
const bgColors = [
{ color: '#f5f5f5', kind: 'light', forPreview: '#f5f5f5' },
diff --git a/packages/frontend/src/pages/timeline.tutorial.vue b/packages/frontend/src/pages/timeline.tutorial.vue
index 32228d28f4..d17ad9cd38 100644
--- a/packages/frontend/src/pages/timeline.tutorial.vue
+++ b/packages/frontend/src/pages/timeline.tutorial.vue
@@ -1,3 +1,8 @@
+
+
@@ -44,10 +49,10 @@
@@ -266,9 +299,13 @@ definePageMetadata(computed(() => ({
}
&.showEl {
- transform: translateY(calc(var(--stickyTop, 0px) - 181px))
+ transform: translateY(calc(var(--stickyTop, 0px) - 101px))
}
+ &.showElTab {
+ transform: translateY(calc(var(--stickyTop, 0px) - 181px))
+ }
+
&.reduceAnimation {
transition: opacity 0s, transform 0s;
}
diff --git a/packages/frontend/src/pages/user-list-timeline.vue b/packages/frontend/src/pages/user-list-timeline.vue
index f66670e1f6..957869ac5c 100644
--- a/packages/frontend/src/pages/user-list-timeline.vue
+++ b/packages/frontend/src/pages/user-list-timeline.vue
@@ -1,3 +1,8 @@
+
+
@@ -21,11 +26,11 @@
diff --git a/packages/frontend/src/pages/user/clips.vue b/packages/frontend/src/pages/user/clips.vue
index 343ed42017..c205225a29 100644
--- a/packages/frontend/src/pages/user/clips.vue
+++ b/packages/frontend/src/pages/user/clips.vue
@@ -1,3 +1,8 @@
+
+
@@ -13,11 +18,11 @@
diff --git a/packages/frontend/src/pages/user/follow-list.vue b/packages/frontend/src/pages/user/follow-list.vue
index e8a49927ca..51ab91a748 100644
--- a/packages/frontend/src/pages/user/follow-list.vue
+++ b/packages/frontend/src/pages/user/follow-list.vue
@@ -1,3 +1,8 @@
+
+
@@ -10,12 +15,12 @@
+
+
diff --git a/packages/frontend/src/ui/_common_/common.ts b/packages/frontend/src/ui/_common_/common.ts
index f97d187730..65de7b9070 100644
--- a/packages/frontend/src/ui/_common_/common.ts
+++ b/packages/frontend/src/ui/_common_/common.ts
@@ -1,8 +1,16 @@
-import * as os from '@/os';
-import { instance } from '@/instance';
-import { host } from '@/config';
-import { i18n } from '@/i18n';
-import { $i } from '@/account';
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey, cherrypick contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { defineAsyncComponent } from 'vue';
+import * as os from '@/os.js';
+import { instance } from '@/instance.js';
+import { host } from '@/config.js';
+import { i18n } from '@/i18n.js';
+import { $i } from '@/account.js';
+import { defaultStore } from '@/store.js';
+import { unisonReload } from '@/scripts/unison-reload.js';
export function openInstanceMenu(ev: MouseEvent) {
os.popupMenu([{
@@ -33,7 +41,12 @@ export function openInstanceMenu(ev: MouseEvent) {
text: i18n.ts.ads,
icon: 'ti ti-ad',
to: '/ads',
- }, {
+ }, ($i && ($i.isAdmin || $i.policies.canInvite) && instance.disableRegistration) ? {
+ type: 'link',
+ to: '/invite',
+ text: i18n.ts.invite,
+ icon: 'ti ti-user-plus',
+ } : undefined, {
type: 'parent',
text: i18n.ts.tools,
icon: 'ti ti-tool',
@@ -52,29 +65,20 @@ export function openInstanceMenu(ev: MouseEvent) {
to: '/clicker',
text: '🍪👈',
icon: 'ti ti-cookie',
- }, ($i && ($i.isAdmin || $i.policies.canInvite) && instance.disableRegistration) ? {
- text: i18n.ts.invite,
- icon: 'ti ti-user-plus',
- action: () => {
- os.api('invite').then(x => {
- os.alert({
- type: 'info',
- text: x.code,
- });
- }).catch(err => {
- os.alert({
- type: 'error',
- text: err,
- });
- });
- },
- } : undefined, ($i && ($i.isAdmin || $i.policies.canManageCustomEmojis)) ? {
+ }, ($i && ($i.isAdmin || $i.policies.canManageCustomEmojis)) ? {
type: 'link',
to: '/custom-emojis-manager',
text: i18n.ts.manageCustomEmojis,
icon: 'ti ti-icons',
} : undefined],
}, null, {
+ type: 'button',
+ text: i18n.ts.termsOfService,
+ icon: 'ti ti-checklist',
+ action: () => {
+ window.open(instance.tosUrl, '_blank');
+ },
+ }, {
type: 'parent',
text: i18n.ts.help,
icon: 'ti ti-help-circle',
@@ -89,6 +93,28 @@ export function openInstanceMenu(ev: MouseEvent) {
text: i18n.ts._mfm.cheatSheet,
icon: 'ti ti-help-circle',
to: '/mfm-cheat-sheet',
+ }, null, {
+ type: 'button',
+ text: i18n.ts.replayUserSetupDialog,
+ icon: 'ti ti-list-numbers',
+ action: () => {
+ defaultStore.set('accountSetupWizard', 0);
+ os.popup(defineAsyncComponent(() => import('@/components/MkUserSetupDialog.vue')), {}, {}, 'closed');
+ },
+ }, {
+ type: 'button',
+ text: i18n.ts.replayTutorial,
+ icon: 'ti ti-checkup-list',
+ action: () => {
+ defaultStore.set('timelineTutorial', 0);
+ defaultStore.set('tlHomeHintClosed', false);
+ defaultStore.set('tlLocalHintClosed', false);
+ defaultStore.set('tlMediaHintClosed', false);
+ defaultStore.set('tlSocialHintClosed', false);
+ defaultStore.set('tlCatHintClosed', false);
+ defaultStore.set('tlGlobalHintClosed', false);
+ setTimeout(unisonReload, 100);
+ },
}],
}, {
type: 'link',
diff --git a/packages/frontend/src/ui/_common_/common.vue b/packages/frontend/src/ui/_common_/common.vue
index 7beb487e8d..c7278d0db2 100644
--- a/packages/frontend/src/ui/_common_/common.vue
+++ b/packages/frontend/src/ui/_common_/common.vue
@@ -1,3 +1,8 @@
+
+
import { defineAsyncComponent, ref } from 'vue';
-import * as misskey from 'cherrypick-js';
+import * as Misskey from 'cherrypick-js';
import { swInject } from './sw-inject';
import XNotification from './notification.vue';
-import { popups, pendingApiRequestsCount } from '@/os';
-import { uploads } from '@/scripts/upload';
-import * as sound from '@/scripts/sound';
-import { $i } from '@/account';
-import { useStream } from '@/stream';
-import { i18n } from '@/i18n';
-import { defaultStore } from '@/store';
+import { popups, pendingApiRequestsCount } from '@/os.js';
+import { uploads } from '@/scripts/upload.js';
+import * as sound from '@/scripts/sound.js';
+import { $i } from '@/account.js';
+import { useStream } from '@/stream.js';
+import { i18n } from '@/i18n.js';
+import { defaultStore } from '@/store.js';
+import { globalEvents } from '@/events.js';
const XStreamIndicator = defineAsyncComponent(() => import('./stream-indicator.vue'));
const XUpload = defineAsyncComponent(() => import('./upload.vue'));
const dev = _DEV_;
-let notifications = $ref([]);
+let notifications = $ref([]);
-function onNotification(notification) {
+function onNotification(notification: Misskey.entities.Notification, isClient = false) {
if ($i.mutingNotificationTypes.includes(notification.type)) return;
if (document.visibilityState === 'visible') {
- useStream().send('readNotification');
+ if (!isClient) {
+ useStream().send('readNotification');
+ }
notifications.unshift(notification);
window.setTimeout(() => {
@@ -81,6 +89,7 @@ function onNotification(notification) {
if ($i) {
const connection = useStream().useChannel('main', null, 'UI');
connection.on('notification', onNotification);
+ globalEvents.on('clientNotification', notification => onNotification(notification, true));
//#region Listen message from SW
if ('serviceWorker' in navigator) {
diff --git a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
index f9699736c6..21edb42bd7 100644
--- a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
+++ b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
@@ -1,9 +1,14 @@
+
+
-
@@ -13,7 +18,7 @@
-
+
{{ navbarItemDef[item].title }}
@@ -21,9 +26,10 @@
{{ i18n.ts.controlPanel }}
+
-
- {{ i18n.ts.more }}
+
+ {{ i18n.ts.more }}
@@ -32,10 +38,10 @@
-
- {{ i18n.ts.note }}
+
+ {{ defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note }}
-
+
@@ -45,12 +51,12 @@
@@ -21,4 +27,8 @@ defineProps<{
overflow: clip;
contain: content;
}
+
+.reduceBlurEffect {
+ background: var(--panel) !important;
+}
diff --git a/packages/frontend/src/ui/_common_/statusbar-federation.vue b/packages/frontend/src/ui/_common_/statusbar-federation.vue
index 77c2681ced..cce74a4de7 100644
--- a/packages/frontend/src/ui/_common_/statusbar-federation.vue
+++ b/packages/frontend/src/ui/_common_/statusbar-federation.vue
@@ -1,3 +1,8 @@
+
+
@@ -27,11 +32,11 @@
diff --git a/packages/frontend/src/ui/classic.header.vue b/packages/frontend/src/ui/classic.header.vue
index 747d4edcb4..486ed0d2f7 100644
--- a/packages/frontend/src/ui/classic.header.vue
+++ b/packages/frontend/src/ui/classic.header.vue
@@ -1,8 +1,13 @@
+
+
-
+
@@ -10,7 +15,7 @@
-
+
@@ -19,7 +24,7 @@
-
+
@@ -28,7 +33,7 @@
-
+
@@ -44,13 +49,13 @@
@@ -177,7 +182,7 @@ onMounted(() => {
> .post {
display: inline-block;
-
+
> .button {
width: 40px;
height: 40px;
diff --git a/packages/frontend/src/ui/classic.sidebar.vue b/packages/frontend/src/ui/classic.sidebar.vue
index 561d615755..82970bdd78 100644
--- a/packages/frontend/src/ui/classic.sidebar.vue
+++ b/packages/frontend/src/ui/classic.sidebar.vue
@@ -1,11 +1,16 @@
+
+
-
+
- {{ i18n.ts.note }}
+ {{ defaultStore.state.renameTheButtonInPostFormToNya ? i18n.ts.nya : i18n.ts.note }}
@@ -14,7 +19,7 @@
-
+
{{ navbarItemDef[item].title }}
@@ -22,8 +27,9 @@
{{ i18n.ts.controlPanel }}
+
-
+
{{ i18n.ts.more }}