summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorAcid Chicken (硫酸鶏) <root@acid-chicken.com>2023-04-03 13:01:15 +0900
committerGitHub <noreply@github.com>2023-04-03 13:01:15 +0900
commit8a9847b06a3b0ec7acd69258435664ab82e8a9e7 (patch)
tree09030e98032845e75357fb00c03cd250089c3222 /packages
parentfix: the avatar in the title bar is clipped (diff)
parentMerge branch 'develop' of https://github.com/misskey-dev/misskey into develop (diff)
downloadmisskey-8a9847b06a3b0ec7acd69258435664ab82e8a9e7.tar.gz
misskey-8a9847b06a3b0ec7acd69258435664ab82e8a9e7.tar.bz2
misskey-8a9847b06a3b0ec7acd69258435664ab82e8a9e7.zip
Merge branch 'develop' into acid-chicken-patch-1
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/migration/1680491187535-cleanup.js10
-rw-r--r--packages/backend/src/core/AntennaService.ts61
-rw-r--r--packages/backend/src/core/IdService.ts15
-rw-r--r--packages/backend/src/core/NoteCreateService.ts12
-rw-r--r--packages/backend/src/core/NoteReadService.ts43
-rw-r--r--packages/backend/src/core/VideoProcessingService.ts2
-rw-r--r--packages/backend/src/core/entities/AntennaEntityService.ts9
-rw-r--r--packages/backend/src/core/entities/UserEntityService.ts8
-rw-r--r--packages/backend/src/di-symbols.ts1
-rw-r--r--packages/backend/src/misc/id/aid.ts5
-rw-r--r--packages/backend/src/models/RepositoryModule.ts10
-rw-r--r--packages/backend/src/models/entities/AntennaNote.ts43
-rw-r--r--packages/backend/src/models/index.ts3
-rw-r--r--packages/backend/src/postgres.ts2
-rw-r--r--packages/backend/src/queue/processors/CleanProcessorService.ts5
-rw-r--r--packages/backend/src/server/api/endpoints/antennas/notes.ts40
-rw-r--r--packages/backend/src/server/api/endpoints/channels/timeline.ts29
-rw-r--r--packages/frontend/@types/vue.d.ts16
-rw-r--r--packages/frontend/src/components/MkContainer.vue13
-rw-r--r--packages/frontend/src/components/MkContextMenu.vue9
-rw-r--r--packages/frontend/src/components/MkDonation.vue3
-rw-r--r--packages/frontend/src/components/MkFoldableSection.vue4
-rw-r--r--packages/frontend/src/components/MkFolder.vue9
-rw-r--r--packages/frontend/src/components/MkFormDialog.vue14
-rw-r--r--packages/frontend/src/components/MkGoogle.vue3
-rw-r--r--packages/frontend/src/components/MkMediaBanner.vue5
-rw-r--r--packages/frontend/src/components/MkMediaVideo.vue5
-rw-r--r--packages/frontend/src/components/MkMention.vue3
-rw-r--r--packages/frontend/src/components/MkModalPageWindow.vue2
-rw-r--r--packages/frontend/src/components/MkNote.vue2
-rw-r--r--packages/frontend/src/components/MkNoteDetailed.vue2
-rw-r--r--packages/frontend/src/components/MkNotePreview.vue1
-rw-r--r--packages/frontend/src/components/MkNoteSimple.vue1
-rw-r--r--packages/frontend/src/components/MkNoteSub.vue1
-rw-r--r--packages/frontend/src/components/MkOmit.vue3
-rw-r--r--packages/frontend/src/components/MkPagination.vue44
-rw-r--r--packages/frontend/src/components/MkPoll.vue4
-rw-r--r--packages/frontend/src/components/MkPollEditor.vue2
-rw-r--r--packages/frontend/src/components/MkReactionsViewer.vue21
-rw-r--r--packages/frontend/src/components/MkSample.vue2
-rw-r--r--packages/frontend/src/components/MkSubNoteContent.vue3
-rw-r--r--packages/frontend/src/components/MkTimeline.vue3
-rw-r--r--packages/frontend/src/components/MkToast.vue9
-rw-r--r--packages/frontend/src/components/MkTokenGenerateWindow.vue8
-rw-r--r--packages/frontend/src/components/MkTooltip.vue9
-rw-r--r--packages/frontend/src/components/MkUrlPreview.vue3
-rw-r--r--packages/frontend/src/components/MkUrlPreviewPopup.vue3
-rw-r--r--packages/frontend/src/components/MkUserInfo.vue3
-rw-r--r--packages/frontend/src/components/MkUserPopup.vue18
-rw-r--r--packages/frontend/src/components/MkWindow.vue9
-rw-r--r--packages/frontend/src/components/MkYoutubePlayer.vue3
-rw-r--r--packages/frontend/src/components/form/suspense.vue10
-rw-r--r--packages/frontend/src/components/global/MkAcct.vue3
-rw-r--r--packages/frontend/src/components/global/MkAd.vue7
-rw-r--r--packages/frontend/src/components/global/MkError.vue3
-rw-r--r--packages/frontend/src/components/page/page.post.vue8
-rw-r--r--packages/frontend/src/components/page/page.text.vue6
-rw-r--r--packages/frontend/src/init.ts11
-rw-r--r--packages/frontend/src/pages/_error_.vue3
-rw-r--r--packages/frontend/src/pages/about.emojis.vue9
-rw-r--r--packages/frontend/src/pages/about.vue17
-rw-r--r--packages/frontend/src/pages/admin/index.vue4
-rw-r--r--packages/frontend/src/pages/admin/object-storage.vue6
-rw-r--r--packages/frontend/src/pages/admin/overview.instances.vue3
-rw-r--r--packages/frontend/src/pages/admin/overview.moderators.vue3
-rw-r--r--packages/frontend/src/pages/admin/overview.stats.vue3
-rw-r--r--packages/frontend/src/pages/admin/overview.users.vue3
-rw-r--r--packages/frontend/src/pages/admin/relays.vue2
-rw-r--r--packages/frontend/src/pages/announcements.vue3
-rw-r--r--packages/frontend/src/pages/antenna-timeline.vue2
-rw-r--r--packages/frontend/src/pages/auth.form.vue28
-rw-r--r--packages/frontend/src/pages/auth.vue2
-rw-r--r--packages/frontend/src/pages/flash/flash.vue6
-rw-r--r--packages/frontend/src/pages/gallery/post.vue4
-rw-r--r--packages/frontend/src/pages/miauth.vue8
-rw-r--r--packages/frontend/src/pages/note.vue3
-rw-r--r--packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue3
-rw-r--r--packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue9
-rw-r--r--packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue3
-rw-r--r--packages/frontend/src/pages/page-editor/page-editor.container.vue6
-rw-r--r--packages/frontend/src/pages/page-editor/page-editor.vue28
-rw-r--r--packages/frontend/src/pages/page.vue5
-rw-r--r--packages/frontend/src/pages/settings/apps.vue2
-rw-r--r--packages/frontend/src/pages/settings/delete-account.vue2
-rw-r--r--packages/frontend/src/pages/settings/sounds.vue2
-rw-r--r--packages/frontend/src/pages/timeline.vue4
-rw-r--r--packages/frontend/src/pages/user-info.vue2
-rw-r--r--packages/frontend/src/pages/user/home.vue2
-rw-r--r--packages/frontend/src/pages/user/index.activity.vue2
-rw-r--r--packages/frontend/src/pages/user/index.photos.vue4
-rw-r--r--packages/frontend/src/pages/welcome.entrance.a.vue2
-rw-r--r--packages/frontend/src/pages/welcome.entrance.b.vue20
-rw-r--r--packages/frontend/src/pages/welcome.entrance.c.vue32
-rw-r--r--packages/frontend/src/pages/welcome.setup.vue8
-rw-r--r--packages/frontend/src/pages/welcome.timeline.vue13
-rw-r--r--packages/frontend/src/ui/_common_/common.vue11
-rw-r--r--packages/frontend/src/ui/_common_/navbar-for-mobile.vue7
-rw-r--r--packages/frontend/src/ui/_common_/navbar.vue7
-rw-r--r--packages/frontend/src/ui/_common_/stream-indicator.vue3
-rw-r--r--packages/frontend/src/ui/classic.header.vue21
-rw-r--r--packages/frontend/src/ui/classic.sidebar.vue27
-rw-r--r--packages/frontend/src/ui/classic.vue6
-rw-r--r--packages/frontend/src/ui/deck.vue17
-rw-r--r--packages/frontend/src/ui/universal.vue32
-rw-r--r--packages/frontend/src/ui/visitor/a.vue19
-rw-r--r--packages/frontend/src/ui/visitor/b.vue23
-rw-r--r--packages/frontend/src/ui/visitor/header.vue16
-rw-r--r--packages/frontend/src/ui/visitor/kanban.vue14
-rw-r--r--packages/frontend/src/widgets/WidgetCalendar.vue8
-rw-r--r--packages/frontend/src/widgets/WidgetFederation.vue3
-rw-r--r--packages/frontend/src/widgets/WidgetInstanceInfo.vue7
-rw-r--r--packages/frontend/src/widgets/WidgetSlideshow.vue2
-rw-r--r--packages/frontend/src/widgets/WidgetTimeline.vue2
-rw-r--r--packages/frontend/src/widgets/WidgetTrends.vue5
114 files changed, 541 insertions, 533 deletions
diff --git a/packages/backend/migration/1680491187535-cleanup.js b/packages/backend/migration/1680491187535-cleanup.js
new file mode 100644
index 0000000000..1e609ca060
--- /dev/null
+++ b/packages/backend/migration/1680491187535-cleanup.js
@@ -0,0 +1,10 @@
+export class cleanup1680491187535 {
+ name = 'cleanup1680491187535'
+
+ async up(queryRunner) {
+ await queryRunner.query(`DROP TABLE "antenna_note" `);
+ }
+
+ async down(queryRunner) {
+ }
+}
diff --git a/packages/backend/src/core/AntennaService.ts b/packages/backend/src/core/AntennaService.ts
index aaa26a8321..4bd3f39af2 100644
--- a/packages/backend/src/core/AntennaService.ts
+++ b/packages/backend/src/core/AntennaService.ts
@@ -12,7 +12,7 @@ import { PushNotificationService } from '@/core/PushNotificationService.js';
import * as Acct from '@/misc/acct.js';
import type { Packed } from '@/misc/json-schema.js';
import { DI } from '@/di-symbols.js';
-import type { MutingsRepository, NotesRepository, AntennaNotesRepository, AntennasRepository, UserListJoiningsRepository } from '@/models/index.js';
+import type { MutingsRepository, NotesRepository, AntennasRepository, UserListJoiningsRepository } from '@/models/index.js';
import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { StreamMessages } from '@/server/api/stream/types.js';
@@ -24,6 +24,9 @@ export class AntennaService implements OnApplicationShutdown {
private antennas: Antenna[];
constructor(
+ @Inject(DI.redis)
+ private redisClient: Redis.Redis,
+
@Inject(DI.redisSubscriber)
private redisSubscriber: Redis.Redis,
@@ -33,9 +36,6 @@ export class AntennaService implements OnApplicationShutdown {
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
- @Inject(DI.antennaNotesRepository)
- private antennaNotesRepository: AntennaNotesRepository,
-
@Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository,
@@ -92,54 +92,13 @@ export class AntennaService implements OnApplicationShutdown {
@bindThis
public async addNoteToAntenna(antenna: Antenna, note: Note, noteUser: { id: User['id']; }): Promise<void> {
- // 通知しない設定になっているか、自分自身の投稿なら既読にする
- const read = !antenna.notify || (antenna.userId === noteUser.id);
-
- this.antennaNotesRepository.insert({
- id: this.idService.genId(),
- antennaId: antenna.id,
- noteId: note.id,
- read: read,
- });
-
+ this.redisClient.xadd(
+ `antennaTimeline:${antenna.id}`,
+ 'MAXLEN', '~', '200',
+ `${this.idService.parse(note.id).date.getTime()}-*`,
+ 'note', note.id);
+
this.globalEventService.publishAntennaStream(antenna.id, 'note', note);
-
- if (!read) {
- const mutings = await this.mutingsRepository.find({
- where: {
- muterId: antenna.userId,
- },
- select: ['muteeId'],
- });
-
- // Copy
- const _note: Note = {
- ...note,
- };
-
- if (note.replyId != null) {
- _note.reply = await this.notesRepository.findOneByOrFail({ id: note.replyId });
- }
- if (note.renoteId != null) {
- _note.renote = await this.notesRepository.findOneByOrFail({ id: note.renoteId });
- }
-
- if (isUserRelated(_note, new Set<string>(mutings.map(x => x.muteeId)))) {
- return;
- }
-
- // 2秒経っても既読にならなかったら通知
- setTimeout(async () => {
- const unread = await this.antennaNotesRepository.findOneBy({ antennaId: antenna.id, read: false });
- if (unread) {
- this.globalEventService.publishMainStream(antenna.userId, 'unreadAntenna', antenna);
- this.pushNotificationService.pushNotification(antenna.userId, 'unreadAntennaNote', {
- antenna: { id: antenna.id, name: antenna.name },
- note: await this.noteEntityService.pack(note),
- });
- }
- }, 2000);
- }
}
// NOTE: フォローしているユーザーのノート、リストのユーザーのノート、グループのユーザーのノート指定はパフォーマンス上の理由で無効になっている
diff --git a/packages/backend/src/core/IdService.ts b/packages/backend/src/core/IdService.ts
index 31c0819e50..94084ad84f 100644
--- a/packages/backend/src/core/IdService.ts
+++ b/packages/backend/src/core/IdService.ts
@@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { ulid } from 'ulid';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
-import { genAid } from '@/misc/id/aid.js';
+import { genAid, parseAid } from '@/misc/id/aid.js';
import { genMeid } from '@/misc/id/meid.js';
import { genMeidg } from '@/misc/id/meidg.js';
import { genObjectId } from '@/misc/id/object-id.js';
@@ -32,4 +32,17 @@ export class IdService {
default: throw new Error('unrecognized id generation method');
}
}
+
+ @bindThis
+ public parse(id: string): { date: Date; } {
+ switch (this.method) {
+ case 'aid': return parseAid(id);
+ // TODO
+ //case 'meid':
+ //case 'meidg':
+ //case 'ulid':
+ //case 'objectid':
+ default: throw new Error('unrecognized id generation method');
+ }
+ }
}
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 7d08053761..7af7099432 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -1,6 +1,7 @@
import { setImmediate } from 'node:timers/promises';
import * as mfm from 'mfm-js';
import { In, DataSource } from 'typeorm';
+import Redis from 'ioredis';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { extractMentions } from '@/misc/extract-mentions.js';
import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js';
@@ -150,6 +151,9 @@ export class NoteCreateService implements OnApplicationShutdown {
@Inject(DI.db)
private db: DataSource,
+ @Inject(DI.redis)
+ private redisClient: Redis.Redis,
+
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@@ -321,6 +325,14 @@ export class NoteCreateService implements OnApplicationShutdown {
const note = await this.insertNote(user, data, tags, emojis, mentionedUsers);
+ if (data.channel) {
+ this.redisClient.xadd(
+ `channelTimeline:${data.channel.id}`,
+ 'MAXLEN', '~', '1000',
+ `${this.idService.parse(note.id).date.getTime()}-*`,
+ 'note', note.id);
+ }
+
setImmediate('post created', { signal: this.#shutdownController.signal }).then(
() => this.postNoteCreated(note, user, data, silent, tags!, mentionedUsers!),
() => { /* aborted, ignore this */ },
diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts
index 22d72815ec..1bf0eb918f 100644
--- a/packages/backend/src/core/NoteReadService.ts
+++ b/packages/backend/src/core/NoteReadService.ts
@@ -8,7 +8,7 @@ import type { Packed } from '@/misc/json-schema.js';
import type { Note } from '@/models/entities/Note.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
-import type { UsersRepository, NoteUnreadsRepository, MutingsRepository, NoteThreadMutingsRepository, FollowingsRepository, ChannelFollowingsRepository, AntennaNotesRepository } from '@/models/index.js';
+import type { UsersRepository, NoteUnreadsRepository, MutingsRepository, NoteThreadMutingsRepository, FollowingsRepository, ChannelFollowingsRepository } from '@/models/index.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';
import { NotificationService } from './NotificationService.js';
@@ -38,9 +38,6 @@ export class NoteReadService implements OnApplicationShutdown {
@Inject(DI.channelFollowingsRepository)
private channelFollowingsRepository: ChannelFollowingsRepository,
- @Inject(DI.antennaNotesRepository)
- private antennaNotesRepository: AntennaNotesRepository,
-
private userEntityService: UserEntityService,
private idService: IdService,
private globalEventService: GlobalEventService,
@@ -121,7 +118,6 @@ export class NoteReadService implements OnApplicationShutdown {
const readMentions: (Note | Packed<'Note'>)[] = [];
const readSpecifiedNotes: (Note | Packed<'Note'>)[] = [];
const readChannelNotes: (Note | Packed<'Note'>)[] = [];
- const readAntennaNotes: (Note | Packed<'Note'>)[] = [];
for (const note of notes) {
if (note.mentions && note.mentions.includes(userId)) {
@@ -133,14 +129,6 @@ export class NoteReadService implements OnApplicationShutdown {
if (note.channelId && followingChannels.has(note.channelId)) {
readChannelNotes.push(note);
}
-
- if (note.user != null) { // たぶんnullになることは無いはずだけど一応
- for (const antenna of myAntennas) {
- if (await this.antennaService.checkHitAntenna(antenna, note, note.user)) {
- readAntennaNotes.push(note);
- }
- }
- }
}
if ((readMentions.length > 0) || (readSpecifiedNotes.length > 0) || (readChannelNotes.length > 0)) {
@@ -186,35 +174,6 @@ export class NoteReadService implements OnApplicationShutdown {
noteId: In([...readMentions.map(n => n.id), ...readSpecifiedNotes.map(n => n.id)]),
});
}
-
- if (readAntennaNotes.length > 0) {
- await this.antennaNotesRepository.update({
- antennaId: In(myAntennas.map(a => a.id)),
- noteId: In(readAntennaNotes.map(n => n.id)),
- }, {
- read: true,
- });
-
- // TODO: まとめてクエリしたい
- for (const antenna of myAntennas) {
- const count = await this.antennaNotesRepository.countBy({
- antennaId: antenna.id,
- read: false,
- });
-
- if (count === 0) {
- this.globalEventService.publishMainStream(userId, 'readAntenna', antenna);
- this.pushNotificationService.pushNotification(userId, 'readAntenna', { antennaId: antenna.id });
- }
- }
-
- this.userEntityService.getHasUnreadAntenna(userId).then(unread => {
- if (!unread) {
- this.globalEventService.publishMainStream(userId, 'readAllAntennas');
- this.pushNotificationService.pushNotification(userId, 'readAllAntennas', undefined);
- }
- });
- }
}
onApplicationShutdown(signal?: string | undefined): void {
diff --git a/packages/backend/src/core/VideoProcessingService.ts b/packages/backend/src/core/VideoProcessingService.ts
index eccfeb0e7d..5869905db0 100644
--- a/packages/backend/src/core/VideoProcessingService.ts
+++ b/packages/backend/src/core/VideoProcessingService.ts
@@ -37,7 +37,7 @@ export class VideoProcessingService {
});
});
- return await this.imageProcessingService.convertToWebp(`${dir}/out.png`, 498, 280);
+ return await this.imageProcessingService.convertToWebp(`${dir}/out.png`, 498, 422);
} finally {
cleanup();
}
diff --git a/packages/backend/src/core/entities/AntennaEntityService.ts b/packages/backend/src/core/entities/AntennaEntityService.ts
index e02daefd64..328511f5df 100644
--- a/packages/backend/src/core/entities/AntennaEntityService.ts
+++ b/packages/backend/src/core/entities/AntennaEntityService.ts
@@ -1,6 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
-import type { AntennaNotesRepository, AntennasRepository } from '@/models/index.js';
+import type { AntennasRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Antenna } from '@/models/entities/Antenna.js';
import { bindThis } from '@/decorators.js';
@@ -10,9 +10,6 @@ export class AntennaEntityService {
constructor(
@Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository,
-
- @Inject(DI.antennaNotesRepository)
- private antennaNotesRepository: AntennaNotesRepository,
) {
}
@@ -22,8 +19,6 @@ export class AntennaEntityService {
): Promise<Packed<'Antenna'>> {
const antenna = typeof src === 'object' ? src : await this.antennasRepository.findOneByOrFail({ id: src });
- const hasUnreadNote = (await this.antennaNotesRepository.findOneBy({ antennaId: antenna.id, read: false })) != null;
-
return {
id: antenna.id,
createdAt: antenna.createdAt.toISOString(),
@@ -38,7 +33,7 @@ export class AntennaEntityService {
withReplies: antenna.withReplies,
withFile: antenna.withFile,
isActive: antenna.isActive,
- hasUnreadNote,
+ hasUnreadNote: false, // TODO
};
}
}
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index b693883e06..61fd6f2f66 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -12,7 +12,7 @@ import { KVCache } from '@/misc/cache.js';
import type { Instance } from '@/models/entities/Instance.js';
import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js';
import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js';
-import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, NotificationsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, AnnouncementsRepository, AntennaNotesRepository, PagesRepository, UserProfile, RenoteMutingsRepository } from '@/models/index.js';
+import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, NotificationsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, AnnouncementsRepository, PagesRepository, UserProfile, RenoteMutingsRepository } from '@/models/index.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import type { OnModuleInit } from '@nestjs/common';
@@ -108,9 +108,6 @@ export class UserEntityService implements OnModuleInit {
@Inject(DI.announcementsRepository)
private announcementsRepository: AnnouncementsRepository,
- @Inject(DI.antennaNotesRepository)
- private antennaNotesRepository: AntennaNotesRepository,
-
@Inject(DI.pagesRepository)
private pagesRepository: PagesRepository,
@@ -223,6 +220,7 @@ export class UserEntityService implements OnModuleInit {
@bindThis
public async getHasUnreadAntenna(userId: User['id']): Promise<boolean> {
+ /*
const myAntennas = (await this.antennaService.getAntennas()).filter(a => a.userId === userId);
const unread = myAntennas.length > 0 ? await this.antennaNotesRepository.findOneBy({
@@ -231,6 +229,8 @@ export class UserEntityService implements OnModuleInit {
}) : null;
return unread != null;
+ */
+ return false; // TODO
}
@bindThis
diff --git a/packages/backend/src/di-symbols.ts b/packages/backend/src/di-symbols.ts
index 4f475a03ad..f2ab6cb864 100644
--- a/packages/backend/src/di-symbols.ts
+++ b/packages/backend/src/di-symbols.ts
@@ -54,7 +54,6 @@ export const DI = {
clipNotesRepository: Symbol('clipNotesRepository'),
clipFavoritesRepository: Symbol('clipFavoritesRepository'),
antennasRepository: Symbol('antennasRepository'),
- antennaNotesRepository: Symbol('antennaNotesRepository'),
promoNotesRepository: Symbol('promoNotesRepository'),
promoReadsRepository: Symbol('promoReadsRepository'),
relaysRepository: Symbol('relaysRepository'),
diff --git a/packages/backend/src/misc/id/aid.ts b/packages/backend/src/misc/id/aid.ts
index 19c8546f95..93a9929aa7 100644
--- a/packages/backend/src/misc/id/aid.ts
+++ b/packages/backend/src/misc/id/aid.ts
@@ -23,3 +23,8 @@ export function genAid(date: Date): string {
counter++;
return getTime(t) + getNoise();
}
+
+export function parseAid(id: string): { date: Date; } {
+ const time = parseInt(id.slice(0, 8), 36) + TIME2000;
+ return { date: new Date(time) };
+}
diff --git a/packages/backend/src/models/RepositoryModule.ts b/packages/backend/src/models/RepositoryModule.ts
index da7faf9ffb..b74ee3689c 100644
--- a/packages/backend/src/models/RepositoryModule.ts
+++ b/packages/backend/src/models/RepositoryModule.ts
@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
-import { User, Note, Announcement, AnnouncementRead, App, NoteFavorite, NoteThreadMuting, NoteReaction, NoteUnread, Notification, Poll, PollVote, UserProfile, UserKeypair, UserPending, AttestationChallenge, UserSecurityKey, UserPublickey, UserList, UserListJoining, UserNotePining, UserIp, UsedUsername, Following, FollowRequest, Instance, Emoji, DriveFile, DriveFolder, Meta, Muting, RenoteMuting, Blocking, SwSubscription, Hashtag, AbuseUserReport, RegistrationTicket, AuthSession, AccessToken, Signin, Page, PageLike, GalleryPost, GalleryLike, ModerationLog, Clip, ClipNote, Antenna, AntennaNote, PromoNote, PromoRead, Relay, MutedNote, Channel, ChannelFollowing, ChannelFavorite, RegistryItem, Webhook, Ad, PasswordResetRequest, RetentionAggregation, FlashLike, Flash, Role, RoleAssignment, ClipFavorite } from './index.js';
+import { User, Note, Announcement, AnnouncementRead, App, NoteFavorite, NoteThreadMuting, NoteReaction, NoteUnread, Notification, Poll, PollVote, UserProfile, UserKeypair, UserPending, AttestationChallenge, UserSecurityKey, UserPublickey, UserList, UserListJoining, UserNotePining, UserIp, UsedUsername, Following, FollowRequest, Instance, Emoji, DriveFile, DriveFolder, Meta, Muting, RenoteMuting, Blocking, SwSubscription, Hashtag, AbuseUserReport, RegistrationTicket, AuthSession, AccessToken, Signin, Page, PageLike, GalleryPost, GalleryLike, ModerationLog, Clip, ClipNote, Antenna, PromoNote, PromoRead, Relay, MutedNote, Channel, ChannelFollowing, ChannelFavorite, RegistryItem, Webhook, Ad, PasswordResetRequest, RetentionAggregation, FlashLike, Flash, Role, RoleAssignment, ClipFavorite } from './index.js';
import type { DataSource } from 'typeorm';
import type { Provider } from '@nestjs/common';
@@ -298,12 +298,6 @@ const $antennasRepository: Provider = {
inject: [DI.db],
};
-const $antennaNotesRepository: Provider = {
- provide: DI.antennaNotesRepository,
- useFactory: (db: DataSource) => db.getRepository(AntennaNote),
- inject: [DI.db],
-};
-
const $promoNotesRepository: Provider = {
provide: DI.promoNotesRepository,
useFactory: (db: DataSource) => db.getRepository(PromoNote),
@@ -453,7 +447,6 @@ const $roleAssignmentsRepository: Provider = {
$clipNotesRepository,
$clipFavoritesRepository,
$antennasRepository,
- $antennaNotesRepository,
$promoNotesRepository,
$promoReadsRepository,
$relaysRepository,
@@ -521,7 +514,6 @@ const $roleAssignmentsRepository: Provider = {
$clipNotesRepository,
$clipFavoritesRepository,
$antennasRepository,
- $antennaNotesRepository,
$promoNotesRepository,
$promoReadsRepository,
$relaysRepository,
diff --git a/packages/backend/src/models/entities/AntennaNote.ts b/packages/backend/src/models/entities/AntennaNote.ts
deleted file mode 100644
index 5524a89367..0000000000
--- a/packages/backend/src/models/entities/AntennaNote.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm';
-import { id } from '../id.js';
-import { Note } from './Note.js';
-import { Antenna } from './Antenna.js';
-
-@Entity()
-@Index(['noteId', 'antennaId'], { unique: true })
-export class AntennaNote {
- @PrimaryColumn(id())
- public id: string;
-
- @Index()
- @Column({
- ...id(),
- comment: 'The note ID.',
- })
- public noteId: Note['id'];
-
- @ManyToOne(type => Note, {
- onDelete: 'CASCADE',
- })
- @JoinColumn()
- public note: Note | null;
-
- @Index()
- @Column({
- ...id(),
- comment: 'The antenna ID.',
- })
- public antennaId: Antenna['id'];
-
- @ManyToOne(type => Antenna, {
- onDelete: 'CASCADE',
- })
- @JoinColumn()
- public antenna: Antenna | null;
-
- @Index()
- @Column('boolean', {
- default: false,
- })
- public read: boolean;
-}
diff --git a/packages/backend/src/models/index.ts b/packages/backend/src/models/index.ts
index 79bd014cea..c4c9717ed5 100644
--- a/packages/backend/src/models/index.ts
+++ b/packages/backend/src/models/index.ts
@@ -4,7 +4,6 @@ import { Ad } from '@/models/entities/Ad.js';
import { Announcement } from '@/models/entities/Announcement.js';
import { AnnouncementRead } from '@/models/entities/AnnouncementRead.js';
import { Antenna } from '@/models/entities/Antenna.js';
-import { AntennaNote } from '@/models/entities/AntennaNote.js';
import { App } from '@/models/entities/App.js';
import { AttestationChallenge } from '@/models/entities/AttestationChallenge.js';
import { AuthSession } from '@/models/entities/AuthSession.js';
@@ -73,7 +72,6 @@ export {
Announcement,
AnnouncementRead,
Antenna,
- AntennaNote,
App,
AttestationChallenge,
AuthSession,
@@ -141,7 +139,6 @@ export type AdsRepository = Repository<Ad>;
export type AnnouncementsRepository = Repository<Announcement>;
export type AnnouncementReadsRepository = Repository<AnnouncementRead>;
export type AntennasRepository = Repository<Antenna>;
-export type AntennaNotesRepository = Repository<AntennaNote>;
export type AppsRepository = Repository<App>;
export type AttestationChallengesRepository = Repository<AttestationChallenge>;
export type AuthSessionsRepository = Repository<AuthSession>;
diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts
index cbe3814a24..024aa114fc 100644
--- a/packages/backend/src/postgres.ts
+++ b/packages/backend/src/postgres.ts
@@ -12,7 +12,6 @@ import { Ad } from '@/models/entities/Ad.js';
import { Announcement } from '@/models/entities/Announcement.js';
import { AnnouncementRead } from '@/models/entities/AnnouncementRead.js';
import { Antenna } from '@/models/entities/Antenna.js';
-import { AntennaNote } from '@/models/entities/AntennaNote.js';
import { App } from '@/models/entities/App.js';
import { AttestationChallenge } from '@/models/entities/AttestationChallenge.js';
import { AuthSession } from '@/models/entities/AuthSession.js';
@@ -168,7 +167,6 @@ export const entities = [
ClipNote,
ClipFavorite,
Antenna,
- AntennaNote,
PromoNote,
PromoRead,
Relay,
diff --git a/packages/backend/src/queue/processors/CleanProcessorService.ts b/packages/backend/src/queue/processors/CleanProcessorService.ts
index 9534454fd7..3feb86f86f 100644
--- a/packages/backend/src/queue/processors/CleanProcessorService.ts
+++ b/packages/backend/src/queue/processors/CleanProcessorService.ts
@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { In, LessThan } from 'typeorm';
import { DI } from '@/di-symbols.js';
-import type { AntennaNotesRepository, AntennasRepository, MutedNotesRepository, NotificationsRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js';
+import type { AntennasRepository, MutedNotesRepository, NotificationsRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js';
import type { Config } from '@/config.js';
import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';
@@ -29,9 +29,6 @@ export class CleanProcessorService {
@Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository,
- @Inject(DI.antennaNotesRepository)
- private antennaNotesRepository: AntennaNotesRepository,
-
@Inject(DI.roleAssignmentsRepository)
private roleAssignmentsRepository: RoleAssignmentsRepository,
diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts
index 039ba1115a..364f9d9c05 100644
--- a/packages/backend/src/server/api/endpoints/antennas/notes.ts
+++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts
@@ -1,10 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
+import Redis from 'ioredis';
import { Endpoint } from '@/server/api/endpoint-base.js';
-import type { NotesRepository, AntennaNotesRepository, AntennasRepository } from '@/models/index.js';
+import type { NotesRepository, AntennasRepository } from '@/models/index.js';
import { QueryService } from '@/core/QueryService.js';
import { NoteReadService } from '@/core/NoteReadService.js';
import { DI } from '@/di-symbols.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
+import { IdService } from '@/core/IdService.js';
import { ApiError } from '../../error.js';
export const meta = {
@@ -50,15 +52,16 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
+ @Inject(DI.redis)
+ private redisClient: Redis.Redis,
+
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
@Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository,
- @Inject(DI.antennaNotesRepository)
- private antennaNotesRepository: AntennaNotesRepository,
-
+ private idService: IdService,
private noteEntityService: NoteEntityService,
private queryService: QueryService,
private noteReadService: NoteReadService,
@@ -73,9 +76,24 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
throw new ApiError(meta.errors.noSuchAntenna);
}
- const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'),
- ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
- .innerJoin(this.antennaNotesRepository.metadata.targetName, 'antennaNote', 'antennaNote.noteId = note.id')
+ const noteIdsRes = await this.redisClient.xrevrange(
+ `antennaTimeline:${antenna.id}`,
+ ps.untilId ? this.idService.parse(ps.untilId).date.getTime() : '+',
+ '-',
+ 'COUNT', ps.limit + 1); // untilIdに指定したものも含まれるため+1
+
+ if (noteIdsRes.length === 0) {
+ return [];
+ }
+
+ const noteIds = noteIdsRes.map(x => x[1][1]).filter(x => x !== ps.untilId);
+
+ if (noteIds.length === 0) {
+ return [];
+ }
+
+ const query = this.notesRepository.createQueryBuilder('note')
+ .where('note.id IN (:...noteIds)', { noteIds: noteIds })
.innerJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('user.avatar', 'avatar')
.leftJoinAndSelect('user.banner', 'banner')
@@ -86,16 +104,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.leftJoinAndSelect('replyUser.banner', 'replyUserBanner')
.leftJoinAndSelect('renote.user', 'renoteUser')
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
- .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner')
- .andWhere('antennaNote.antennaId = :antennaId', { antennaId: antenna.id });
+ .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
this.queryService.generateVisibilityQuery(query, me);
this.queryService.generateMutedUserQuery(query, me);
this.queryService.generateBlockedUserQuery(query, me);
- const notes = await query
- .take(ps.limit)
- .getMany();
+ const notes = await query.getMany();
+ notes.sort((a, b) => a.id > b.id ? -1 : 1);
if (notes.length > 0) {
this.noteReadService.read(me.id, notes);
diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts
index cdaa400137..eef343d139 100644
--- a/packages/backend/src/server/api/endpoints/channels/timeline.ts
+++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts
@@ -1,10 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
+import Redis from 'ioredis';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { ChannelsRepository, NotesRepository } from '@/models/index.js';
import { QueryService } from '@/core/QueryService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
import { DI } from '@/di-symbols.js';
+import { IdService } from '@/core/IdService.js';
import { ApiError } from '../../error.js';
export const meta = {
@@ -48,12 +50,16 @@ export const paramDef = {
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
+ @Inject(DI.redis)
+ private redisClient: Redis.Redis,
+
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
@Inject(DI.channelsRepository)
private channelsRepository: ChannelsRepository,
+ private idService: IdService,
private noteEntityService: NoteEntityService,
private queryService: QueryService,
private activeUsersChart: ActiveUsersChart,
@@ -67,9 +73,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
throw new ApiError(meta.errors.noSuchChannel);
}
+ const noteIdsRes = await this.redisClient.xrevrange(
+ `channelTimeline:${channel.id}`,
+ ps.untilId ? this.idService.parse(ps.untilId).date.getTime() : '+',
+ '-',
+ 'COUNT', ps.limit + 1); // untilIdに指定したものも含まれるため+1
+
+ if (noteIdsRes.length === 0) {
+ return [];
+ }
+
+ const noteIds = noteIdsRes.map(x => x[1][1]).filter(x => x !== ps.untilId);
+
+ if (noteIds.length === 0) {
+ return [];
+ }
+
//#region Construct query
- const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
- .andWhere('note.channelId = :channelId', { channelId: channel.id })
+ const query = this.notesRepository.createQueryBuilder('note')
+ .where('note.id IN (:...noteIds)', { noteIds: noteIds })
.innerJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('user.avatar', 'avatar')
.leftJoinAndSelect('user.banner', 'banner')
@@ -90,7 +112,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
//#endregion
- const timeline = await query.take(ps.limit).getMany();
+ const timeline = await query.getMany();
+ timeline.sort((a, b) => a.id > b.id ? -1 : 1);
if (me) this.activeUsersChart.read(me);
diff --git a/packages/frontend/@types/vue.d.ts b/packages/frontend/@types/vue.d.ts
deleted file mode 100644
index 9c9c34ccc5..0000000000
--- a/packages/frontend/@types/vue.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/// <reference types="vue/macros-global" />
-
-import type { $i } from '@/account';
-import type { defaultStore } from '@/store';
-import type { instance } from '@/instance';
-import type { i18n } from '@/i18n';
-
-declare module 'vue' {
- interface ComponentCustomProperties {
- $i: typeof $i;
- $store: typeof defaultStore;
- $instance: typeof instance;
- $t: typeof i18n['t'];
- $ts: typeof i18n['ts'];
- }
-}
diff --git a/packages/frontend/src/components/MkContainer.vue b/packages/frontend/src/components/MkContainer.vue
index 833fa9d382..1834224b8d 100644
--- a/packages/frontend/src/components/MkContainer.vue
+++ b/packages/frontend/src/components/MkContainer.vue
@@ -14,10 +14,10 @@
</div>
</header>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_toggle_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_toggle_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_toggle_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_toggle_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_toggle_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_toggle_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_toggle_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_toggle_leaveTo : ''"
@enter="enter"
@after-enter="afterEnter"
@leave="leave"
@@ -26,7 +26,7 @@
<div v-show="showBody" ref="content" :class="[$style.content, { [$style.omitted]: omitted }]">
<slot></slot>
<button v-if="omitted" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
- <span :class="$style.fadeLabel">{{ $ts.showMore }}</span>
+ <span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
</button>
</div>
</Transition>
@@ -35,6 +35,8 @@
<script lang="ts">
import { defineComponent } from 'vue';
+import { defaultStore } from '@/store';
+import { i18n } from '@/i18n';
export default defineComponent({
props: {
@@ -79,6 +81,7 @@ export default defineComponent({
showBody: this.expanded,
omitted: null,
ignoreOmit: false,
+ defaultStore,
};
},
mounted() {
diff --git a/packages/frontend/src/components/MkContextMenu.vue b/packages/frontend/src/components/MkContextMenu.vue
index 21cccaabde..5bdf477241 100644
--- a/packages/frontend/src/components/MkContextMenu.vue
+++ b/packages/frontend/src/components/MkContextMenu.vue
@@ -1,10 +1,10 @@
<template>
<Transition
appear
- :enter-active-class="$store.state.animation ? $style.transition_fade_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_fade_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_fade_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_fade_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_fade_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_fade_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_fade_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_fade_leaveTo : ''"
>
<div ref="rootEl" :class="$style.root" :style="{ zIndex }" @contextmenu.prevent.stop="() => {}">
<MkMenu :items="items" :align="'left'" @close="$emit('closed')"/>
@@ -18,6 +18,7 @@ import MkMenu from './MkMenu.vue';
import { MenuItem } from './types/menu.vue';
import contains from '@/scripts/contains';
import * as os from '@/os';
+import { defaultStore } from '@/store';
const props = defineProps<{
items: MenuItem[];
diff --git a/packages/frontend/src/components/MkDonation.vue b/packages/frontend/src/components/MkDonation.vue
index 9baa90ebfe..b5ae4c6c48 100644
--- a/packages/frontend/src/components/MkDonation.vue
+++ b/packages/frontend/src/components/MkDonation.vue
@@ -14,7 +14,7 @@
<div :class="$style.text">
<I18n :src="i18n.ts.pleaseDonate" tag="span">
<template #host>
- {{ $instance.name ?? host }}
+ {{ instance.name ?? host }}
</template>
</I18n>
<div style="margin-top: 0.2em;">
@@ -37,6 +37,7 @@ import { host } from '@/config';
import { i18n } from '@/i18n';
import * as os from '@/os';
import { miLocalStorage } from '@/local-storage';
+import { instance } from '@/instance';
const emit = defineEmits<{
(ev: 'closed'): void;
diff --git a/packages/frontend/src/components/MkFoldableSection.vue b/packages/frontend/src/components/MkFoldableSection.vue
index d4b1bee9e4..475e01c8d4 100644
--- a/packages/frontend/src/components/MkFoldableSection.vue
+++ b/packages/frontend/src/components/MkFoldableSection.vue
@@ -9,7 +9,7 @@
</button>
</header>
<Transition
- :name="$store.state.animation ? 'folder-toggle' : ''"
+ :name="defaultStore.state.animation ? 'folder-toggle' : ''"
@enter="enter"
@after-enter="afterEnter"
@leave="leave"
@@ -26,6 +26,7 @@
import { defineComponent } from 'vue';
import tinycolor from 'tinycolor2';
import { miLocalStorage } from '@/local-storage';
+import { defaultStore } from '@/store';
const miLocalStoragePrefix = 'ui:folder:' as const;
@@ -44,6 +45,7 @@ export default defineComponent({
},
data() {
return {
+ defaultStore,
bg: null,
showBody: (this.persistKey && miLocalStorage.getItem(`${miLocalStoragePrefix}${this.persistKey}`)) ? (miLocalStorage.getItem(`${miLocalStoragePrefix}${this.persistKey}`) === 't') : this.expanded,
};
diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue
index 2748a9e491..58cc0de5c8 100644
--- a/packages/frontend/src/components/MkFolder.vue
+++ b/packages/frontend/src/components/MkFolder.vue
@@ -22,10 +22,10 @@
<div v-if="openedAtLeastOnce" :class="[$style.body, { [$style.bgSame]: bgSame }]" :style="{ maxHeight: maxHeight ? `${maxHeight}px` : null, overflow: maxHeight ? `auto` : null }">
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_toggle_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_toggle_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_toggle_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_toggle_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_toggle_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_toggle_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_toggle_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_toggle_leaveTo : ''"
@enter="enter"
@after-enter="afterEnter"
@leave="leave"
@@ -46,6 +46,7 @@
<script lang="ts" setup>
import { nextTick, onMounted } from 'vue';
+import { defaultStore } from '@/store';
const props = withDefaults(defineProps<{
defaultOpen?: boolean;
diff --git a/packages/frontend/src/components/MkFormDialog.vue b/packages/frontend/src/components/MkFormDialog.vue
index 971bb806af..979df2e7c1 100644
--- a/packages/frontend/src/components/MkFormDialog.vue
+++ b/packages/frontend/src/components/MkFormDialog.vue
@@ -18,15 +18,15 @@
<div class="_gaps_m">
<template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
<MkInput v-if="form[item].type === 'number'" v-model="values[item]" type="number" :step="form[item].step || 1">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
+ <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
<template v-if="form[item].description" #caption>{{ form[item].description }}</template>
</MkInput>
<MkInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model="values[item]" type="text">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
+ <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
<template v-if="form[item].description" #caption>{{ form[item].description }}</template>
</MkInput>
<MkTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model="values[item]">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
+ <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
<template v-if="form[item].description" #caption>{{ form[item].description }}</template>
</MkTextarea>
<MkSwitch v-else-if="form[item].type === 'boolean'" v-model="values[item]">
@@ -34,15 +34,15 @@
<template v-if="form[item].description" #caption>{{ form[item].description }}</template>
</MkSwitch>
<MkSelect v-else-if="form[item].type === 'enum'" v-model="values[item]">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
+ <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
<option v-for="item in form[item].enum" :key="item.value" :value="item.value">{{ item.label }}</option>
</MkSelect>
<MkRadios v-else-if="form[item].type === 'radio'" v-model="values[item]">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
+ <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
<option v-for="item in form[item].options" :key="item.value" :value="item.value">{{ item.label }}</option>
</MkRadios>
<MkRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].min" :max="form[item].max" :step="form[item].step" :text-converter="form[item].textConverter">
- <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
+ <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ i18n.ts.optional }})</span></template>
<template v-if="form[item].description" #caption>{{ form[item].description }}</template>
</MkRange>
<MkButton v-else-if="form[item].type === 'button'" @click="form[item].action($event, values)">
@@ -64,6 +64,7 @@ import MkRange from './MkRange.vue';
import MkButton from './MkButton.vue';
import MkRadios from './MkRadios.vue';
import MkModalWindow from '@/components/MkModalWindow.vue';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -93,6 +94,7 @@ export default defineComponent({
data() {
return {
values: {},
+ i18n,
};
},
diff --git a/packages/frontend/src/components/MkGoogle.vue b/packages/frontend/src/components/MkGoogle.vue
index 007728176e..227054d963 100644
--- a/packages/frontend/src/components/MkGoogle.vue
+++ b/packages/frontend/src/components/MkGoogle.vue
@@ -1,12 +1,13 @@
<template>
<div :class="$style.root">
<input v-model="query" :class="$style.input" type="search" :placeholder="q">
- <button :class="$style.button" @click="search"><i class="ti ti-search"></i> {{ $ts.searchByGoogle }}</button>
+ <button :class="$style.button" @click="search"><i class="ti ti-search"></i> {{ i18n.ts.searchByGoogle }}</button>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
+import { i18n } from '@/i18n';
const props = defineProps<{
q: string;
diff --git a/packages/frontend/src/components/MkMediaBanner.vue b/packages/frontend/src/components/MkMediaBanner.vue
index c0401a6455..1576144f6b 100644
--- a/packages/frontend/src/components/MkMediaBanner.vue
+++ b/packages/frontend/src/components/MkMediaBanner.vue
@@ -2,8 +2,8 @@
<div class="mk-media-banner">
<div v-if="media.isSensitive && hide" class="sensitive" @click="hide = false">
<span class="icon"><i class="ti ti-alert-triangle"></i></span>
- <b>{{ $ts.sensitive }}</b>
- <span>{{ $ts.clickToShow }}</span>
+ <b>{{ i18n.ts.sensitive }}</b>
+ <span>{{ i18n.ts.clickToShow }}</span>
</div>
<div v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" class="audio">
<VuePlyr :options="{ volume: 0.5 }">
@@ -33,6 +33,7 @@ import * as misskey from 'misskey-js';
import VuePlyr from 'vue-plyr';
import { ColdDeviceStorage } from '@/store';
import 'vue-plyr/dist/vue-plyr.css';
+import { i18n } from '@/i18n';
const props = withDefaults(defineProps<{
media: misskey.entities.DriveFile;
diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue
index 979c3eed28..e02a7af09e 100644
--- a/packages/frontend/src/components/MkMediaVideo.vue
+++ b/packages/frontend/src/components/MkMediaVideo.vue
@@ -1,8 +1,8 @@
<template>
<div v-if="hide" class="icozogqfvdetwohsdglrbswgrejoxbdj" @click="hide = false">
<div>
- <b><i class="ti ti-alert-triangle"></i> {{ $ts.sensitive }}</b>
- <span>{{ $ts.clickToShow }}</span>
+ <b><i class="ti ti-alert-triangle"></i> {{ i18n.ts.sensitive }}</b>
+ <span>{{ i18n.ts.clickToShow }}</span>
</div>
</div>
<div v-else class="kkjnbbplepmiyuadieoenjgutgcmtsvu">
@@ -28,6 +28,7 @@ import * as misskey from 'misskey-js';
import VuePlyr from 'vue-plyr';
import { defaultStore } from '@/store';
import 'vue-plyr/dist/vue-plyr.css';
+import { i18n } from '@/i18n';
const props = defineProps<{
video: misskey.entities.DriveFile;
diff --git a/packages/frontend/src/components/MkMention.vue b/packages/frontend/src/components/MkMention.vue
index f586eeff4d..481c3710ca 100644
--- a/packages/frontend/src/components/MkMention.vue
+++ b/packages/frontend/src/components/MkMention.vue
@@ -3,7 +3,7 @@
<img :class="$style.icon" :src="`/avatar/@${username}@${host}`" alt="">
<span>
<span :class="$style.username">@{{ username }}</span>
- <span v-if="(host != localHost) || $store.state.showFullAcct" :class="$style.host">@{{ toUnicode(host) }}</span>
+ <span v-if="(host != localHost) || defaultStore.state.showFullAcct" :class="$style.host">@{{ toUnicode(host) }}</span>
</span>
</MkA>
</template>
@@ -14,6 +14,7 @@ import { } from 'vue';
import tinycolor from 'tinycolor2';
import { host as localHost } from '@/config';
import { $i } from '@/account';
+import { defaultStore } from '@/store';
const props = defineProps<{
username: string;
diff --git a/packages/frontend/src/components/MkModalPageWindow.vue b/packages/frontend/src/components/MkModalPageWindow.vue
index 68a3eda3d8..b38865f525 100644
--- a/packages/frontend/src/components/MkModalPageWindow.vue
+++ b/packages/frontend/src/components/MkModalPageWindow.vue
@@ -2,7 +2,7 @@
<MkModal ref="modal" @click="$emit('click')" @closed="$emit('closed')">
<div ref="rootEl" class="hrmcaedk" :style="{ width: `${width}px`, height: (height ? `min(${height}px, 100%)` : '100%') }">
<div class="header" @contextmenu="onContextmenu">
- <button v-if="history.length > 0" v-tooltip="$ts.goBack" class="_button" @click="back()"><i class="ti ti-arrow-left"></i></button>
+ <button v-if="history.length > 0" v-tooltip="i18n.ts.goBack" class="_button" @click="back()"><i class="ti ti-arrow-left"></i></button>
<span v-else style="display: inline-block; width: 20px"></span>
<span v-if="pageMetadata?.value" class="title">
<i v-if="pageMetadata?.value.icon" class="icon" :class="pageMetadata?.value.icon"></i>
diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue
index eb9793fcc1..700bbde6f0 100644
--- a/packages/frontend/src/components/MkNote.vue
+++ b/packages/frontend/src/components/MkNote.vue
@@ -57,7 +57,7 @@
<div v-if="translating || translation" :class="$style.translation">
<MkLoading v-if="translating" mini/>
<div v-else :class="$style.translated">
- <b>{{ $t('translatedFrom', { x: translation.sourceLang }) }}: </b>
+ <b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emoji-urls="appearNote.emojis"/>
</div>
</div>
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue
index 715fd3a9a8..67bdfd2258 100644
--- a/packages/frontend/src/components/MkNoteDetailed.vue
+++ b/packages/frontend/src/components/MkNoteDetailed.vue
@@ -70,7 +70,7 @@
<div v-if="translating || translation" class="translation">
<MkLoading v-if="translating" mini/>
<div v-else class="translated">
- <b>{{ $t('translatedFrom', { x: translation.sourceLang }) }}: </b>
+ <b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :emoji-urls="appearNote.emojis"/>
</div>
</div>
diff --git a/packages/frontend/src/components/MkNotePreview.vue b/packages/frontend/src/components/MkNotePreview.vue
index 1cc01386ba..16196834b7 100644
--- a/packages/frontend/src/components/MkNotePreview.vue
+++ b/packages/frontend/src/components/MkNotePreview.vue
@@ -16,6 +16,7 @@
<script lang="ts" setup>
import { } from 'vue';
+import { $i } from '@/account';
const props = defineProps<{
text: string;
diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue
index 2b541e6094..bd27a43b61 100644
--- a/packages/frontend/src/components/MkNoteSimple.vue
+++ b/packages/frontend/src/components/MkNoteSimple.vue
@@ -22,6 +22,7 @@ import * as misskey from 'misskey-js';
import MkNoteHeader from '@/components/MkNoteHeader.vue';
import MkSubNoteContent from '@/components/MkSubNoteContent.vue';
import MkCwButton from '@/components/MkCwButton.vue';
+import { $i } from '@/account';
const props = defineProps<{
note: misskey.entities.Note;
diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue
index ab6d62fba5..c293641355 100644
--- a/packages/frontend/src/components/MkNoteSub.vue
+++ b/packages/frontend/src/components/MkNoteSub.vue
@@ -33,6 +33,7 @@ import MkCwButton from '@/components/MkCwButton.vue';
import { notePage } from '@/filters/note';
import * as os from '@/os';
import { i18n } from '@/i18n';
+import { $i } from '@/account';
const props = withDefaults(defineProps<{
note: misskey.entities.Note;
diff --git a/packages/frontend/src/components/MkOmit.vue b/packages/frontend/src/components/MkOmit.vue
index a806d92b22..9232ebb7c9 100644
--- a/packages/frontend/src/components/MkOmit.vue
+++ b/packages/frontend/src/components/MkOmit.vue
@@ -2,13 +2,14 @@
<div ref="content" :class="[$style.content, { [$style.omitted]: omitted }]">
<slot></slot>
<button v-if="omitted" :class="$style.fade" class="_button" @click="() => { ignoreOmit = true; omitted = false; }">
- <span :class="$style.fadeLabel">{{ $ts.showMore }}</span>
+ <span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
</button>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
+import { i18n } from '@/i18n';
const props = withDefaults(defineProps<{
maxHeight: number;
diff --git a/packages/frontend/src/components/MkPagination.vue b/packages/frontend/src/components/MkPagination.vue
index a1a61a6fd6..cd8af560e4 100644
--- a/packages/frontend/src/components/MkPagination.vue
+++ b/packages/frontend/src/components/MkPagination.vue
@@ -1,9 +1,9 @@
<template>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_fade_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_fade_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_fade_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_fade_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_fade_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_fade_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_fade_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_fade_leaveTo : ''"
mode="out-in"
>
<MkLoading v-if="fetching"/>
@@ -163,21 +163,22 @@ async function init(): Promise<void> {
const params = props.pagination.params ? isRef(props.pagination.params) ? props.pagination.params.value : props.pagination.params : {};
await os.api(props.pagination.endpoint, {
...params,
- limit: props.pagination.noPaging ? (props.pagination.limit || 10) : (props.pagination.limit || 10) + 1,
+ limit: props.pagination.limit ?? 10,
}).then(res => {
for (let i = 0; i < res.length; i++) {
const item = res[i];
if (i === 3) item._shouldInsertAd_ = true;
}
- if (!props.pagination.noPaging && (res.length > (props.pagination.limit || 10))) {
- res.pop();
- if (props.pagination.reversed) moreFetching.value = true;
+
+ if (res.length === 0 || props.pagination.noPaging) {
items.value = res;
- more.value = true;
+ more.value = false;
} else {
+ if (props.pagination.reversed) moreFetching.value = true;
items.value = res;
- more.value = false;
+ more.value = true;
}
+
offset.value = res.length;
error.value = false;
fetching.value = false;
@@ -198,7 +199,7 @@ const fetchMore = async (): Promise<void> => {
const params = props.pagination.params ? isRef(props.pagination.params) ? props.pagination.params.value : props.pagination.params : {};
await os.api(props.pagination.endpoint, {
...params,
- limit: SECOND_FETCH_LIMIT + 1,
+ limit: SECOND_FETCH_LIMIT,
...(props.pagination.offsetMode ? {
offset: offset.value,
} : {
@@ -227,28 +228,26 @@ const fetchMore = async (): Promise<void> => {
});
};
- if (res.length > SECOND_FETCH_LIMIT) {
- res.pop();
-
+ if (res.length === 0) {
if (props.pagination.reversed) {
reverseConcat(res).then(() => {
- more.value = true;
+ more.value = false;
moreFetching.value = false;
});
} else {
items.value = items.value.concat(res);
- more.value = true;
+ more.value = false;
moreFetching.value = false;
}
} else {
if (props.pagination.reversed) {
reverseConcat(res).then(() => {
- more.value = false;
+ more.value = true;
moreFetching.value = false;
});
} else {
items.value = items.value.concat(res);
- more.value = false;
+ more.value = true;
moreFetching.value = false;
}
}
@@ -264,20 +263,19 @@ const fetchMoreAhead = async (): Promise<void> => {
const params = props.pagination.params ? isRef(props.pagination.params) ? props.pagination.params.value : props.pagination.params : {};
await os.api(props.pagination.endpoint, {
...params,
- limit: SECOND_FETCH_LIMIT + 1,
+ limit: SECOND_FETCH_LIMIT,
...(props.pagination.offsetMode ? {
offset: offset.value,
} : {
sinceId: items.value[items.value.length - 1].id,
}),
}).then(res => {
- if (res.length > SECOND_FETCH_LIMIT) {
- res.pop();
+ if (res.length === 0) {
items.value = items.value.concat(res);
- more.value = true;
+ more.value = false;
} else {
items.value = items.value.concat(res);
- more.value = false;
+ more.value = true;
}
offset.value += res.length;
moreFetching.value = false;
diff --git a/packages/frontend/src/components/MkPoll.vue b/packages/frontend/src/components/MkPoll.vue
index fcbd8ad351..0810061ff9 100644
--- a/packages/frontend/src/components/MkPoll.vue
+++ b/packages/frontend/src/components/MkPoll.vue
@@ -6,12 +6,12 @@
<span>
<template v-if="choice.isVoted"><i class="ti ti-check"></i></template>
<Mfm :text="choice.text" :plain="true"/>
- <span v-if="showResult" class="votes">({{ $t('_poll.votesCount', { n: choice.votes }) }})</span>
+ <span v-if="showResult" class="votes">({{ i18n.t('_poll.votesCount', { n: choice.votes }) }})</span>
</span>
</li>
</ul>
<p v-if="!readOnly">
- <span>{{ $t('_poll.totalVotes', { n: total }) }}</span>
+ <span>{{ i18n.t('_poll.totalVotes', { n: total }) }}</span>
<span> · </span>
<a v-if="!closed && !isVoted" @click="showResult = !showResult">{{ showResult ? i18n.ts._poll.vote : i18n.ts._poll.showResult }}</a>
<span v-if="isVoted">{{ i18n.ts._poll.voted }}</span>
diff --git a/packages/frontend/src/components/MkPollEditor.vue b/packages/frontend/src/components/MkPollEditor.vue
index 9567c58b99..471ec39169 100644
--- a/packages/frontend/src/components/MkPollEditor.vue
+++ b/packages/frontend/src/components/MkPollEditor.vue
@@ -5,7 +5,7 @@
</p>
<ul>
<li v-for="(choice, i) in choices" :key="i">
- <MkInput class="input" small :model-value="choice" :placeholder="$t('_poll.choiceN', { n: i + 1 })" @update:model-value="onInput(i, $event)">
+ <MkInput class="input" small :model-value="choice" :placeholder="i18n.t('_poll.choiceN', { n: i + 1 })" @update:model-value="onInput(i, $event)">
</MkInput>
<button class="_button" @click="remove(i)">
<i class="ti ti-x"></i>
diff --git a/packages/frontend/src/components/MkReactionsViewer.vue b/packages/frontend/src/components/MkReactionsViewer.vue
index 76faffe926..3219c8a92c 100644
--- a/packages/frontend/src/components/MkReactionsViewer.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.vue
@@ -1,27 +1,28 @@
<template>
<TransitionGroup
- :enter-active-class="$store.state.animation ? $style.transition_x_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_x_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_x_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_x_leaveTo : ''"
- :move-class="$store.state.animation ? $style.transition_x_move : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_x_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_x_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_x_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_x_leaveTo : ''"
+ :move-class="defaultStore.state.animation ? $style.transition_x_move : ''"
tag="div" :class="$style.root"
>
<XReaction v-for="[reaction, count] in reactions" :key="reaction" :reaction="reaction" :count="count" :is-initial="initialReactions.has(reaction)" :note="note"/>
- <slot v-if="hasMoreReactions" name="more" />
+ <slot v-if="hasMoreReactions" name="more"/>
</TransitionGroup>
</template>
<script lang="ts" setup>
import * as misskey from 'misskey-js';
-import XReaction from '@/components/MkReactionsViewer.reaction.vue';
import { watch } from 'vue';
+import XReaction from '@/components/MkReactionsViewer.reaction.vue';
+import { defaultStore } from '@/store';
const props = withDefaults(defineProps<{
- note: misskey.entities.Note;
- maxNumber?: number;
+ note: misskey.entities.Note;
+ maxNumber?: number;
}>(), {
- maxNumber: Infinity,
+ maxNumber: Infinity,
});
const initialReactions = new Set(Object.keys(props.note.reactions));
diff --git a/packages/frontend/src/components/MkSample.vue b/packages/frontend/src/components/MkSample.vue
index 8b7fc2ef76..7a3bc20888 100644
--- a/packages/frontend/src/components/MkSample.vue
+++ b/packages/frontend/src/components/MkSample.vue
@@ -36,6 +36,7 @@ import MkTextarea from '@/components/MkTextarea.vue';
import MkRadio from '@/components/MkRadio.vue';
import * as os from '@/os';
import * as config from '@/config';
+import { $i } from '@/account';
export default defineComponent({
components: {
@@ -51,6 +52,7 @@ export default defineComponent({
text: '',
flag: true,
radio: 'misskey',
+ $i,
mfm: `Hello world! This is an @example mention. BTW you are @${this.$i ? this.$i.username : 'guest'}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`,
};
},
diff --git a/packages/frontend/src/components/MkSubNoteContent.vue b/packages/frontend/src/components/MkSubNoteContent.vue
index 9f90f5eecb..1ac7107aa7 100644
--- a/packages/frontend/src/components/MkSubNoteContent.vue
+++ b/packages/frontend/src/components/MkSubNoteContent.vue
@@ -8,7 +8,7 @@
<MkA v-if="note.renoteId" :class="$style.rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
</div>
<details v-if="note.files.length > 0">
- <summary>({{ $t('withNFiles', { n: note.files.length }) }})</summary>
+ <summary>({{ i18n.t('withNFiles', { n: note.files.length }) }})</summary>
<MkMediaList :media-list="note.files"/>
</details>
<details v-if="note.poll">
@@ -27,6 +27,7 @@ import * as misskey from 'misskey-js';
import MkMediaList from '@/components/MkMediaList.vue';
import MkPoll from '@/components/MkPoll.vue';
import { i18n } from '@/i18n';
+import { $i } from '@/account';
const props = defineProps<{
note: misskey.entities.Note;
diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue
index 87f7c61a92..6741e7a18b 100644
--- a/packages/frontend/src/components/MkTimeline.vue
+++ b/packages/frontend/src/components/MkTimeline.vue
@@ -1,5 +1,5 @@
<template>
-<MkNotes ref="tlComponent" :no-gap="!$store.state.showGapBetweenNotesInTimeline" :pagination="pagination" @queue="emit('queue', $event)"/>
+<MkNotes ref="tlComponent" :no-gap="!defaultStore.state.showGapBetweenNotesInTimeline" :pagination="pagination" @queue="emit('queue', $event)"/>
</template>
<script lang="ts" setup>
@@ -8,6 +8,7 @@ import MkNotes from '@/components/MkNotes.vue';
import { stream } from '@/stream';
import * as sound from '@/scripts/sound';
import { $i } from '@/account';
+import { defaultStore } from '@/store';
const props = defineProps<{
src: string;
diff --git a/packages/frontend/src/components/MkToast.vue b/packages/frontend/src/components/MkToast.vue
index 6d59702569..ad53c7f289 100644
--- a/packages/frontend/src/components/MkToast.vue
+++ b/packages/frontend/src/components/MkToast.vue
@@ -1,10 +1,10 @@
<template>
<div>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_toast_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_toast_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_toast_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_toast_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_toast_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_toast_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_toast_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_toast_leaveTo : ''"
appear @after-leave="emit('closed')"
>
<div v-if="showing" class="_acrylic" :class="$style.root" :style="{ zIndex }">
@@ -19,6 +19,7 @@
<script lang="ts" setup>
import { onMounted } from 'vue';
import * as os from '@/os';
+import { defaultStore } from '@/store';
defineProps<{
message: string;
diff --git a/packages/frontend/src/components/MkTokenGenerateWindow.vue b/packages/frontend/src/components/MkTokenGenerateWindow.vue
index 6035c20d23..56be044405 100644
--- a/packages/frontend/src/components/MkTokenGenerateWindow.vue
+++ b/packages/frontend/src/components/MkTokenGenerateWindow.vue
@@ -10,7 +10,7 @@
@closed="$emit('closed')"
@ok="ok()"
>
- <template #header>{{ title || $ts.generateAccessToken }}</template>
+ <template #header>{{ title || i18n.ts.generateAccessToken }}</template>
<MkSpacer :margin-min="20" :margin-max="28">
<div class="_gaps_m">
@@ -19,15 +19,15 @@
</div>
<div>
<MkInput v-model="name">
- <template #label>{{ $ts.name }}</template>
+ <template #label>{{ i18n.ts.name }}</template>
</MkInput>
</div>
- <div><b>{{ $ts.permission }}</b></div>
+ <div><b>{{ i18n.ts.permission }}</b></div>
<div class="_buttons">
<MkButton inline @click="disableAll">{{ i18n.ts.disableAll }}</MkButton>
<MkButton inline @click="enableAll">{{ i18n.ts.enableAll }}</MkButton>
</div>
- <MkSwitch v-for="kind in (initialPermissions || kinds)" :key="kind" v-model="permissions[kind]">{{ $t(`_permissions.${kind}`) }}</MkSwitch>
+ <MkSwitch v-for="kind in (initialPermissions || kinds)" :key="kind" v-model="permissions[kind]">{{ i18n.t(`_permissions.${kind}`) }}</MkSwitch>
</div>
</MkSpacer>
</MkModalWindow>
diff --git a/packages/frontend/src/components/MkTooltip.vue b/packages/frontend/src/components/MkTooltip.vue
index 0b0556de39..2d34b090ed 100644
--- a/packages/frontend/src/components/MkTooltip.vue
+++ b/packages/frontend/src/components/MkTooltip.vue
@@ -1,9 +1,9 @@
<template>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_tooltip_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_tooltip_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_tooltip_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_tooltip_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_tooltip_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_tooltip_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_tooltip_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_tooltip_leaveTo : ''"
appear @after-leave="emit('closed')"
>
<div v-show="showing" ref="el" :class="$style.root" class="_acrylic _shadow" :style="{ zIndex, maxWidth: maxWidth + 'px' }">
@@ -19,6 +19,7 @@
import { nextTick, onMounted, onUnmounted, shallowRef } from 'vue';
import * as os from '@/os';
import { calcPopupPosition } from '@/scripts/popup-position';
+import { defaultStore } from '@/store';
const props = withDefaults(defineProps<{
showing: boolean;
diff --git a/packages/frontend/src/components/MkUrlPreview.vue b/packages/frontend/src/components/MkUrlPreview.vue
index 094709e093..635ac3e8bd 100644
--- a/packages/frontend/src/components/MkUrlPreview.vue
+++ b/packages/frontend/src/components/MkUrlPreview.vue
@@ -23,7 +23,7 @@
</template>
<template v-else-if="tweetId && tweetExpanded">
<div ref="twitter" :class="$style.twitter">
- <iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&amp;hideCard=false&amp;hideThread=false&amp;lang=en&amp;theme=${$store.state.darkMode ? 'dark' : 'light'}&amp;id=${tweetId}`"></iframe>
+ <iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&amp;hideCard=false&amp;hideThread=false&amp;lang=en&amp;theme=${defaultStore.state.darkMode ? 'dark' : 'light'}&amp;id=${tweetId}`"></iframe>
</div>
<div :class="$style.action">
<MkButton :small="true" inline @click="tweetExpanded = false">
@@ -77,6 +77,7 @@ import * as os from '@/os';
import { deviceKind } from '@/scripts/device-kind';
import MkButton from '@/components/MkButton.vue';
import { versatileLang } from '@/scripts/intl-const';
+import { defaultStore } from '@/store';
type SummalyResult = Awaited<ReturnType<typeof summaly>>;
diff --git a/packages/frontend/src/components/MkUrlPreviewPopup.vue b/packages/frontend/src/components/MkUrlPreviewPopup.vue
index a0ad3c7fdd..e244be3e96 100644
--- a/packages/frontend/src/components/MkUrlPreviewPopup.vue
+++ b/packages/frontend/src/components/MkUrlPreviewPopup.vue
@@ -1,6 +1,6 @@
<template>
<div class="fgmtyycl" :style="{ zIndex, top: top + 'px', left: left + 'px' }">
- <Transition :name="$store.state.animation ? '_transition_zoom' : ''" @after-leave="emit('closed')">
+ <Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" @after-leave="emit('closed')">
<MkUrlPreview v-if="showing" class="_popup _shadow" :url="url"/>
</Transition>
</div>
@@ -10,6 +10,7 @@
import { onMounted } from 'vue';
import MkUrlPreview from '@/components/MkUrlPreview.vue';
import * as os from '@/os';
+import { defaultStore } from '@/store';
const props = defineProps<{
showing: boolean;
diff --git a/packages/frontend/src/components/MkUserInfo.vue b/packages/frontend/src/components/MkUserInfo.vue
index 1486423b3d..5086c1b319 100644
--- a/packages/frontend/src/components/MkUserInfo.vue
+++ b/packages/frontend/src/components/MkUserInfo.vue
@@ -6,7 +6,7 @@
<MkA class="name" :to="userPage(user)"><MkUserName :user="user" :nowrap="false"/></MkA>
<p class="username"><MkAcct :user="user"/></p>
</div>
- <span v-if="$i && $i.id !== user.id && user.isFollowed" class="followed">{{ $ts.followsYou }}</span>
+ <span v-if="$i && $i.id !== user.id && user.isFollowed" class="followed">{{ i18n.ts.followsYou }}</span>
<div class="description">
<div v-if="user.description" class="mfm">
<Mfm :text="user.description" :author="user" :i="$i"/>
@@ -33,6 +33,7 @@ import * as misskey from 'misskey-js';
import MkFollowButton from '@/components/MkFollowButton.vue';
import { userPage } from '@/filters/user';
import { i18n } from '@/i18n';
+import { $i } from '@/account';
defineProps<{
user: misskey.entities.UserDetailed;
diff --git a/packages/frontend/src/components/MkUserPopup.vue b/packages/frontend/src/components/MkUserPopup.vue
index 93e914f6dd..8ca0355448 100644
--- a/packages/frontend/src/components/MkUserPopup.vue
+++ b/packages/frontend/src/components/MkUserPopup.vue
@@ -1,15 +1,15 @@
<template>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_popup_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_popup_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_popup_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_popup_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_popup_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_popup_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_popup_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_popup_leaveTo : ''"
appear @after-leave="emit('closed')"
>
<div v-if="showing" :class="$style.root" class="_popup _shadow" :style="{ zIndex, top: top + 'px', left: left + 'px' }" @mouseover="() => { emit('mouseover'); }" @mouseleave="() => { emit('mouseleave'); }">
<div v-if="user != null">
<div :class="$style.banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''">
- <span v-if="$i && $i.id != user.id && user.isFollowed" :class="$style.followed">{{ $ts.followsYou }}</span>
+ <span v-if="$i && $i.id != user.id && user.isFollowed" :class="$style.followed">{{ i18n.ts.followsYou }}</span>
</div>
<svg viewBox="0 0 128 128" :class="$style.avatarBack">
<g transform="matrix(1.6,0,0,1.6,-38.4,-51.2)">
@@ -27,15 +27,15 @@
</div>
<div :class="$style.status">
<div :class="$style.statusItem">
- <div :class="$style.statusItemLabel">{{ $ts.notes }}</div>
+ <div :class="$style.statusItemLabel">{{ i18n.ts.notes }}</div>
<div>{{ number(user.notesCount) }}</div>
</div>
<div :class="$style.statusItem">
- <div :class="$style.statusItemLabel">{{ $ts.following }}</div>
+ <div :class="$style.statusItemLabel">{{ i18n.ts.following }}</div>
<div>{{ number(user.followingCount) }}</div>
</div>
<div :class="$style.statusItem">
- <div :class="$style.statusItemLabel">{{ $ts.followers }}</div>
+ <div :class="$style.statusItemLabel">{{ i18n.ts.followers }}</div>
<div>{{ number(user.followersCount) }}</div>
</div>
</div>
@@ -59,6 +59,8 @@ import * as os from '@/os';
import { getUserMenu } from '@/scripts/get-user-menu';
import number from '@/filters/number';
import { i18n } from '@/i18n';
+import { defaultStore } from '@/store';
+import { $i } from '@/account';
const props = defineProps<{
showing: boolean;
diff --git a/packages/frontend/src/components/MkWindow.vue b/packages/frontend/src/components/MkWindow.vue
index e7ad2b9a43..30b5391e9a 100644
--- a/packages/frontend/src/components/MkWindow.vue
+++ b/packages/frontend/src/components/MkWindow.vue
@@ -1,9 +1,9 @@
<template>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_window_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_window_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_window_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_window_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_window_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_window_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_window_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_window_leaveTo : ''"
appear
@after-leave="$emit('closed')"
>
@@ -47,6 +47,7 @@ import contains from '@/scripts/contains';
import * as os from '@/os';
import { MenuItem } from '@/types/menu';
import { i18n } from '@/i18n';
+import { defaultStore } from '@/store';
const minHeight = 50;
const minWidth = 250;
diff --git a/packages/frontend/src/components/MkYoutubePlayer.vue b/packages/frontend/src/components/MkYoutubePlayer.vue
index 460b038838..4d765fe2f7 100644
--- a/packages/frontend/src/components/MkYoutubePlayer.vue
+++ b/packages/frontend/src/components/MkYoutubePlayer.vue
@@ -6,7 +6,7 @@
</template>
<div class="poamfof">
- <Transition :name="$store.state.animation ? 'fade' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="player.url && (player.url.startsWith('http://') || player.url.startsWith('https://'))" class="player">
<iframe v-if="!fetching" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
</div>
@@ -21,6 +21,7 @@
<script lang="ts" setup>
import MkWindow from '@/components/MkWindow.vue';
import { versatileLang } from '@/scripts/intl-const';
+import { defaultStore } from '@/store';
const props = defineProps<{
url: string;
diff --git a/packages/frontend/src/components/form/suspense.vue b/packages/frontend/src/components/form/suspense.vue
index 936e12aa7b..3a44c3da3d 100644
--- a/packages/frontend/src/components/form/suspense.vue
+++ b/packages/frontend/src/components/form/suspense.vue
@@ -1,5 +1,5 @@
<template>
-<Transition :name="$store.state.animation ? 'fade' : ''" mode="out-in">
+<Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="pending">
<MkLoading/>
</div>
@@ -8,8 +8,8 @@
</div>
<div v-else>
<div class="wszdbhzo">
- <div><i class="ti ti-alert-triangle"></i> {{ $ts.somethingHappened }}</div>
- <MkButton inline class="retry" @click="retry"><i class="ti ti-reload"></i> {{ $ts.retry }}</MkButton>
+ <div><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</div>
+ <MkButton inline class="retry" @click="retry"><i class="ti ti-reload"></i> {{ i18n.ts.retry }}</MkButton>
</div>
</div>
</Transition>
@@ -18,6 +18,8 @@
<script lang="ts">
import { defineComponent, PropType, ref, watch } from 'vue';
import MkButton from '@/components/MkButton.vue';
+import { defaultStore } from '@/store';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -72,6 +74,8 @@ export default defineComponent({
rejected,
result,
retry,
+ defaultStore,
+ i18n,
};
},
});
diff --git a/packages/frontend/src/components/global/MkAcct.vue b/packages/frontend/src/components/global/MkAcct.vue
index 2a43ded9e1..e06ab64e86 100644
--- a/packages/frontend/src/components/global/MkAcct.vue
+++ b/packages/frontend/src/components/global/MkAcct.vue
@@ -1,7 +1,7 @@
<template>
<span>
<span>@{{ user.username }}</span>
- <span v-if="user.host || detail || $store.state.showFullAcct" style="opacity: 0.5;">@{{ user.host || host }}</span>
+ <span v-if="user.host || detail || defaultStore.state.showFullAcct" style="opacity: 0.5;">@{{ user.host || host }}</span>
</span>
</template>
@@ -9,6 +9,7 @@
import * as misskey from 'misskey-js';
import { toUnicode } from 'punycode/';
import { host as hostRaw } from '@/config';
+import { defaultStore } from '@/store';
defineProps<{
user: misskey.entities.UserDetailed;
diff --git a/packages/frontend/src/components/global/MkAd.vue b/packages/frontend/src/components/global/MkAd.vue
index e0304c8bc5..b8f749bd1c 100644
--- a/packages/frontend/src/components/global/MkAd.vue
+++ b/packages/frontend/src/components/global/MkAd.vue
@@ -9,9 +9,9 @@
<div v-else :class="$style.menu">
<div :class="$style.menuContainer">
<div>Ads by {{ host }}</div>
- <!--<MkButton class="button" primary>{{ $ts._ad.like }}</MkButton>-->
- <MkButton v-if="chosen.ratio !== 0" :class="$style.menuButton" @click="reduceFrequency">{{ $ts._ad.reduceFrequencyOfThisAd }}</MkButton>
- <button class="_textButton" @click="toggleMenu">{{ $ts._ad.back }}</button>
+ <!--<MkButton class="button" primary>{{ i18n.ts._ad.like }}</MkButton>-->
+ <MkButton v-if="chosen.ratio !== 0" :class="$style.menuButton" @click="reduceFrequency">{{ i18n.ts._ad.reduceFrequencyOfThisAd }}</MkButton>
+ <button class="_textButton" @click="toggleMenu">{{ i18n.ts._ad.back }}</button>
</div>
</div>
</div>
@@ -26,6 +26,7 @@ import MkButton from '@/components/MkButton.vue';
import { defaultStore } from '@/store';
import * as os from '@/os';
import { $i } from '@/account';
+import { i18n } from '@/i18n';
type Ad = (typeof instance)['ads'][number];
diff --git a/packages/frontend/src/components/global/MkError.vue b/packages/frontend/src/components/global/MkError.vue
index 7390a9dfb9..513ef21d35 100644
--- a/packages/frontend/src/components/global/MkError.vue
+++ b/packages/frontend/src/components/global/MkError.vue
@@ -1,5 +1,5 @@
<template>
-<Transition :name="$store.state.animation ? '_transition_zoom' : ''" appear>
+<Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" appear>
<div :class="$style.root">
<img :class="$style.img" src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
<p :class="$style.text"><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
@@ -11,6 +11,7 @@
<script lang="ts" setup>
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n';
+import { defaultStore } from '@/store';
const emit = defineEmits<{
(ev: 'retry'): void;
diff --git a/packages/frontend/src/components/page/page.post.vue b/packages/frontend/src/components/page/page.post.vue
index 6de0a78694..55da610cb6 100644
--- a/packages/frontend/src/components/page/page.post.vue
+++ b/packages/frontend/src/components/page/page.post.vue
@@ -16,6 +16,8 @@ import { apiUrl } from '@/config';
import * as os from '@/os';
import { PostBlock } from '@/scripts/hpml/block';
import { Hpml } from '@/scripts/hpml/evaluator';
+import { defaultStore } from '@/store';
+import { $i } from '@/account';
export default defineComponent({
components: {
@@ -54,9 +56,9 @@ export default defineComponent({
canvas.toBlob(blob => {
const formData = new FormData();
formData.append('file', blob);
- formData.append('i', this.$i.token);
- if (this.$store.state.uploadFolder) {
- formData.append('folderId', this.$store.state.uploadFolder);
+ formData.append('i', $i.token);
+ if (defaultStore.state.uploadFolder) {
+ formData.append('folderId', defaultStore.state.uploadFolder);
}
window.fetch(apiUrl + '/drive/files/create', {
diff --git a/packages/frontend/src/components/page/page.text.vue b/packages/frontend/src/components/page/page.text.vue
index 689c484521..e0e4959efa 100644
--- a/packages/frontend/src/components/page/page.text.vue
+++ b/packages/frontend/src/components/page/page.text.vue
@@ -6,11 +6,12 @@
</template>
<script lang="ts">
-import { TextBlock } from '@/scripts/hpml/block';
-import { Hpml } from '@/scripts/hpml/evaluator';
import { defineAsyncComponent, defineComponent, PropType } from 'vue';
import * as mfm from 'mfm-js';
+import { TextBlock } from '@/scripts/hpml/block';
+import { Hpml } from '@/scripts/hpml/evaluator';
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm';
+import { $i } from '@/account';
export default defineComponent({
components: {
@@ -29,6 +30,7 @@ export default defineComponent({
data() {
return {
text: this.hpml.interpolate(this.block.text),
+ $i,
};
},
computed: {
diff --git a/packages/frontend/src/init.ts b/packages/frontend/src/init.ts
index a2dff87e8e..26c5adfc70 100644
--- a/packages/frontend/src/init.ts
+++ b/packages/frontend/src/init.ts
@@ -198,15 +198,6 @@ if (_DEV_) {
app.config.performance = true;
}
-// TODO: 廃止
-app.config.globalProperties = {
- $i,
- $store: defaultStore,
- $instance: instance,
- $t: i18n.t,
- $ts: i18n.ts,
-};
-
widgets(app);
directives(app);
components(app);
@@ -356,7 +347,7 @@ const hotkeys = {
},
's': (): void => {
mainRouter.push('/search');
- }
+ },
};
if ($i) {
diff --git a/packages/frontend/src/pages/_error_.vue b/packages/frontend/src/pages/_error_.vue
index 5001b5a8b4..f53fec7d94 100644
--- a/packages/frontend/src/pages/_error_.vue
+++ b/packages/frontend/src/pages/_error_.vue
@@ -1,6 +1,6 @@
<template>
<MkLoading v-if="!loaded"/>
-<Transition :name="$store.state.animation ? '_transition_zoom' : ''" appear>
+<Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" appear>
<div v-show="loaded" class="mjndxjch">
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
<p><b><i class="ti ti-alert-triangle"></i> {{ i18n.ts.pageLoadError }}</b></p>
@@ -27,6 +27,7 @@ import { unisonReload } from '@/scripts/unison-reload';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
import { miLocalStorage } from '@/local-storage';
+import { defaultStore } from '@/store';
const props = withDefaults(defineProps<{
error?: Error;
diff --git a/packages/frontend/src/pages/about.emojis.vue b/packages/frontend/src/pages/about.emojis.vue
index 7f3b4fd937..d461430234 100644
--- a/packages/frontend/src/pages/about.emojis.vue
+++ b/packages/frontend/src/pages/about.emojis.vue
@@ -3,7 +3,7 @@
<MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary link to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton>
<div class="query">
- <MkInput v-model="q" class="" :placeholder="$ts.search">
+ <MkInput v-model="q" class="" :placeholder="i18n.ts.search">
<template #prefix><i class="ti ti-search"></i></template>
</MkInput>
@@ -15,14 +15,14 @@
</div>
<MkFoldableSection v-if="searchEmojis" class="emojis">
- <template #header>{{ $ts.searchResult }}</template>
+ <template #header>{{ i18n.ts.searchResult }}</template>
<div class="zuvgdzyt">
<XEmoji v-for="emoji in searchEmojis" :key="emoji.name" class="emoji" :emoji="emoji"/>
</div>
</MkFoldableSection>
<MkFoldableSection v-for="category in customEmojiCategories" v-once :key="category" class="emojis">
- <template #header>{{ category || $ts.other }}</template>
+ <template #header>{{ category || i18n.ts.other }}</template>
<div class="zuvgdzyt">
<XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" class="emoji" :emoji="emoji"/>
</div>
@@ -32,13 +32,14 @@
<script lang="ts" setup>
import { watch } from 'vue';
+import * as Misskey from 'misskey-js';
import XEmoji from './emojis.emoji.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
import MkFoldableSection from '@/components/MkFoldableSection.vue';
import { customEmojis, customEmojiCategories, getCustomEmojiTags } from '@/custom-emojis';
import { i18n } from '@/i18n';
-import * as Misskey from 'misskey-js';
+import { $i } from '@/account';
const customEmojiTags = getCustomEmojiTags();
let q = $ref('');
diff --git a/packages/frontend/src/pages/about.vue b/packages/frontend/src/pages/about.vue
index be0c1828a3..d54d93eaee 100644
--- a/packages/frontend/src/pages/about.vue
+++ b/packages/frontend/src/pages/about.vue
@@ -3,18 +3,18 @@
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer v-if="tab === 'overview'" :content-max="600" :margin-min="20">
<div class="_gaps_m">
- <div class="fwhjspax" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }">
+ <div class="fwhjspax" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }">
<div class="content">
- <img :src="$instance.iconUrl ?? $instance.faviconUrl ?? '/favicon.ico'" alt="" class="icon"/>
+ <img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" alt="" class="icon"/>
<div class="name">
- <b>{{ $instance.name ?? host }}</b>
+ <b>{{ instance.name ?? host }}</b>
</div>
</div>
</div>
<MkKeyValue>
<template #key>{{ i18n.ts.description }}</template>
- <template #value><div v-html="$instance.description"></div></template>
+ <template #value><div v-html="instance.description"></div></template>
</MkKeyValue>
<FormSection>
@@ -23,7 +23,7 @@
<template #key>Misskey</template>
<template #value>{{ version }}</template>
</MkKeyValue>
- <div v-html="i18n.t('poweredByMisskeyDescription', { name: $instance.name ?? host })">
+ <div v-html="i18n.t('poweredByMisskeyDescription', { name: instance.name ?? host })">
</div>
<FormLink to="/about-misskey">{{ i18n.ts.aboutMisskey }}</FormLink>
</div>
@@ -34,14 +34,14 @@
<FormSplit>
<MkKeyValue>
<template #key>{{ i18n.ts.administrator }}</template>
- <template #value>{{ $instance.maintainerName }}</template>
+ <template #value>{{ instance.maintainerName }}</template>
</MkKeyValue>
<MkKeyValue>
<template #key>{{ i18n.ts.contact }}</template>
- <template #value>{{ $instance.maintainerEmail }}</template>
+ <template #value>{{ instance.maintainerEmail }}</template>
</MkKeyValue>
</FormSplit>
- <FormLink v-if="$instance.tosUrl" :to="$instance.tosUrl" external>{{ i18n.ts.tos }}</FormLink>
+ <FormLink v-if="instance.tosUrl" :to="instance.tosUrl" external>{{ i18n.ts.tos }}</FormLink>
</div>
</FormSection>
@@ -101,6 +101,7 @@ import number from '@/filters/number';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
import { claimAchievement } from '@/scripts/achievements';
+import { instance } from '@/instance';
const props = withDefaults(defineProps<{
initialTab?: string;
diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue
index 8aae39cba1..963393d7e5 100644
--- a/packages/frontend/src/pages/admin/index.vue
+++ b/packages/frontend/src/pages/admin/index.vue
@@ -4,7 +4,7 @@
<MkSpacer :content-max="700" :margin-min="16">
<div class="lxpfedzu">
<div class="banner">
- <img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
+ <img :src="instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
</div>
<MkInfo v-if="thereIsUnresolvedAbuseReport" warn class="info">{{ i18n.ts.thereIsUnresolvedAbuseReportWarning }} <MkA to="/admin/abuses" class="_link">{{ i18n.ts.check }}</MkA></MkInfo>
@@ -221,7 +221,7 @@ onUnmounted(() => {
});
watch(router.currentRef, (to) => {
- if (to.route.path === "/admin" && to.child?.route.name == null && !narrow) {
+ if (to.route.path === '/admin' && to.child?.route.name == null && !narrow) {
router.replace('/admin/overview');
}
});
diff --git a/packages/frontend/src/pages/admin/object-storage.vue b/packages/frontend/src/pages/admin/object-storage.vue
index cbe38b2d81..704b27c174 100644
--- a/packages/frontend/src/pages/admin/object-storage.vue
+++ b/packages/frontend/src/pages/admin/object-storage.vue
@@ -7,7 +7,7 @@
<MkSwitch v-model="useObjectStorage">{{ i18n.ts.useObjectStorage }}</MkSwitch>
<template v-if="useObjectStorage">
- <MkInput v-model="objectStorageBaseUrl">
+ <MkInput v-model="objectStorageBaseUrl" :placeholder="'https://example.com'">
<template #label>{{ i18n.ts.objectStorageBaseUrl }}</template>
<template #caption>{{ i18n.ts.objectStorageBaseUrlDesc }}</template>
</MkInput>
@@ -22,8 +22,9 @@
<template #caption>{{ i18n.ts.objectStoragePrefixDesc }}</template>
</MkInput>
- <MkInput v-model="objectStorageEndpoint">
+ <MkInput v-model="objectStorageEndpoint" :placeholder="'example.com'">
<template #label>{{ i18n.ts.objectStorageEndpoint }}</template>
+ <template #prefix>https://</template>
<template #caption>{{ i18n.ts.objectStorageEndpointDesc }}</template>
</MkInput>
@@ -60,6 +61,7 @@
<MkSwitch v-model="objectStorageS3ForcePathStyle">
<template #label>s3ForcePathStyle</template>
+ <template #caption>{{ i18n.ts.s3ForcePathStyleDesc }}</template>
</MkSwitch>
</template>
</div>
diff --git a/packages/frontend/src/pages/admin/overview.instances.vue b/packages/frontend/src/pages/admin/overview.instances.vue
index 7d530d6b95..6c2ffd4742 100644
--- a/packages/frontend/src/pages/admin/overview.instances.vue
+++ b/packages/frontend/src/pages/admin/overview.instances.vue
@@ -1,6 +1,6 @@
<template>
<div class="wbrkwale">
- <Transition :name="$store.state.animation ? '_transition_zoom' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" mode="out-in">
<MkLoading v-if="fetching"/>
<div v-else class="instances">
<MkA v-for="(instance, i) in instances" :key="instance.id" v-tooltip.mfm.noDelay="`${instance.name}\n${instance.host}\n${instance.softwareName} ${instance.softwareVersion}`" :to="`/instance-info/${instance.host}`" class="instance">
@@ -16,6 +16,7 @@ import { ref } from 'vue';
import * as os from '@/os';
import { useInterval } from '@/scripts/use-interval';
import MkInstanceCardMini from '@/components/MkInstanceCardMini.vue';
+import { defaultStore } from '@/store';
const instances = ref([]);
const fetching = ref(true);
diff --git a/packages/frontend/src/pages/admin/overview.moderators.vue b/packages/frontend/src/pages/admin/overview.moderators.vue
index ff689b8bf9..fee6a1394e 100644
--- a/packages/frontend/src/pages/admin/overview.moderators.vue
+++ b/packages/frontend/src/pages/admin/overview.moderators.vue
@@ -1,6 +1,6 @@
<template>
<div>
- <Transition :name="$store.state.animation ? '_transition_zoom' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" mode="out-in">
<MkLoading v-if="fetching"/>
<div v-else :class="$style.root" class="_panel">
<MkA v-for="user in moderators" :key="user.id" class="user" :to="`/user-info/${user.id}`">
@@ -14,6 +14,7 @@
<script lang="ts" setup>
import { onMounted } from 'vue';
import * as os from '@/os';
+import { defaultStore } from '@/store';
let moderators: any = $ref(null);
let fetching = $ref(true);
diff --git a/packages/frontend/src/pages/admin/overview.stats.vue b/packages/frontend/src/pages/admin/overview.stats.vue
index 3dc1ed8ec5..142e70c698 100644
--- a/packages/frontend/src/pages/admin/overview.stats.vue
+++ b/packages/frontend/src/pages/admin/overview.stats.vue
@@ -1,6 +1,6 @@
<template>
<div>
- <Transition :name="$store.state.animation ? '_transition_zoom' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" mode="out-in">
<MkLoading v-if="fetching"/>
<div v-else :class="$style.root">
<div class="item _panel users">
@@ -62,6 +62,7 @@ import MkNumberDiff from '@/components/MkNumberDiff.vue';
import MkNumber from '@/components/MkNumber.vue';
import { i18n } from '@/i18n';
import { customEmojis } from '@/custom-emojis';
+import { defaultStore } from '@/store';
let stats: any = $ref(null);
let usersComparedToThePrevDay = $ref<number>();
diff --git a/packages/frontend/src/pages/admin/overview.users.vue b/packages/frontend/src/pages/admin/overview.users.vue
index 3379d064cd..5df7b468f3 100644
--- a/packages/frontend/src/pages/admin/overview.users.vue
+++ b/packages/frontend/src/pages/admin/overview.users.vue
@@ -1,6 +1,6 @@
<template>
<div :class="$style.root">
- <Transition :name="$store.state.animation ? '_transition_zoom' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" mode="out-in">
<MkLoading v-if="fetching"/>
<div v-else class="users">
<MkA v-for="(user, i) in newUsers" :key="user.id" :to="`/user-info/${user.id}`" class="user">
@@ -15,6 +15,7 @@
import * as os from '@/os';
import { useInterval } from '@/scripts/use-interval';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
+import { defaultStore } from '@/store';
let newUsers = $ref(null);
let fetching = $ref(true);
diff --git a/packages/frontend/src/pages/admin/relays.vue b/packages/frontend/src/pages/admin/relays.vue
index 55d33e0158..7ebcdfc583 100644
--- a/packages/frontend/src/pages/admin/relays.vue
+++ b/packages/frontend/src/pages/admin/relays.vue
@@ -9,7 +9,7 @@
<i v-if="relay.status === 'accepted'" class="ti ti-check icon accepted"></i>
<i v-else-if="relay.status === 'rejected'" class="ti ti-ban icon rejected"></i>
<i v-else class="ti ti-clock icon requesting"></i>
- <span>{{ $t(`_relayStatus.${relay.status}`) }}</span>
+ <span>{{ i18n.t(`_relayStatus.${relay.status}`) }}</span>
</div>
<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
</div>
diff --git a/packages/frontend/src/pages/announcements.vue b/packages/frontend/src/pages/announcements.vue
index 131f6d11ea..16a0ee8373 100644
--- a/packages/frontend/src/pages/announcements.vue
+++ b/packages/frontend/src/pages/announcements.vue
@@ -10,7 +10,7 @@
<img v-if="announcement.imageUrl" :src="announcement.imageUrl"/>
</div>
<div v-if="$i && !announcement.isRead" class="footer">
- <MkButton primary @click="read(items, announcement, i)"><i class="ti ti-check"></i> {{ $ts.gotIt }}</MkButton>
+ <MkButton primary @click="read(items, announcement, i)"><i class="ti ti-check"></i> {{ i18n.ts.gotIt }}</MkButton>
</div>
</section>
</MkPagination>
@@ -25,6 +25,7 @@ import MkButton from '@/components/MkButton.vue';
import * as os from '@/os';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
+import { $i } from '@/account';
const pagination = {
endpoint: 'announcements' as const,
diff --git a/packages/frontend/src/pages/antenna-timeline.vue b/packages/frontend/src/pages/antenna-timeline.vue
index cf803d6c7f..62e8178af1 100644
--- a/packages/frontend/src/pages/antenna-timeline.vue
+++ b/packages/frontend/src/pages/antenna-timeline.vue
@@ -2,7 +2,7 @@
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<div ref="rootEl" v-hotkey.global="keymap" class="tqmomfks">
- <div v-if="queue > 0" class="new"><button class="_buttonPrimary" @click="top()">{{ $ts.newNoteRecived }}</button></div>
+ <div v-if="queue > 0" class="new"><button class="_buttonPrimary" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
<div class="tl">
<MkTimeline
ref="tlEl" :key="antennaId"
diff --git a/packages/frontend/src/pages/auth.form.vue b/packages/frontend/src/pages/auth.form.vue
index f8484185f5..40a6d782b0 100644
--- a/packages/frontend/src/pages/auth.form.vue
+++ b/packages/frontend/src/pages/auth.form.vue
@@ -1,25 +1,25 @@
<template>
- <section>
- <div v-if="app.permission.length > 0">
- <p>{{ $t('_auth.permission', { name }) }}</p>
- <ul>
- <li v-for="p in app.permission" :key="p">{{ $t(`_permissions.${p}`) }}</li>
- </ul>
- </div>
- <div>{{ i18n.t('_auth.shareAccess', { name: `${name} (${app.id})` }) }}</div>
- <div :class="$style.buttons">
- <MkButton inline @click="cancel">{{ i18n.ts.cancel }}</MkButton>
- <MkButton inline primary @click="accept">{{ i18n.ts.accept }}</MkButton>
- </div>
- </section>
+<section>
+ <div v-if="app.permission.length > 0">
+ <p>{{ i18n.t('_auth.permission', { name }) }}</p>
+ <ul>
+ <li v-for="p in app.permission" :key="p">{{ i18n.t(`_permissions.${p}`) }}</li>
+ </ul>
+ </div>
+ <div>{{ i18n.t('_auth.shareAccess', { name: `${name} (${app.id})` }) }}</div>
+ <div :class="$style.buttons">
+ <MkButton inline @click="cancel">{{ i18n.ts.cancel }}</MkButton>
+ <MkButton inline primary @click="accept">{{ i18n.ts.accept }}</MkButton>
+ </div>
+</section>
</template>
<script lang="ts" setup>
import { } from 'vue';
+import { AuthSession } from 'misskey-js/built/entities';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os';
import { i18n } from '@/i18n';
-import { AuthSession } from 'misskey-js/built/entities';
const props = defineProps<{
session: AuthSession;
diff --git a/packages/frontend/src/pages/auth.vue b/packages/frontend/src/pages/auth.vue
index 4f8afb9ea2..2f40e7ded6 100644
--- a/packages/frontend/src/pages/auth.vue
+++ b/packages/frontend/src/pages/auth.vue
@@ -20,7 +20,7 @@
<h1>{{ i18n.ts._auth.denied }}</h1>
</div>
<div v-if="state == 'accepted' && session">
- <h1>{{ session.app.isAuthorized ? $t('already-authorized') : i18n.ts.allowed }}</h1>
+ <h1>{{ session.app.isAuthorized ? i18n.t('already-authorized') : i18n.ts.allowed }}</h1>
<p v-if="session.app.callbackUrl">
{{ i18n.ts._auth.callback }}
<MkEllipsis/>
diff --git a/packages/frontend/src/pages/flash/flash.vue b/packages/frontend/src/pages/flash/flash.vue
index 76201aa85f..961ef4b751 100644
--- a/packages/frontend/src/pages/flash/flash.vue
+++ b/packages/frontend/src/pages/flash/flash.vue
@@ -2,9 +2,9 @@
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="700">
- <Transition :name="$store.state.animation ? 'fade' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="flash" :key="flash.id">
- <Transition :name="$store.state.animation ? 'zoom' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? 'zoom' : ''" mode="out-in">
<div v-if="started" :class="$style.started">
<div class="main _panel">
<MkAsUi v-if="root" :component="root" :components="components"/>
@@ -63,6 +63,8 @@ import { AsUiComponent, AsUiRoot, registerAsUiLib } from '@/scripts/aiscript/ui'
import { createAiScriptEnv } from '@/scripts/aiscript/api';
import MkFolder from '@/components/MkFolder.vue';
import MkCode from '@/components/MkCode.vue';
+import { defaultStore } from '@/store';
+import { $i } from '@/account';
const props = defineProps<{
id: string;
diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue
index 4bf7c8c514..e0f3c105e1 100644
--- a/packages/frontend/src/pages/gallery/post.vue
+++ b/packages/frontend/src/pages/gallery/post.vue
@@ -3,7 +3,7 @@
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="1000" :margin-min="16" :margin-max="32">
<div class="_root">
- <Transition :name="$store.state.animation ? 'fade' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="post" class="rkxwuolj">
<div class="files">
<div v-for="file in post.files" :key="file.id" class="file">
@@ -67,6 +67,8 @@ import { url } from '@/config';
import { useRouter } from '@/router';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
+import { defaultStore } from '@/store';
+import { $i } from '@/account';
const router = useRouter();
diff --git a/packages/frontend/src/pages/miauth.vue b/packages/frontend/src/pages/miauth.vue
index 915adff277..8e0624f555 100644
--- a/packages/frontend/src/pages/miauth.vue
+++ b/packages/frontend/src/pages/miauth.vue
@@ -1,6 +1,6 @@
<template>
<MkStickyContainer>
- <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs" /></template>
+ <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="800">
<div v-if="$i">
<div v-if="state == 'waiting'">
@@ -15,13 +15,13 @@
</div>
<div v-else>
<div v-if="_permissions.length > 0">
- <p v-if="name">{{ $t('_auth.permission', { name }) }}</p>
+ <p v-if="name">{{ i18n.t('_auth.permission', { name }) }}</p>
<p v-else>{{ i18n.ts._auth.permissionAsk }}</p>
<ul>
- <li v-for="p in _permissions" :key="p">{{ $t(`_permissions.${p}`) }}</li>
+ <li v-for="p in _permissions" :key="p">{{ i18n.t(`_permissions.${p}`) }}</li>
</ul>
</div>
- <div v-if="name">{{ $t('_auth.shareAccess', { name }) }}</div>
+ <div v-if="name">{{ i18n.t('_auth.shareAccess', { name }) }}</div>
<div v-else>{{ i18n.ts._auth.shareAccessAsk }}</div>
<div :class="$style.buttons">
<MkButton inline @click="deny">{{ i18n.ts.cancel }}</MkButton>
diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue
index 3e5e1ffe9d..d9baa1096a 100644
--- a/packages/frontend/src/pages/note.vue
+++ b/packages/frontend/src/pages/note.vue
@@ -3,7 +3,7 @@
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="800">
<div class="fcuexfpr">
- <Transition :name="$store.state.animation ? 'fade' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="note" class="note">
<div v-if="showNext" class="_margin">
<MkNotes class="" :pagination="nextPagination" :no-gap="true"/>
@@ -50,6 +50,7 @@ import { definePageMetadata } from '@/scripts/page-metadata';
import { i18n } from '@/i18n';
import { dateString } from '@/filters/date';
import MkClipPreview from '@/components/MkClipPreview.vue';
+import { defaultStore } from '@/store';
const props = defineProps<{
noteId: string;
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 fe230ad095..ffeb8ba285 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,7 +1,7 @@
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => $emit('remove')">
- <template #header><i class="ti ti-photo"></i> {{ $ts._pages.blocks.image }}</template>
+ <template #header><i class="ti ti-photo"></i> {{ i18n.ts._pages.blocks.image }}</template>
<template #func>
<button @click="choose()">
<i class="ti ti-folder"></i>
@@ -20,6 +20,7 @@ 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';
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 cc39d2c412..a388a8d0c1 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,14 +1,14 @@
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => $emit('remove')">
- <template #header><i class="ti ti-note"></i> {{ $ts._pages.blocks.note }}</template>
+ <template #header><i class="ti ti-note"></i> {{ i18n.ts._pages.blocks.note }}</template>
<section style="padding: 0 16px 0 16px;">
<MkInput v-model="id">
- <template #label>{{ $ts._pages.blocks._note.id }}</template>
- <template #caption>{{ $ts._pages.blocks._note.idDescription }}</template>
+ <template #label>{{ i18n.ts._pages.blocks._note.id }}</template>
+ <template #caption>{{ i18n.ts._pages.blocks._note.idDescription }}</template>
</MkInput>
- <MkSwitch v-model="props.modelValue.detailed"><span>{{ $ts._pages.blocks._note.detailed }}</span></MkSwitch>
+ <MkSwitch v-model="props.modelValue.detailed"><span>{{ i18n.ts._pages.blocks._note.detailed }}</span></MkSwitch>
<MkNote v-if="note && !props.modelValue.detailed" :key="note.id + ':normal'" v-model:note="note" style="margin-bottom: 16px;"/>
<MkNoteDetailed v-if="note && props.modelValue.detailed" :key="note.id + ':detail'" v-model:note="note" style="margin-bottom: 16px;"/>
@@ -25,6 +25,7 @@ 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';
const props = defineProps<{
modelValue: any
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 ee494b7574..bf21ae3c67 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,7 +1,7 @@
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => $emit('remove')">
- <template #header><i class="ti ti-align-left"></i> {{ $ts._pages.blocks.text }}</template>
+ <template #header><i class="ti ti-align-left"></i> {{ i18n.ts._pages.blocks.text }}</template>
<section class="vckmsadr">
<textarea v-model="text"></textarea>
@@ -13,6 +13,7 @@
/* eslint-disable vue/no-mutating-props */
import { watch } from 'vue';
import XContainer from '../page-editor.container.vue';
+import { i18n } from '@/i18n';
const props = defineProps<{
modelValue: any
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 15cdda5efb..dd733403af 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.container.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.container.vue
@@ -16,8 +16,8 @@
</button>
</div>
</header>
- <p v-show="showBody" v-if="error != null" class="error">{{ $t('_pages.script.typeError', { slot: error.arg + 1, expect: $t(`script.types.${error.expect}`), actual: $t(`script.types.${error.actual}`) }) }}</p>
- <p v-show="showBody" v-if="warn != null" class="warn">{{ $t('_pages.script.thereIsEmptySlot', { slot: warn.slot + 1 }) }}</p>
+ <p v-show="showBody" v-if="error != null" class="error">{{ i18n.t('_pages.script.typeError', { slot: error.arg + 1, expect: i18n.t(`script.types.${error.expect}`), actual: i18n.t(`script.types.${error.actual}`) }) }}</p>
+ <p v-show="showBody" v-if="warn != null" class="warn">{{ i18n.t('_pages.script.thereIsEmptySlot', { slot: warn.slot + 1 }) }}</p>
<div v-show="showBody" class="body">
<slot></slot>
</div>
@@ -26,6 +26,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
+import { i18n } from '@/i18n';
export default defineComponent({
props: {
@@ -54,6 +55,7 @@ export default defineComponent({
data() {
return {
showBody: this.expanded,
+ i18n,
};
},
methods: {
diff --git a/packages/frontend/src/pages/page-editor/page-editor.vue b/packages/frontend/src/pages/page-editor/page-editor.vue
index c4b37c91c6..bcf30e23a7 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.vue
@@ -3,42 +3,42 @@
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="700">
<div class="jqqmcavi">
- <MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ $ts._pages.viewPage }}</MkButton>
- <MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ti ti-device-floppy"></i> {{ $ts.save }}</MkButton>
- <MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ti ti-copy"></i> {{ $ts.duplicate }}</MkButton>
- <MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ti ti-trash"></i> {{ $ts.delete }}</MkButton>
+ <MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ i18n.ts._pages.viewPage }}</MkButton>
+ <MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+ <MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ti ti-copy"></i> {{ i18n.ts.duplicate }}</MkButton>
+ <MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
</div>
<div v-if="tab === 'settings'">
<div class="_gaps_m">
<MkInput v-model="title">
- <template #label>{{ $ts._pages.title }}</template>
+ <template #label>{{ i18n.ts._pages.title }}</template>
</MkInput>
<MkInput v-model="summary">
- <template #label>{{ $ts._pages.summary }}</template>
+ <template #label>{{ i18n.ts._pages.summary }}</template>
</MkInput>
<MkInput v-model="name">
<template #prefix>{{ url }}/@{{ author.username }}/pages/</template>
- <template #label>{{ $ts._pages.url }}</template>
+ <template #label>{{ i18n.ts._pages.url }}</template>
</MkInput>
- <MkSwitch v-model="alignCenter">{{ $ts._pages.alignCenter }}</MkSwitch>
+ <MkSwitch v-model="alignCenter">{{ i18n.ts._pages.alignCenter }}</MkSwitch>
<MkSelect v-model="font">
- <template #label>{{ $ts._pages.font }}</template>
- <option value="serif">{{ $ts._pages.fontSerif }}</option>
- <option value="sans-serif">{{ $ts._pages.fontSansSerif }}</option>
+ <template #label>{{ i18n.ts._pages.font }}</template>
+ <option value="serif">{{ i18n.ts._pages.fontSerif }}</option>
+ <option value="sans-serif">{{ i18n.ts._pages.fontSansSerif }}</option>
</MkSelect>
- <MkSwitch v-model="hideTitleWhenPinned">{{ $ts._pages.hideTitleWhenPinned }}</MkSwitch>
+ <MkSwitch v-model="hideTitleWhenPinned">{{ i18n.ts._pages.hideTitleWhenPinned }}</MkSwitch>
<div class="eyeCatch">
- <MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="ti ti-plus"></i> {{ $ts._pages.eyeCatchingImageSet }}</MkButton>
+ <MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="ti ti-plus"></i> {{ i18n.ts._pages.eyeCatchingImageSet }}</MkButton>
<div v-else-if="eyeCatchingImage">
<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name" style="max-width: 100%;"/>
- <MkButton v-if="!readonly" @click="removeEyeCatchingImage()"><i class="ti ti-trash"></i> {{ $ts._pages.eyeCatchingImageRemove }}</MkButton>
+ <MkButton v-if="!readonly" @click="removeEyeCatchingImage()"><i class="ti ti-trash"></i> {{ i18n.ts._pages.eyeCatchingImageRemove }}</MkButton>
</div>
</div>
</div>
diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue
index b26255ce61..5a0f58c8df 100644
--- a/packages/frontend/src/pages/page.vue
+++ b/packages/frontend/src/pages/page.vue
@@ -2,7 +2,7 @@
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="700">
- <Transition :name="$store.state.animation ? 'fade' : ''" mode="out-in">
+ <Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="page" :key="page.id" class="xcukqgmh">
<div class="main">
<!--
@@ -75,8 +75,9 @@ import MkPagination from '@/components/MkPagination.vue';
import MkPagePreview from '@/components/MkPagePreview.vue';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
-import { pageViewInterruptors } from '@/store';
+import { pageViewInterruptors, defaultStore } from '@/store';
import { deepClone } from '@/scripts/clone';
+import { $i } from '@/account';
const props = defineProps<{
pageName: string;
diff --git a/packages/frontend/src/pages/settings/apps.vue b/packages/frontend/src/pages/settings/apps.vue
index 861414cef8..955d812154 100644
--- a/packages/frontend/src/pages/settings/apps.vue
+++ b/packages/frontend/src/pages/settings/apps.vue
@@ -24,7 +24,7 @@
<details>
<summary>{{ i18n.ts.details }}</summary>
<ul>
- <li v-for="p in token.permission" :key="p">{{ $t(`_permissions.${p}`) }}</li>
+ <li v-for="p in token.permission" :key="p">{{ i18n.t(`_permissions.${p}`) }}</li>
</ul>
</details>
<div class="actions">
diff --git a/packages/frontend/src/pages/settings/delete-account.vue b/packages/frontend/src/pages/settings/delete-account.vue
index bbd5513954..c6e79165c5 100644
--- a/packages/frontend/src/pages/settings/delete-account.vue
+++ b/packages/frontend/src/pages/settings/delete-account.vue
@@ -11,7 +11,7 @@
import FormInfo from '@/components/MkInfo.vue';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os';
-import { signout } from '@/account';
+import { signout, $i } from '@/account';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
diff --git a/packages/frontend/src/pages/settings/sounds.vue b/packages/frontend/src/pages/settings/sounds.vue
index 006a2377d4..8855a275c6 100644
--- a/packages/frontend/src/pages/settings/sounds.vue
+++ b/packages/frontend/src/pages/settings/sounds.vue
@@ -8,7 +8,7 @@
<template #label>{{ i18n.ts.sounds }}</template>
<div class="_gaps_s">
<MkFolder v-for="type in Object.keys(sounds)" :key="type">
- <template #label>{{ $t('_sfx.' + type) }}</template>
+ <template #label>{{ i18n.t('_sfx.' + type) }}</template>
<template #suffix>{{ sounds[type].type ?? i18n.ts.none }}</template>
<XSound :type="sounds[type].type" :volume="sounds[type].volume" @update="(res) => updated(type, res)"/>
diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue
index 62b0b4551a..9f13f7a1dd 100644
--- a/packages/frontend/src/pages/timeline.vue
+++ b/packages/frontend/src/pages/timeline.vue
@@ -3,8 +3,8 @@
<template #header><MkPageHeader v-model:tab="src" :actions="headerActions" :tabs="$i ? headerTabs : headerTabsWhenNotLogin" :display-my-avatar="true"/></template>
<MkSpacer :content-max="800">
<div ref="rootEl" v-hotkey.global="keymap">
- <XTutorial v-if="$i && $store.reactiveState.tutorial.value != -1" class="_panel" style="margin-bottom: var(--margin);"/>
- <MkPostForm v-if="$store.reactiveState.showFixedPostForm.value" :class="$style.postForm" class="post-form _panel" fixed style="margin-bottom: var(--margin);"/>
+ <XTutorial v-if="$i && defaultStore.reactiveState.tutorial.value != -1" class="_panel" style="margin-bottom: var(--margin);"/>
+ <MkPostForm v-if="defaultStore.reactiveState.showFixedPostForm.value" :class="$style.postForm" class="post-form _panel" fixed style="margin-bottom: var(--margin);"/>
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
<div :class="$style.tl">
diff --git a/packages/frontend/src/pages/user-info.vue b/packages/frontend/src/pages/user-info.vue
index 571f058240..94718d1533 100644
--- a/packages/frontend/src/pages/user-info.vue
+++ b/packages/frontend/src/pages/user-info.vue
@@ -192,7 +192,7 @@ import { url } from '@/config';
import { userPage, acct } from '@/filters/user';
import { definePageMetadata } from '@/scripts/page-metadata';
import { i18n } from '@/i18n';
-import { iAmAdmin, iAmModerator } from '@/account';
+import { iAmAdmin, iAmModerator, $i } from '@/account';
import MkRolePreview from '@/components/MkRolePreview.vue';
const props = withDefaults(defineProps<{
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index c45c0600a7..1ce0bedbe3 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -57,7 +57,7 @@
</dl>
<dl v-if="user.birthday" class="field">
<dt class="name"><i class="ti ti-cake ti-fw"></i> {{ i18n.ts.birthday }}</dt>
- <dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd>
+ <dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ i18n.t('yearsOld', { age }) }})</dd>
</dl>
<dl class="field">
<dt class="name"><i class="ti ti-calendar ti-fw"></i> {{ i18n.ts.registeredDate }}</dt>
diff --git a/packages/frontend/src/pages/user/index.activity.vue b/packages/frontend/src/pages/user/index.activity.vue
index 8ff3374446..2d9ee85bc4 100644
--- a/packages/frontend/src/pages/user/index.activity.vue
+++ b/packages/frontend/src/pages/user/index.activity.vue
@@ -1,7 +1,7 @@
<template>
<MkContainer>
<template #icon><i class="ti ti-chart-line"></i></template>
- <template #header>{{ $ts.activity }}</template>
+ <template #header>{{ i18n.ts.activity }}</template>
<template #func="{ buttonStyleClass }">
<button class="_button" :class="buttonStyleClass" @click="showMenu">
<i class="ti ti-dots"></i>
diff --git a/packages/frontend/src/pages/user/index.photos.vue b/packages/frontend/src/pages/user/index.photos.vue
index 85f6591eee..e710dab2d9 100644
--- a/packages/frontend/src/pages/user/index.photos.vue
+++ b/packages/frontend/src/pages/user/index.photos.vue
@@ -1,7 +1,7 @@
<template>
<MkContainer :max-height="300" :foldable="true">
<template #icon><i class="ti ti-photo"></i></template>
- <template #header>{{ $ts.images }}</template>
+ <template #header>{{ i18n.ts.images }}</template>
<div :class="$style.root">
<MkLoading v-if="fetching"/>
<div v-if="!fetching && images.length > 0" :class="$style.stream">
@@ -14,7 +14,7 @@
<ImgWithBlurhash :hash="image.file.blurhash" :src="thumbnail(image.file)" :title="image.file.name"/>
</MkA>
</div>
- <p v-if="!fetching && images.length == 0" :class="$style.empty">{{ $ts.nothing }}</p>
+ <p v-if="!fetching && images.length == 0" :class="$style.empty">{{ i18n.ts.nothing }}</p>
</div>
</MkContainer>
</template>
diff --git a/packages/frontend/src/pages/welcome.entrance.a.vue b/packages/frontend/src/pages/welcome.entrance.a.vue
index b6f9b3eb23..4d8d76db18 100644
--- a/packages/frontend/src/pages/welcome.entrance.a.vue
+++ b/packages/frontend/src/pages/welcome.entrance.a.vue
@@ -14,7 +14,7 @@
</div>
<div class="contents">
<div class="main">
- <img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
+ <img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
<button class="_button _acrylic menu" @click="showMenu"><i class="ti ti-dots"></i></button>
<div class="fg">
<h1>
diff --git a/packages/frontend/src/pages/welcome.entrance.b.vue b/packages/frontend/src/pages/welcome.entrance.b.vue
index 7c7dfcc850..03bf174710 100644
--- a/packages/frontend/src/pages/welcome.entrance.b.vue
+++ b/packages/frontend/src/pages/welcome.entrance.b.vue
@@ -10,22 +10,22 @@
</h1>
<div class="about">
<!-- eslint-disable-next-line vue/no-v-html -->
- <div class="desc" v-html="meta.description || $ts.headlineMisskey"></div>
+ <div class="desc" v-html="meta.description || i18n.ts.headlineMisskey"></div>
</div>
<div class="action">
- <MkButton class="signup" inline gradate @click="signup()">{{ $ts.signup }}</MkButton>
- <MkButton class="signin" inline @click="signin()">{{ $ts.login }}</MkButton>
+ <MkButton class="signup" inline gradate @click="signup()">{{ i18n.ts.signup }}</MkButton>
+ <MkButton class="signin" inline @click="signin()">{{ i18n.ts.login }}</MkButton>
</div>
<div v-if="onlineUsersCount && stats" class="status">
<div>
- <I18n :src="$ts.nUsers" text-tag="span" class="users">
+ <I18n :src="i18n.ts.nUsers" text-tag="span" class="users">
<template #n><b>{{ number(stats.originalUsersCount) }}</b></template>
</I18n>
- <I18n :src="$ts.nNotes" text-tag="span" class="notes">
+ <I18n :src="i18n.ts.nNotes" text-tag="span" class="notes">
<template #n><b>{{ number(stats.originalNotesCount) }}</b></template>
</I18n>
</div>
- <I18n :src="$ts.onlineUsersCount" text-tag="span" class="online">
+ <I18n :src="i18n.ts.onlineUsersCount" text-tag="span" class="online">
<template #n><b>{{ onlineUsersCount }}</b></template>
</I18n>
</div>
@@ -47,6 +47,7 @@ import MkFeaturedPhotos from '@/components/MkFeaturedPhotos.vue';
import { host, instanceName } from '@/config';
import * as os from '@/os';
import number from '@/filters/number';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -64,6 +65,7 @@ export default defineComponent({
stats: null,
tags: [],
onlineUsersCount: null,
+ i18n,
};
},
@@ -103,19 +105,19 @@ export default defineComponent({
showMenu(ev) {
os.popupMenu([{
- text: this.$t('aboutX', { x: instanceName }),
+ text: i18n.t('aboutX', { x: instanceName }),
icon: 'ti ti-info-circle',
action: () => {
os.pageWindow('/about');
},
}, {
- text: this.$ts.aboutMisskey,
+ text: i18n.ts.aboutMisskey,
icon: 'ti ti-info-circle',
action: () => {
os.pageWindow('/about-misskey');
},
}, null, {
- text: this.$ts.help,
+ text: i18n.ts.help,
icon: 'ti ti-question-circle',
action: () => {
window.open('https://misskey-hub.net/help.md', '_blank');
diff --git a/packages/frontend/src/pages/welcome.entrance.c.vue b/packages/frontend/src/pages/welcome.entrance.c.vue
index f566d1a56a..eca4e5764d 100644
--- a/packages/frontend/src/pages/welcome.entrance.c.vue
+++ b/packages/frontend/src/pages/welcome.entrance.c.vue
@@ -22,22 +22,22 @@
</h1>
<div class="about">
<!-- eslint-disable-next-line vue/no-v-html -->
- <div class="desc" v-html="meta.description || $ts.headlineMisskey"></div>
+ <div class="desc" v-html="meta.description || i18n.ts.headlineMisskey"></div>
</div>
<div class="action">
- <MkButton inline gradate @click="signup()">{{ $ts.signup }}</MkButton>
- <MkButton inline @click="signin()">{{ $ts.login }}</MkButton>
+ <MkButton inline gradate @click="signup()">{{ i18n.ts.signup }}</MkButton>
+ <MkButton inline @click="signin()">{{ i18n.ts.login }}</MkButton>
</div>
<div v-if="onlineUsersCount && stats" class="status">
<div>
- <I18n :src="$ts.nUsers" text-tag="span" class="users">
+ <I18n :src="i18n.ts.nUsers" text-tag="span" class="users">
<template #n><b>{{ number(stats.originalUsersCount) }}</b></template>
</I18n>
- <I18n :src="$ts.nNotes" text-tag="span" class="notes">
+ <I18n :src="i18n.ts.nNotes" text-tag="span" class="notes">
<template #n><b>{{ number(stats.originalNotesCount) }}</b></template>
</I18n>
</div>
- <I18n :src="$ts.onlineUsersCount" text-tag="span" class="online">
+ <I18n :src="i18n.ts.onlineUsersCount" text-tag="span" class="online">
<template #n><b>{{ onlineUsersCount }}</b></template>
</I18n>
</div>
@@ -45,10 +45,10 @@
</div>
</div>
<nav class="nav">
- <MkA to="/announcements">{{ $ts.announcements }}</MkA>
- <MkA to="/explore">{{ $ts.explore }}</MkA>
- <MkA to="/channels">{{ $ts.channel }}</MkA>
- <MkA to="/featured">{{ $ts.featured }}</MkA>
+ <MkA to="/announcements">{{ i18n.ts.announcements }}</MkA>
+ <MkA to="/explore">{{ i18n.ts.explore }}</MkA>
+ <MkA to="/channels">{{ i18n.ts.channel }}</MkA>
+ <MkA to="/featured">{{ i18n.ts.featured }}</MkA>
</nav>
</div>
</div>
@@ -58,15 +58,16 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { toUnicode } from 'punycode/';
+import XTimeline from './welcome.timeline.vue';
import XSigninDialog from '@/components/MkSigninDialog.vue';
import XSignupDialog from '@/components/MkSignupDialog.vue';
import MkButton from '@/components/MkButton.vue';
import MkNote from '@/components/MkNote.vue';
import MkFeaturedPhotos from '@/components/MkFeaturedPhotos.vue';
-import XTimeline from './welcome.timeline.vue';
import { host, instanceName } from '@/config';
import * as os from '@/os';
import number from '@/filters/number';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -84,6 +85,7 @@ export default defineComponent({
stats: null,
tags: [],
onlineUsersCount: null,
+ i18n,
};
},
@@ -123,22 +125,22 @@ export default defineComponent({
showMenu(ev) {
os.popupMenu([{
- text: this.$t('aboutX', { x: instanceName }),
+ text: i18n.t('aboutX', { x: instanceName }),
icon: 'ti ti-info-circle',
action: () => {
os.pageWindow('/about');
},
}, {
- text: this.$ts.aboutMisskey,
+ text: i18n.ts.aboutMisskey,
icon: 'ti ti-info-circle',
action: () => {
os.pageWindow('/about-misskey');
},
}, null, {
- text: this.$ts.help,
+ text: i18n.ts.help,
icon: 'ti ti-question-circle',
action: () => {
- window.open(`https://misskey-hub.net/help.md`, '_blank');
+ window.open('https://misskey-hub.net/help.md', '_blank');
},
}], ev.currentTarget ?? ev.target);
},
diff --git a/packages/frontend/src/pages/welcome.setup.vue b/packages/frontend/src/pages/welcome.setup.vue
index 8b43fa368b..212d156a83 100644
--- a/packages/frontend/src/pages/welcome.setup.vue
+++ b/packages/frontend/src/pages/welcome.setup.vue
@@ -2,19 +2,19 @@
<form class="mk-setup" @submit.prevent="submit()">
<h1>Welcome to Misskey!</h1>
<div class="_gaps_m">
- <p>{{ $ts.intro }}</p>
+ <p>{{ i18n.ts.intro }}</p>
<MkInput v-model="username" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" required data-cy-admin-username>
- <template #label>{{ $ts.username }}</template>
+ <template #label>{{ i18n.ts.username }}</template>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
</MkInput>
<MkInput v-model="password" type="password" data-cy-admin-password>
- <template #label>{{ $ts.password }}</template>
+ <template #label>{{ i18n.ts.password }}</template>
<template #prefix><i class="ti ti-lock"></i></template>
</MkInput>
<div class="bottom">
<MkButton gradate type="submit" :disabled="submitting" data-cy-admin-ok>
- {{ submitting ? $ts.processing : $ts.done }}<MkEllipsis v-if="submitting"/>
+ {{ submitting ? i18n.ts.processing : i18n.ts.done }}<MkEllipsis v-if="submitting"/>
</MkButton>
</div>
</div>
diff --git a/packages/frontend/src/pages/welcome.timeline.vue b/packages/frontend/src/pages/welcome.timeline.vue
index c34d43dc1c..6a507ee1ed 100644
--- a/packages/frontend/src/pages/welcome.timeline.vue
+++ b/packages/frontend/src/pages/welcome.timeline.vue
@@ -5,30 +5,31 @@
<div class="_panel" :class="$style.content">
<div :class="$style.body">
<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
- <Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" />
+ <Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i"/>
<MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
</div>
<div v-if="note.files.length > 0" :class="$style.richcontent">
- <MkMediaList :media-list="note.files" />
+ <MkMediaList :media-list="note.files"/>
</div>
<div v-if="note.poll">
- <MkPoll :note="note" :readOnly="true" />
+ <MkPoll :note="note" :read-only="true"/>
</div>
</div>
- <MkReactionsViewer ref="reactionsViewer" :note="note" />
+ <MkReactionsViewer ref="reactionsViewer" :note="note"/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
+import { Note } from 'misskey-js/built/entities';
+import { onUpdated } from 'vue';
import MkReactionsViewer from '@/components/MkReactionsViewer.vue';
import MkMediaList from '@/components/MkMediaList.vue';
import MkPoll from '@/components/MkPoll.vue';
import * as os from '@/os';
-import { Note } from 'misskey-js/built/entities';
-import { onUpdated } from 'vue';
import { getScrollContainer } from '@/scripts/scroll';
+import { $i } from '@/account';
let notes = $ref<Note[]>([]);
let isScrolling = $ref(false);
diff --git a/packages/frontend/src/ui/_common_/common.vue b/packages/frontend/src/ui/_common_/common.vue
index 976345f9ee..e1561cb396 100644
--- a/packages/frontend/src/ui/_common_/common.vue
+++ b/packages/frontend/src/ui/_common_/common.vue
@@ -11,11 +11,11 @@
<TransitionGroup
tag="div" :class="$style.notifications"
- :move-class="$store.state.animation ? $style.transition_notification_move : ''"
- :enter-active-class="$store.state.animation ? $style.transition_notification_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_notification_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_notification_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_notification_leaveTo : ''"
+ :move-class="defaultStore.state.animation ? $style.transition_notification_move : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_notification_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_notification_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_notification_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_notification_leaveTo : ''"
>
<XNotification v-for="notification in notifications" :key="notification.id" :notification="notification" :class="$style.notification"/>
</TransitionGroup>
@@ -40,6 +40,7 @@ import * as sound from '@/scripts/sound';
import { $i } from '@/account';
import { stream } from '@/stream';
import { i18n } from '@/i18n';
+import { defaultStore } from '@/store';
const XStreamIndicator = defineAsyncComponent(() => import('./stream-indicator.vue'));
const XUpload = defineAsyncComponent(() => import('./upload.vue'));
diff --git a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
index 935aceea7c..7a94a0c3ee 100644
--- a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
+++ b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
@@ -2,9 +2,9 @@
<div class="kmwsukvl">
<div class="body">
<div class="top">
- <div class="banner" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }"></div>
+ <div class="banner" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
<button v-click-anime class="item _button instance" @click="openInstanceMenu">
- <img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
+ <img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
</button>
</div>
<div class="middle">
@@ -47,9 +47,10 @@ import { computed, defineAsyncComponent, toRef } from 'vue';
import { openInstanceMenu } from './common';
import * as os from '@/os';
import { navbarItemDef } from '@/navbar';
-import { openAccountMenu as openAccountMenu_ } from '@/account';
+import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
import { defaultStore } from '@/store';
import { i18n } from '@/i18n';
+import { instance } from '@/instance';
const menu = toRef(defaultStore.state, 'menu');
const otherMenuItemIndicated = computed(() => {
diff --git a/packages/frontend/src/ui/_common_/navbar.vue b/packages/frontend/src/ui/_common_/navbar.vue
index 3c161f6797..3b4b161422 100644
--- a/packages/frontend/src/ui/_common_/navbar.vue
+++ b/packages/frontend/src/ui/_common_/navbar.vue
@@ -2,9 +2,9 @@
<div class="mvcprjjd" :class="{ iconOnly }">
<div class="body">
<div class="top">
- <div class="banner" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }"></div>
- <button v-click-anime v-tooltip.noDelay.right="$instance.name ?? i18n.ts.instance" class="item _button instance" @click="openInstanceMenu">
- <img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
+ <div class="banner" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
+ <button v-click-anime v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="item _button instance" @click="openInstanceMenu">
+ <img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
</button>
</div>
<div class="middle">
@@ -60,6 +60,7 @@ import { navbarItemDef } from '@/navbar';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
import { defaultStore } from '@/store';
import { i18n } from '@/i18n';
+import { instance } from '@/instance';
const iconOnly = ref(false);
diff --git a/packages/frontend/src/ui/_common_/stream-indicator.vue b/packages/frontend/src/ui/_common_/stream-indicator.vue
index b46422d6cd..2a856e2a45 100644
--- a/packages/frontend/src/ui/_common_/stream-indicator.vue
+++ b/packages/frontend/src/ui/_common_/stream-indicator.vue
@@ -1,5 +1,5 @@
<template>
-<div v-if="hasDisconnected && $store.state.serverDisconnectedBehavior === 'quiet'" :class="$style.root" class="_panel _shadow" @click="resetDisconnected">
+<div v-if="hasDisconnected && defaultStore.state.serverDisconnectedBehavior === 'quiet'" :class="$style.root" class="_panel _shadow" @click="resetDisconnected">
<div><i class="ti ti-alert-triangle"></i> {{ i18n.ts.disconnectedFromServer }}</div>
<div :class="$style.command" class="_buttons">
<MkButton :class="$style.commandButton" small primary @click="reload">{{ i18n.ts.reload }}</MkButton>
@@ -14,6 +14,7 @@ import { stream } from '@/stream';
import { i18n } from '@/i18n';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os';
+import { defaultStore } from '@/store';
const zIndex = os.claimZIndex('high');
diff --git a/packages/frontend/src/ui/classic.header.vue b/packages/frontend/src/ui/classic.header.vue
index 3dfb371d32..5e632c16d0 100644
--- a/packages/frontend/src/ui/classic.header.vue
+++ b/packages/frontend/src/ui/classic.header.vue
@@ -3,9 +3,9 @@
<div class="body">
<div class="left">
<button v-click-anime class="item _button instance" @click="openInstanceMenu">
- <img :src="$instance.iconUrl ?? $instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
+ <img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
</button>
- <MkA v-click-anime v-tooltip="$ts.timeline" class="item index" active-class="active" to="/" exact>
+ <MkA v-click-anime v-tooltip="i18n.ts.timeline" class="item index" active-class="active" to="/" exact>
<i class="ti ti-home ti-fw"></i>
</MkA>
<template v-for="item in menu">
@@ -16,7 +16,7 @@
</component>
</template>
<div class="divider"></div>
- <MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="$ts.controlPanel" class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
+ <MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="i18n.ts.controlPanel" class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
<i class="ti ti-dashboard ti-fw"></i>
</MkA>
<button v-click-anime class="item _button" @click="more">
@@ -25,7 +25,7 @@
</button>
</div>
<div class="right">
- <MkA v-click-anime v-tooltip="$ts.settings" class="item" active-class="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
+ <MkA v-click-anime v-tooltip="i18n.ts.settings" class="item" active-class="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
<i class="ti ti-settings ti-fw"></i>
</MkA>
<button v-click-anime class="item _button account" @click="openAccountMenu">
@@ -47,9 +47,12 @@ import { openInstanceMenu } from './_common_/common';
import { host } from '@/config';
import * as os from '@/os';
import { navbarItemDef } from '@/navbar';
-import { openAccountMenu } from '@/account';
+import { openAccountMenu, $i } from '@/account';
import MkButton from '@/components/MkButton.vue';
import { mainRouter } from '@/router';
+import { defaultStore } from '@/store';
+import { instance } from '@/instance';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -63,12 +66,16 @@ export default defineComponent({
connection: null,
navbarItemDef: navbarItemDef,
settingsWindowed: false,
+ defaultStore,
+ instance,
+ $i,
+ i18n,
};
},
computed: {
menu(): string[] {
- return this.$store.state.menu;
+ return defaultStore.state.menu;
},
otherNavItemIndicated(): boolean {
@@ -81,7 +88,7 @@ export default defineComponent({
},
watch: {
- '$store.reactiveState.menuDisplay.value'() {
+ 'defaultStore.reactiveState.menuDisplay.value'() {
this.calcViewState();
},
},
diff --git a/packages/frontend/src/ui/classic.sidebar.vue b/packages/frontend/src/ui/classic.sidebar.vue
index 6fff233ac5..42ea5cd785 100644
--- a/packages/frontend/src/ui/classic.sidebar.vue
+++ b/packages/frontend/src/ui/classic.sidebar.vue
@@ -5,12 +5,12 @@
</button>
<div class="post" data-cy-open-post-form @click="post">
<MkButton class="button" gradate full rounded>
- <i class="ti ti-pencil ti-fw"></i><span v-if="!iconOnly" class="text">{{ $ts.note }}</span>
+ <i class="ti ti-pencil ti-fw"></i><span v-if="!iconOnly" class="text">{{ i18n.ts.note }}</span>
</MkButton>
</div>
<div class="divider"></div>
<MkA v-click-anime class="item index" active-class="active" to="/" exact>
- <i class="ti ti-home ti-fw"></i><span class="text">{{ $ts.timeline }}</span>
+ <i class="ti ti-home ti-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
@@ -21,19 +21,19 @@
</template>
<div class="divider"></div>
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
- <i class="ti ti-dashboard ti-fw"></i><span class="text">{{ $ts.controlPanel }}</span>
+ <i class="ti ti-dashboard ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
</MkA>
<button v-click-anime class="item _button" @click="more">
- <i class="ti ti-dots ti-fw"></i><span class="text">{{ $ts.more }}</span>
+ <i class="ti ti-dots ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
</button>
<MkA v-click-anime class="item" active-class="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
- <i class="ti ti-settings ti-fw"></i><span class="text">{{ $ts.settings }}</span>
+ <i class="ti ti-settings ti-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
</MkA>
<div class="divider"></div>
<div class="about">
<button v-click-anime class="item _button" @click="openInstanceMenu">
- <img :src="$instance.iconUrl ?? $instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
+ <img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
</button>
</div>
<!--<MisskeyLogo class="misskey"/>-->
@@ -46,11 +46,14 @@ import { openInstanceMenu } from './_common_/common';
import { host } from '@/config';
import * as os from '@/os';
import { navbarItemDef } from '@/navbar';
-import { openAccountMenu } from '@/account';
+import { openAccountMenu, $i } from '@/account';
import MkButton from '@/components/MkButton.vue';
import { StickySidebar } from '@/scripts/sticky-sidebar';
import { mainRouter } from '@/router';
//import MisskeyLogo from '@assets/client/misskey.svg';
+import { defaultStore } from '@/store';
+import { instance } from '@/instance';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -66,12 +69,16 @@ export default defineComponent({
navbarItemDef: navbarItemDef,
iconOnly: false,
settingsWindowed: false,
+ defaultStore,
+ instance,
+ $i,
+ i18n,
};
},
computed: {
menu(): string[] {
- return this.$store.state.menu;
+ return this.defaultStore.state.menu;
},
otherNavItemIndicated(): boolean {
@@ -84,7 +91,7 @@ export default defineComponent({
},
watch: {
- '$store.reactiveState.menuDisplay.value'() {
+ 'defaultStore.reactiveState.menuDisplay.value'() {
this.calcViewState();
},
@@ -111,7 +118,7 @@ export default defineComponent({
openInstanceMenu,
calcViewState() {
- this.iconOnly = (window.innerWidth <= 1400) || (this.$store.state.menuDisplay === 'sideIcon');
+ this.iconOnly = (window.innerWidth <= 1400) || (this.defaultStore.state.menuDisplay === 'sideIcon');
this.settingsWindowed = (window.innerWidth > 1400);
},
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue
index a359463d9b..4838272a9e 100644
--- a/packages/frontend/src/ui/classic.vue
+++ b/packages/frontend/src/ui/classic.vue
@@ -21,7 +21,7 @@
</div>
</div>
- <Transition :name="$store.state.animation ? 'tray-back' : ''">
+ <Transition :name="defaultStore.state.animation ? 'tray-back' : ''">
<div
v-if="widgetsShowing"
class="tray-back _modalBg"
@@ -30,11 +30,11 @@
></div>
</Transition>
- <Transition :name="$store.state.animation ? 'tray' : ''">
+ <Transition :name="defaultStore.state.animation ? 'tray' : ''">
<XWidgets v-if="widgetsShowing" class="tray"/>
</Transition>
- <iframe v-if="$store.state.aiChanMode" ref="live2d" class="ivnzpscs" src="https://misskey-dev.github.io/mascot-web/?scale=2&y=1.4"></iframe>
+ <iframe v-if="defaultStore.state.aiChanMode" ref="live2d" class="ivnzpscs" src="https://misskey-dev.github.io/mascot-web/?scale=2&y=1.4"></iframe>
<XCommon/>
</div>
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index be168b4282..4db7c9413a 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -53,10 +53,10 @@
</div>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_menuDrawerBg_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_menuDrawerBg_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_menuDrawerBg_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_menuDrawerBg_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_leaveTo : ''"
>
<div
v-if="drawerMenuShowing"
@@ -68,10 +68,10 @@
</Transition>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_menuDrawer_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_menuDrawer_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_menuDrawer_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_menuDrawer_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_menuDrawer_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_menuDrawer_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_menuDrawer_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_menuDrawer_leaveTo : ''"
>
<div v-if="drawerMenuShowing" :class="$style.menu">
<XDrawerMenu/>
@@ -99,6 +99,7 @@ import { i18n } from '@/i18n';
import { mainRouter } from '@/router';
import { unisonReload } from '@/scripts/unison-reload';
import { deviceKind } from '@/scripts/device-kind';
+import { defaultStore } from '@/store';
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
mainRouter.navHook = (path, flag): boolean => {
diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue
index 11d1c85e38..ab3d01532b 100644
--- a/packages/frontend/src/ui/universal.vue
+++ b/packages/frontend/src/ui/universal.vue
@@ -27,10 +27,10 @@
</div>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_menuDrawerBg_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_menuDrawerBg_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_menuDrawerBg_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_menuDrawerBg_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_menuDrawerBg_leaveTo : ''"
>
<div
v-if="drawerMenuShowing"
@@ -42,10 +42,10 @@
</Transition>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_menuDrawer_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_menuDrawer_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_menuDrawer_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_menuDrawer_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_menuDrawer_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_menuDrawer_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_menuDrawer_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_menuDrawer_leaveTo : ''"
>
<div v-if="drawerMenuShowing" :class="$style.menuDrawer">
<XDrawerMenu/>
@@ -53,10 +53,10 @@
</Transition>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_widgetsDrawerBg_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_widgetsDrawerBg_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_widgetsDrawerBg_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_widgetsDrawerBg_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_widgetsDrawerBg_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_widgetsDrawerBg_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_widgetsDrawerBg_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_widgetsDrawerBg_leaveTo : ''"
>
<div
v-if="widgetsShowing"
@@ -68,10 +68,10 @@
</Transition>
<Transition
- :enter-active-class="$store.state.animation ? $style.transition_widgetsDrawer_enterActive : ''"
- :leave-active-class="$store.state.animation ? $style.transition_widgetsDrawer_leaveActive : ''"
- :enter-from-class="$store.state.animation ? $style.transition_widgetsDrawer_enterFrom : ''"
- :leave-to-class="$store.state.animation ? $style.transition_widgetsDrawer_leaveTo : ''"
+ :enter-active-class="defaultStore.state.animation ? $style.transition_widgetsDrawer_enterActive : ''"
+ :leave-active-class="defaultStore.state.animation ? $style.transition_widgetsDrawer_leaveActive : ''"
+ :enter-from-class="defaultStore.state.animation ? $style.transition_widgetsDrawer_enterFrom : ''"
+ :leave-to-class="defaultStore.state.animation ? $style.transition_widgetsDrawer_leaveTo : ''"
>
<div v-if="widgetsShowing" :class="$style.widgetsDrawer">
<button class="_button" :class="$style.widgetsCloseButton" @click="widgetsShowing = false"><i class="ti ti-x"></i></button>
diff --git a/packages/frontend/src/ui/visitor/a.vue b/packages/frontend/src/ui/visitor/a.vue
index 023b7fdb94..4761036075 100644
--- a/packages/frontend/src/ui/visitor/a.vue
+++ b/packages/frontend/src/ui/visitor/a.vue
@@ -1,19 +1,19 @@
<template>
<div class="mk-app">
- <div v-if="mainRouter.currentRoute?.name === 'index'" class="banner" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }">
+ <div v-if="mainRouter.currentRoute?.name === 'index'" class="banner" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }">
<div>
<h1 v-if="meta"><img v-if="meta.logoImageUrl" class="logo" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1>
<div v-if="meta" class="about">
<!-- eslint-disable-next-line vue/no-v-html -->
- <div class="desc" v-html="meta.description || $ts.introMisskey"></div>
+ <div class="desc" v-html="meta.description || i18n.ts.introMisskey"></div>
</div>
<div class="action">
- <button class="_button primary" @click="signup()">{{ $ts.signup }}</button>
- <button class="_button" @click="signin()">{{ $ts.login }}</button>
+ <button class="_button primary" @click="signup()">{{ i18n.ts.signup }}</button>
+ <button class="_button" @click="signin()">{{ i18n.ts.login }}</button>
</div>
</div>
</div>
- <div v-else class="banner-mini" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }">
+ <div v-else class="banner-mini" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }">
<div>
<h1 v-if="meta"><img v-if="meta.logoImageUrl" class="logo" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1>
</div>
@@ -42,8 +42,10 @@ import XHeader from './header.vue';
import { host, instanceName } from '@/config';
import * as os from '@/os';
import MkButton from '@/components/MkButton.vue';
-import { ColdDeviceStorage } from '@/store';
+import { defaultStore, ColdDeviceStorage } from '@/store';
import { mainRouter } from '@/router';
+import { instance } from '@/instance';
+import { i18n } from '@/i18n';
const DESKTOP_THRESHOLD = 1100;
@@ -66,6 +68,9 @@ export default defineComponent({
},
mainRouter,
isDesktop: window.innerWidth >= DESKTOP_THRESHOLD,
+ defaultStore,
+ instance,
+ i18n,
};
},
@@ -74,7 +79,7 @@ export default defineComponent({
return {
'd': () => {
if (ColdDeviceStorage.get('syncDeviceDarkMode')) return;
- this.$store.set('darkMode', !this.$store.state.darkMode);
+ this.defaultStore.set('darkMode', !this.defaultStore.state.darkMode);
},
's': () => {
mainRouter.push('/search');
diff --git a/packages/frontend/src/ui/visitor/b.vue b/packages/frontend/src/ui/visitor/b.vue
index e2168768e8..5287a670c5 100644
--- a/packages/frontend/src/ui/visitor/b.vue
+++ b/packages/frontend/src/ui/visitor/b.vue
@@ -24,7 +24,7 @@
</div>
</div>
- <Transition :name="$store.state.animation ? 'tray-back' : ''">
+ <Transition :name="'tray-back'">
<div
v-if="showMenu"
class="menu-back _modalBg"
@@ -33,20 +33,20 @@
></div>
</Transition>
- <Transition :name="$store.state.animation ? 'tray' : ''">
+ <Transition :name="'tray'">
<div v-if="showMenu" class="menu">
- <MkA to="/" class="link" active-class="active"><i class="ti ti-home icon"></i>{{ $ts.home }}</MkA>
- <MkA v-if="isTimelineAvailable" to="/timeline" class="link" active-class="active"><i class="ti ti-message icon"></i>{{ $ts.timeline }}</MkA>
- <MkA to="/explore" class="link" active-class="active"><i class="ti ti-hash icon"></i>{{ $ts.explore }}</MkA>
- <MkA to="/announcements" class="link" active-class="active"><i class="ti ti-speakerphone icon"></i>{{ $ts.announcements }}</MkA>
- <MkA to="/channels" class="link" active-class="active"><i class="ti ti-device-tv icon"></i>{{ $ts.channel }}</MkA>
+ <MkA to="/" class="link" active-class="active"><i class="ti ti-home icon"></i>{{ i18n.ts.home }}</MkA>
+ <MkA v-if="isTimelineAvailable" to="/timeline" class="link" active-class="active"><i class="ti ti-message icon"></i>{{ i18n.ts.timeline }}</MkA>
+ <MkA to="/explore" class="link" active-class="active"><i class="ti ti-hash icon"></i>{{ i18n.ts.explore }}</MkA>
+ <MkA to="/announcements" class="link" active-class="active"><i class="ti ti-speakerphone icon"></i>{{ i18n.ts.announcements }}</MkA>
+ <MkA to="/channels" class="link" active-class="active"><i class="ti ti-device-tv icon"></i>{{ i18n.ts.channel }}</MkA>
<div class="divider"></div>
- <MkA to="/pages" class="link" active-class="active"><i class="ti ti-news icon"></i>{{ $ts.pages }}</MkA>
+ <MkA to="/pages" class="link" active-class="active"><i class="ti ti-news icon"></i>{{ i18n.ts.pages }}</MkA>
<MkA to="/play" class="link" active-class="active"><i class="ti ti-player-play icon"></i>Play</MkA>
- <MkA to="/gallery" class="link" active-class="active"><i class="ti ti-icons icon"></i>{{ $ts.gallery }}</MkA>
+ <MkA to="/gallery" class="link" active-class="active"><i class="ti ti-icons icon"></i>{{ i18n.ts.gallery }}</MkA>
<div class="action">
- <button class="_buttonPrimary" @click="signup()">{{ $ts.signup }}</button>
- <button class="_button" @click="signin()">{{ $ts.login }}</button>
+ <button class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
+ <button class="_button" @click="signin()">{{ i18n.ts.login }}</button>
</div>
</div>
</Transition>
@@ -65,6 +65,7 @@ import XSignupDialog from '@/components/MkSignupDialog.vue';
import { ColdDeviceStorage, defaultStore } from '@/store';
import { mainRouter } from '@/router';
import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata';
+import { i18n } from '@/i18n';
const DESKTOP_THRESHOLD = 1100;
diff --git a/packages/frontend/src/ui/visitor/header.vue b/packages/frontend/src/ui/visitor/header.vue
index aaa7e77e90..7de81f6431 100644
--- a/packages/frontend/src/ui/visitor/header.vue
+++ b/packages/frontend/src/ui/visitor/header.vue
@@ -2,14 +2,14 @@
<div class="sqxihjet">
<div v-if="narrow === false" class="wide">
<div class="content">
- <MkA to="/" class="link" active-class="active"><i class="ti ti-home icon"></i>{{ $ts.home }}</MkA>
- <MkA v-if="isTimelineAvailable" to="/timeline" class="link" active-class="active"><i class="ti ti-message icon"></i>{{ $ts.timeline }}</MkA>
- <MkA to="/explore" class="link" active-class="active"><i class="ti ti-hash icon"></i>{{ $ts.explore }}</MkA>
- <MkA to="/channels" class="link" active-class="active"><i class="ti ti-device-tv icon"></i>{{ $ts.channel }}</MkA>
+ <MkA to="/" class="link" active-class="active"><i class="ti ti-home icon"></i>{{ i18n.ts.home }}</MkA>
+ <MkA v-if="isTimelineAvailable" to="/timeline" class="link" active-class="active"><i class="ti ti-message icon"></i>{{ i18n.ts.timeline }}</MkA>
+ <MkA to="/explore" class="link" active-class="active"><i class="ti ti-hash icon"></i>{{ i18n.ts.explore }}</MkA>
+ <MkA to="/channels" class="link" active-class="active"><i class="ti ti-device-tv icon"></i>{{ i18n.ts.channel }}</MkA>
<div class="right">
- <button class="_button search" @click="search()"><i class="ti ti-search icon"></i><span>{{ $ts.search }}</span></button>
- <button class="_buttonPrimary signup" @click="signup()">{{ $ts.signup }}</button>
- <button class="_button login" @click="signin()">{{ $ts.login }}</button>
+ <button class="_button search" @click="search()"><i class="ti ti-search icon"></i><span>{{ i18n.ts.search }}</span></button>
+ <button class="_buttonPrimary signup" @click="signup()">{{ i18n.ts.signup }}</button>
+ <button class="_button login" @click="signin()">{{ i18n.ts.login }}</button>
</div>
</div>
</div>
@@ -28,6 +28,7 @@ import XSignupDialog from '@/components/MkSignupDialog.vue';
import * as os from '@/os';
import { instance } from '@/instance';
import { mainRouter } from '@/router';
+import { i18n } from '@/i18n';
export default defineComponent({
data() {
@@ -35,6 +36,7 @@ export default defineComponent({
narrow: null,
showMenu: false,
isTimelineAvailable: instance.policies.ltlAvailable || instance.policies.gtlAvailable,
+ i18n,
};
},
diff --git a/packages/frontend/src/ui/visitor/kanban.vue b/packages/frontend/src/ui/visitor/kanban.vue
index 05ded834ee..ce7fcfe944 100644
--- a/packages/frontend/src/ui/visitor/kanban.vue
+++ b/packages/frontend/src/ui/visitor/kanban.vue
@@ -1,6 +1,6 @@
<!-- eslint-disable vue/no-v-html -->
<template>
-<div class="rwqkcmrc" :style="{ backgroundImage: transparent ? 'none' : `url(${ $instance.backgroundImageUrl })` }">
+<div class="rwqkcmrc" :style="{ backgroundImage: transparent ? 'none' : `url(${ instance.backgroundImageUrl })` }">
<div class="back" :class="{ transparent }"></div>
<div class="contents">
<div class="wrapper">
@@ -9,14 +9,14 @@
</h1>
<template v-if="full">
<div v-if="meta" class="about">
- <div class="desc" v-html="meta.description || $ts.introMisskey"></div>
+ <div class="desc" v-html="meta.description || i18n.ts.introMisskey"></div>
</div>
<div class="action">
- <button class="_buttonPrimary" @click="signup()">{{ $ts.signup }}</button>
- <button class="_button" @click="signin()">{{ $ts.login }}</button>
+ <button class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
+ <button class="_button" @click="signin()">{{ i18n.ts.login }}</button>
</div>
<div class="announcements panel">
- <header>{{ $ts.announcements }}</header>
+ <header>{{ i18n.ts.announcements }}</header>
<MkPagination v-slot="{items}" :pagination="announcements" class="list">
<section v-for="announcement in items" :key="announcement.id" class="item">
<div class="title">{{ announcement.title }}</div>
@@ -45,6 +45,8 @@ import MkPagination from '@/components/MkPagination.vue';
import XSigninDialog from '@/components/MkSigninDialog.vue';
import XSignupDialog from '@/components/MkSignupDialog.vue';
import MkButton from '@/components/MkButton.vue';
+import { instance } from '@/instance';
+import { i18n } from '@/i18n';
export default defineComponent({
components: {
@@ -81,6 +83,8 @@ export default defineComponent({
endpoint: 'announcements',
limit: 10,
},
+ instance,
+ i18n,
};
},
diff --git a/packages/frontend/src/widgets/WidgetCalendar.vue b/packages/frontend/src/widgets/WidgetCalendar.vue
index de2e4b179d..58d0732263 100644
--- a/packages/frontend/src/widgets/WidgetCalendar.vue
+++ b/packages/frontend/src/widgets/WidgetCalendar.vue
@@ -2,11 +2,11 @@
<div :class="[$style.root, { _panel: !widgetProps.transparent }]" data-cy-mkw-calendar>
<div :class="[$style.calendar, { [$style.isHoliday]: isHoliday }]">
<p :class="$style.monthAndYear">
- <span :class="$style.year">{{ $t('yearX', { year }) }}</span>
- <span :class="$style.month">{{ $t('monthX', { month }) }}</span>
+ <span :class="$style.year">{{ i18n.t('yearX', { year }) }}</span>
+ <span :class="$style.month">{{ i18n.t('monthX', { month }) }}</span>
</p>
- <p v-if="month === 1 && day === 1" class="day">🎉{{ $t('dayX', { day }) }}<span style="display: inline-block; transform: scaleX(-1);">🎉</span></p>
- <p v-else :class="$style.day">{{ $t('dayX', { day }) }}</p>
+ <p v-if="month === 1 && day === 1" class="day">🎉{{ i18n.t('dayX', { day }) }}<span style="display: inline-block; transform: scaleX(-1);">🎉</span></p>
+ <p v-else :class="$style.day">{{ i18n.t('dayX', { day }) }}</p>
<p :class="$style.weekDay">{{ weekDay }}</p>
</div>
<div :class="$style.info">
diff --git a/packages/frontend/src/widgets/WidgetFederation.vue b/packages/frontend/src/widgets/WidgetFederation.vue
index 7dcd5cb42e..2033b074e0 100644
--- a/packages/frontend/src/widgets/WidgetFederation.vue
+++ b/packages/frontend/src/widgets/WidgetFederation.vue
@@ -5,7 +5,7 @@
<div class="wbrkwalb">
<MkLoading v-if="fetching"/>
- <TransitionGroup v-else tag="div" :name="$store.state.animation ? 'chart' : ''" class="instances">
+ <TransitionGroup v-else tag="div" :name="defaultStore.state.animation ? 'chart' : ''" class="instances">
<div v-for="(instance, i) in instances" :key="instance.id" class="instance">
<img :src="getInstanceIcon(instance)" alt=""/>
<div class="body">
@@ -29,6 +29,7 @@ import * as os from '@/os';
import { useInterval } from '@/scripts/use-interval';
import { i18n } from '@/i18n';
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy';
+import { defaultStore } from '@/store';
const name = 'federation';
diff --git a/packages/frontend/src/widgets/WidgetInstanceInfo.vue b/packages/frontend/src/widgets/WidgetInstanceInfo.vue
index 3a3b071b7d..d702fd2cb0 100644
--- a/packages/frontend/src/widgets/WidgetInstanceInfo.vue
+++ b/packages/frontend/src/widgets/WidgetInstanceInfo.vue
@@ -1,12 +1,12 @@
<template>
<div class="_panel">
- <div :class="$style.container" :style="{ backgroundImage: $instance.bannerUrl ? `url(${ $instance.bannerUrl })` : null }">
+ <div :class="$style.container" :style="{ backgroundImage: instance.bannerUrl ? `url(${ instance.bannerUrl })` : null }">
<div :class="$style.iconContainer">
- <img :src="$instance.iconUrl ?? $instance.faviconUrl ?? '/favicon.ico'" alt="" :class="$style.icon"/>
+ <img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" alt="" :class="$style.icon"/>
</div>
<div :class="$style.bodyContainer">
<div :class="$style.body">
- <MkA :class="$style.name" to="/about" behavior="window">{{ $instance.name }}</MkA>
+ <MkA :class="$style.name" to="/about" behavior="window">{{ instance.name }}</MkA>
<div :class="$style.host">{{ host }}</div>
</div>
</div>
@@ -18,6 +18,7 @@
import { useWidgetPropsManager, Widget, WidgetComponentExpose } from './widget';
import { GetFormResultType } from '@/scripts/form';
import { host } from '@/config';
+import { instance } from '@/instance';
const name = 'instanceInfo';
diff --git a/packages/frontend/src/widgets/WidgetSlideshow.vue b/packages/frontend/src/widgets/WidgetSlideshow.vue
index 22a0024271..915e7aaaf4 100644
--- a/packages/frontend/src/widgets/WidgetSlideshow.vue
+++ b/packages/frontend/src/widgets/WidgetSlideshow.vue
@@ -4,7 +4,7 @@
<p v-if="widgetProps.folderId == null">
{{ i18n.ts.folder }}
</p>
- <p v-if="widgetProps.folderId != null && images.length === 0 && !fetching">{{ $t('no-image') }}</p>
+ <p v-if="widgetProps.folderId != null && images.length === 0 && !fetching">{{ i18n.t('no-image') }}</p>
<div ref="slideA" class="slide a"></div>
<div ref="slideB" class="slide b"></div>
</div>
diff --git a/packages/frontend/src/widgets/WidgetTimeline.vue b/packages/frontend/src/widgets/WidgetTimeline.vue
index 0f6f25b0a9..71ee75f6cb 100644
--- a/packages/frontend/src/widgets/WidgetTimeline.vue
+++ b/packages/frontend/src/widgets/WidgetTimeline.vue
@@ -10,7 +10,7 @@
</template>
<template #header>
<button class="_button" @click="choose">
- <span>{{ widgetProps.src === 'list' ? widgetProps.list.name : widgetProps.src === 'antenna' ? widgetProps.antenna.name : $t('_timelines.' + widgetProps.src) }}</span>
+ <span>{{ widgetProps.src === 'list' ? widgetProps.list.name : widgetProps.src === 'antenna' ? widgetProps.antenna.name : i18n.t('_timelines.' + widgetProps.src) }}</span>
<i :class="menuOpened ? 'ti ti-chevron-up' : 'ti ti-chevron-down'" style="margin-left: 8px;"></i>
</button>
</template>
diff --git a/packages/frontend/src/widgets/WidgetTrends.vue b/packages/frontend/src/widgets/WidgetTrends.vue
index fc8a310ece..01450a7ab5 100644
--- a/packages/frontend/src/widgets/WidgetTrends.vue
+++ b/packages/frontend/src/widgets/WidgetTrends.vue
@@ -5,11 +5,11 @@
<div class="wbrkwala">
<MkLoading v-if="fetching"/>
- <TransitionGroup v-else tag="div" :name="$store.state.animation ? 'chart' : ''" class="tags">
+ <TransitionGroup v-else tag="div" :name="defaultStore.state.animation ? 'chart' : ''" class="tags">
<div v-for="stat in stats" :key="stat.tag">
<div class="tag">
<MkA class="a" :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</MkA>
- <p>{{ $t('nUsersMentioned', { n: stat.usersCount }) }}</p>
+ <p>{{ i18n.t('nUsersMentioned', { n: stat.usersCount }) }}</p>
</div>
<MkMiniChart class="chart" :src="stat.chart"/>
</div>
@@ -27,6 +27,7 @@ import MkMiniChart from '@/components/MkMiniChart.vue';
import * as os from '@/os';
import { useInterval } from '@/scripts/use-interval';
import { i18n } from '@/i18n';
+import { defaultStore } from '@/store';
const name = 'hashtags';