This repository has been archived on 2025-01-27. You can view files and clone it, but cannot push or open issues or pull requests.
puyoskey-firefish/packages/client/src/init.ts
HidemaruOwO cdd8109e81 ♻️ Refer new firefish (.gitlab-ci.yml, .gitlab/issue_templates/default.md, .gitlab/issue_templates/discussion.md, .gitlab/issue_templates/feature.md, .gitlab/issue_templates/refactor.md, .gitlab/merge_request_templates/default.md, .gitlab/merge_request_templates/release.md, Cargo.lock, Cargo.toml, Dockerfile, dev/container/docker-compose.yml, dev/docs/local-installation.md, docs/changelog.md, docs/downgrade.sql, docs/install.md, docs/notice-for-admins.md, locales/ca-ES.yml, locales/en-US.yml, locales/eo.yml, locales/ja-JP.yml, locales/ko-KR.yml, locales/zh-CN.yml, locales/zh-TW.yml, package.json, packages/backend-rs/Cargo.toml, packages/backend-rs/index.d.ts, packages/backend-rs/index.js, packages/backend-rs/package.json, packages/backend-rs/src/cache/bare.rs, packages/backend-rs/src/cache/mod.rs, packages/backend-rs/src/cache/redis.rs, packages/backend-rs/src/config/meta.rs, packages/backend-rs/src/database/mod.rs, packages/backend-rs/src/federation/activitypub/object/accept.rs, packages/backend-rs/src/federation/activitypub/object/add.rs, packages/backend-rs/src/federation/activitypub/object/emoji.rs, packages/backend-rs/src/federation/activitypub/object/flag.rs, packages/backend-rs/src/federation/activitypub/object/follow.rs, packages/backend-rs/src/federation/activitypub/object/hashtag.rs, packages/backend-rs/src/federation/activitypub/object/like.rs, packages/backend-rs/src/federation/activitypub/object/mention.rs, packages/backend-rs/src/federation/activitypub/object/mod.rs, packages/backend-rs/src/federation/activitypub/object/read.rs, packages/backend-rs/src/federation/activitypub/object/reject.rs, packages/backend-rs/src/federation/activitypub/object/remove.rs, packages/backend-rs/src/federation/activitypub/object/tombstone.rs, packages/backend-rs/src/federation/internal_actor/instance.rs, packages/backend-rs/src/federation/internal_actor/relay.rs, packages/backend-rs/src/federation/nodeinfo/fetch.rs, packages/backend-rs/src/federation/nodeinfo/generate.rs, packages/backend-rs/src/init/system_info.rs, packages/backend-rs/src/lib.rs, packages/backend-rs/src/misc/emoji/mod.rs, packages/backend-rs/src/misc/emoji/reaction.rs, packages/backend-rs/src/misc/emoji/unicode.rs, packages/backend-rs/src/misc/get_image_size.rs, packages/backend-rs/src/misc/latest_version.rs, packages/backend-rs/src/misc/mod.rs, packages/backend-rs/src/misc/note/mod.rs, packages/backend-rs/src/misc/random_icon.rs, packages/backend-rs/src/misc/should_nyaify.rs, packages/backend-rs/src/misc/system_info.rs, packages/backend-rs/src/misc/translate.rs, packages/backend-rs/src/misc/user/mod.rs, packages/backend-rs/src/model/entity/abuse_user_report.rs, packages/backend-rs/src/model/entity/access_token.rs, packages/backend-rs/src/model/entity/ad.rs, packages/backend-rs/src/model/entity/announcement.rs, packages/backend-rs/src/model/entity/announcement_read.rs, packages/backend-rs/src/model/entity/antenna.rs, packages/backend-rs/src/model/entity/app.rs, packages/backend-rs/src/model/entity/attestation_challenge.rs, packages/backend-rs/src/model/entity/auth_session.rs, packages/backend-rs/src/model/entity/blocking.rs, packages/backend-rs/src/model/entity/channel.rs, packages/backend-rs/src/model/entity/channel_following.rs, packages/backend-rs/src/model/entity/channel_note_pining.rs, packages/backend-rs/src/model/entity/clip.rs, packages/backend-rs/src/model/entity/clip_note.rs, packages/backend-rs/src/model/entity/drive_file.rs, packages/backend-rs/src/model/entity/drive_folder.rs, packages/backend-rs/src/model/entity/emoji.rs, packages/backend-rs/src/model/entity/follow_request.rs, packages/backend-rs/src/model/entity/following.rs, packages/backend-rs/src/model/entity/gallery_like.rs, packages/backend-rs/src/model/entity/gallery_post.rs, packages/backend-rs/src/model/entity/hashtag.rs, packages/backend-rs/src/model/entity/instance.rs, packages/backend-rs/src/model/entity/messaging_message.rs, packages/backend-rs/src/model/entity/meta.rs, packages/backend-rs/src/model/entity/migrations.rs, packages/backend-rs/src/model/entity/mod.rs, packages/backend-rs/src/model/entity/moderation_log.rs, packages/backend-rs/src/model/entity/muted_note.rs, packages/backend-rs/src/model/entity/muting.rs, packages/backend-rs/src/model/entity/note.rs, packages/backend-rs/src/model/entity/note_edit.rs, packages/backend-rs/src/model/entity/note_favorite.rs, packages/backend-rs/src/model/entity/note_file.rs, packages/backend-rs/src/model/entity/note_reaction.rs, packages/backend-rs/src/model/entity/note_thread_muting.rs, packages/backend-rs/src/model/entity/note_unread.rs, packages/backend-rs/src/model/entity/note_watching.rs, packages/backend-rs/src/model/entity/notification.rs, packages/backend-rs/src/model/entity/page.rs, packages/backend-rs/src/model/entity/page_like.rs, packages/backend-rs/src/model/entity/password_reset_request.rs, packages/backend-rs/src/model/entity/poll.rs, packages/backend-rs/src/model/entity/poll_vote.rs, packages/backend-rs/src/model/entity/prelude.rs, packages/backend-rs/src/model/entity/promo_note.rs, packages/backend-rs/src/model/entity/promo_read.rs, packages/backend-rs/src/model/entity/registration_ticket.rs, packages/backend-rs/src/model/entity/registry_item.rs, packages/backend-rs/src/model/entity/relay.rs, packages/backend-rs/src/model/entity/renote_muting.rs, packages/backend-rs/src/model/entity/reply_muting.rs, packages/backend-rs/src/model/entity/sea_orm_active_enums.rs, packages/backend-rs/src/model/entity/signin.rs, packages/backend-rs/src/model/entity/sw_subscription.rs, packages/backend-rs/src/model/entity/used_username.rs, packages/backend-rs/src/model/entity/user.rs, packages/backend-rs/src/model/entity/user_group.rs, packages/backend-rs/src/model/entity/user_group_invitation.rs, packages/backend-rs/src/model/entity/user_group_invite.rs, packages/backend-rs/src/model/entity/user_group_joining.rs, packages/backend-rs/src/model/entity/user_ip.rs, packages/backend-rs/src/model/entity/user_keypair.rs, packages/backend-rs/src/model/entity/user_list.rs, packages/backend-rs/src/model/entity/user_list_joining.rs, packages/backend-rs/src/model/entity/user_note_pining.rs, packages/backend-rs/src/model/entity/user_pending.rs, packages/backend-rs/src/model/entity/user_profile.rs, packages/backend-rs/src/model/entity/user_publickey.rs, packages/backend-rs/src/model/entity/user_security_key.rs, packages/backend-rs/src/model/entity/webhook.rs, packages/backend-rs/src/service/antenna/check_hit.rs, packages/backend-rs/src/service/antenna/mod.rs, packages/backend-rs/src/service/antenna/process_new_note.rs, packages/backend-rs/src/service/antenna/update.rs, packages/backend-rs/src/service/push_notification.rs, packages/backend-rs/src/service/stream.rs, packages/backend-rs/src/util/id.rs, packages/backend/package.json, packages/backend/src/boot/master.ts, packages/backend/src/migration/1644010796173-convert-hard-mutes.ts, packages/backend/src/migration/1652859567549-uniform-themecolor.ts, packages/backend/src/migration/1722346019160-set-emoji-public-url.ts, packages/backend/src/models/entities/emoji.ts, packages/backend/src/models/entities/note.ts, packages/backend/src/models/entities/user-profile.ts, packages/backend/src/models/entities/user.ts, packages/backend/src/models/repositories/renote-muting.ts, packages/backend/src/models/repositories/reply-muting.ts, packages/backend/src/models/repositories/user.ts, packages/backend/src/queue/processors/db/import-firefish-post.ts, packages/backend/src/queue/processors/db/import-masto-post.ts, packages/backend/src/remote/activitypub/kernel/like.ts, packages/backend/src/remote/activitypub/misc/contexts.ts, packages/backend/src/remote/activitypub/models/person.ts, packages/backend/src/remote/activitypub/renderer/note.ts, packages/backend/src/remote/activitypub/renderer/person.ts, packages/backend/src/remote/activitypub/request.ts, packages/backend/src/remote/activitypub/resolver.ts, packages/backend/src/remote/activitypub/type.ts, packages/backend/src/server/activitypub.ts, packages/backend/src/server/api/common/inject-featured.ts, packages/backend/src/server/api/common/read-messaging-message.ts, packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts, packages/backend/src/server/api/endpoints/notes/featured.ts, packages/backend/src/server/api/mastodon/helpers/misc.ts, packages/backend/src/server/file/byte-range-readable.ts, packages/backend/src/server/index.ts, packages/backend/src/server/web/bios.css, packages/backend/src/server/web/cli.css, packages/backend/src/server/web/style.css, packages/backend/src/services/blocking/create.ts, packages/backend/src/services/fetch-instance-metadata.ts, packages/backend/src/services/following/create.ts, packages/backend/src/services/following/delete.ts, packages/backend/src/services/following/reject.ts, packages/backend/src/services/following/requests/accept.ts, packages/backend/src/services/following/requests/cancel.ts, packages/backend/src/services/following/requests/create.ts, packages/backend/src/services/i/pin.ts, packages/backend/src/services/logger.ts, packages/backend/src/services/messages/delete.ts, packages/backend/src/services/note/create.ts, packages/backend/src/services/note/delete.ts, packages/backend/src/services/note/reaction/create.ts, packages/backend/src/services/note/reaction/delete.ts, packages/client/package.json, packages/client/src/components/MkAbuseReport.vue, packages/client/src/components/MkAbuseReportWindow.vue, packages/client/src/components/MkAnnouncement.vue, packages/client/src/components/MkAutocomplete.vue, packages/client/src/components/MkAvatars.vue, packages/client/src/components/MkButton.vue, packages/client/src/components/MkChannelFollowButton.vue, packages/client/src/components/MkChannelPreview.vue, packages/client/src/components/MkChart.vue, packages/client/src/components/MkChartTooltip.vue, packages/client/src/components/MkChatPreview.vue, packages/client/src/components/MkContainer.vue, packages/client/src/components/MkCropperDialog.vue, packages/client/src/components/MkCwButton.vue, packages/client/src/components/MkDateSeparatedList.vue, packages/client/src/components/MkDialog.vue, packages/client/src/components/MkDonation.vue, packages/client/src/components/MkDrive.file.vue, packages/client/src/components/MkDrive.folder.vue, packages/client/src/components/MkDrive.navFolder.vue, packages/client/src/components/MkDrive.vue, packages/client/src/components/MkDriveFileThumbnail.vue, packages/client/src/components/MkDriveSelectDialog.vue, packages/client/src/components/MkEmojiPicker.section.vue, packages/client/src/components/MkEmojiPicker.vue, packages/client/src/components/MkEmojiPickerDialog.vue, packages/client/src/components/MkFileListForAdmin.vue, packages/client/src/components/MkFolder.vue, packages/client/src/components/MkFollowButton.vue, packages/client/src/components/MkForgotPassword.vue, packages/client/src/components/MkGalleryPostPreview.vue, packages/client/src/components/MkImageViewer.vue, packages/client/src/components/MkImgWithBlurhash.vue, packages/client/src/components/MkInfo.vue, packages/client/src/components/MkInstanceCardMini.vue, packages/client/src/components/MkInstanceSelectDialog.vue, packages/client/src/components/MkInstanceStats.vue, packages/client/src/components/MkInstanceTicker.vue, packages/client/src/components/MkKeyValue.vue, packages/client/src/components/MkLaunchPad.vue, packages/client/src/components/MkLink.vue, packages/client/src/components/MkManyAnnouncements.vue, packages/client/src/components/MkMedia.vue, packages/client/src/components/MkMediaBanner.vue, packages/client/src/components/MkMediaCaption.vue, packages/client/src/components/MkMediaList.vue, packages/client/src/components/MkMention.vue, packages/client/src/components/MkMenu.child.vue, packages/client/src/components/MkMenu.vue, packages/client/src/components/MkModPlayer.vue, packages/client/src/components/MkModal.vue, packages/client/src/components/MkModalPageWindow.vue, packages/client/src/components/MkModalWindow.vue, packages/client/src/components/MkMoved.vue, packages/client/src/components/MkNote.vue, packages/client/src/components/MkNoteDetailed.vue, packages/client/src/components/MkNotePreview.vue, packages/client/src/components/MkNoteSimple.vue, packages/client/src/components/MkNoteSub.vue, packages/client/src/components/MkNotification.vue, packages/client/src/components/MkNotificationFolded.vue, packages/client/src/components/MkNotificationToast.vue, packages/client/src/components/MkObjectView.value.vue, packages/client/src/components/MkPagePreview.vue, packages/client/src/components/MkPageWindow.vue, packages/client/src/components/MkPagination.vue, packages/client/src/components/MkPoll.vue, packages/client/src/components/MkPollEditor.vue, packages/client/src/components/MkPopupMenu.vue, packages/client/src/components/MkPostForm.vue, packages/client/src/components/MkPostFormAttaches.vue, packages/client/src/components/MkPostSearch.vue, packages/client/src/components/MkPullToRefresh.vue, packages/client/src/components/MkQrCode.vue, packages/client/src/components/MkQuoteButton.vue, packages/client/src/components/MkReactedUsers.vue, packages/client/src/components/MkReactionTooltip.vue, packages/client/src/components/MkReactionsViewer.details.vue, packages/client/src/components/MkReactionsViewer.reaction.vue, packages/client/src/components/MkReactionsViewer.vue, packages/client/src/components/MkRemoteCaution.vue, packages/client/src/components/MkRipple.vue, packages/client/src/components/MkSearchBar.vue, packages/client/src/components/MkShowMoreButton.vue, packages/client/src/components/MkSignin.vue, packages/client/src/components/MkSignup.vue, packages/client/src/components/MkSimpleTextWindow.vue, packages/client/src/components/MkSparkle.vue, packages/client/src/components/MkSuperMenu.vue, packages/client/src/components/MkTab.vue, packages/client/src/components/MkTagCloud.vue, packages/client/src/components/MkTimeline.vue, packages/client/src/components/MkToast.vue, packages/client/src/components/MkTokenGenerateWindow.vue, packages/client/src/components/MkTooltip.vue, packages/client/src/components/MkTutorialDialog.vue, packages/client/src/components/MkUpdated.vue, packages/client/src/components/MkUrlPreview.vue, packages/client/src/components/MkUrlPreviewPopup.vue, packages/client/src/components/MkUserCardMini.vue, packages/client/src/components/MkUserInfo.vue, packages/client/src/components/MkUserPreview.vue, packages/client/src/components/MkUserSelectDialog.vue, packages/client/src/components/MkUserSelectLocalDialog.vue, packages/client/src/components/MkUsersTooltip.vue, packages/client/src/components/MkVisibility.vue, packages/client/src/components/MkVisibilityPicker.vue, packages/client/src/components/MkWaitingDialog.vue, packages/client/src/components/MkWidgets.vue, packages/client/src/components/MkWindow.vue, packages/client/src/components/form/checkbox.vue, packages/client/src/components/form/folder.vue, packages/client/src/components/form/input.vue, packages/client/src/components/form/link.vue, packages/client/src/components/form/radio.vue, packages/client/src/components/form/radios.vue, packages/client/src/components/form/range.vue, packages/client/src/components/form/section.vue, packages/client/src/components/form/select.vue, packages/client/src/components/form/slot.vue, packages/client/src/components/form/suspense.vue, packages/client/src/components/form/switch.vue, packages/client/src/components/form/textarea.vue, packages/client/src/components/global/MkAd.vue, packages/client/src/components/global/MkAvatar.vue, packages/client/src/components/global/MkEmoji.vue, packages/client/src/components/global/MkError.vue, packages/client/src/components/global/MkLoading.vue, packages/client/src/components/global/MkMisskeyFlavoredMarkdown.vue, packages/client/src/components/global/MkPageHeader.vue, packages/client/src/components/global/MkSpacer.vue, packages/client/src/components/global/MkStickyContainer.vue, packages/client/src/components/global/MkUrl.vue, packages/client/src/components/note/MkNoteContent.vue, packages/client/src/components/note/MkNoteFooter.vue, packages/client/src/components/note/MkNoteFooterInfo.vue, packages/client/src/components/note/MkNoteHeader.vue, packages/client/src/components/note/MkNoteHeaderInfo.vue, packages/client/src/components/note/MkNoteMedia.vue, packages/client/src/components/note/MkNoteTranslation.vue, packages/client/src/components/note/MkRenoteBar.vue, packages/client/src/components/page/page.button.vue, packages/client/src/components/page/page.canvas.vue, packages/client/src/components/page/page.counter.vue, packages/client/src/components/page/page.note.vue, packages/client/src/components/page/page.number-input.vue, packages/client/src/components/page/page.post.vue, packages/client/src/components/page/page.section.vue, packages/client/src/components/page/page.switch.vue, packages/client/src/components/page/page.text-input.vue, packages/client/src/components/page/page.text.vue, packages/client/src/init.ts, packages/client/src/navbar.ts, packages/client/src/pages/_error_.vue, packages/client/src/pages/about-firefish.vue, packages/client/src/pages/about.emojis.vue, packages/client/src/pages/about.federation.vue, packages/client/src/pages/about.vue, packages/client/src/pages/admin-file.vue, packages/client/src/pages/admin/_header_.vue, packages/client/src/pages/admin/abuses.vue, packages/client/src/pages/admin/emoji-edit-dialog.vue, packages/client/src/pages/admin/emojis.vue, packages/client/src/pages/admin/files.vue, packages/client/src/pages/admin/index.vue, packages/client/src/pages/admin/overview.federation.vue, packages/client/src/pages/admin/overview.metrics.vue, packages/client/src/pages/admin/overview.moderators.vue, packages/client/src/pages/admin/overview.queue.vue, packages/client/src/pages/admin/overview.stats.vue, packages/client/src/pages/admin/overview.user.vue, packages/client/src/pages/admin/promotions.vue, packages/client/src/pages/admin/queue.chart.vue, packages/client/src/pages/admin/relays.vue, packages/client/src/pages/admin/settings.vue, packages/client/src/pages/admin/users.vue, packages/client/src/pages/announcements.vue, packages/client/src/pages/channel-editor.vue, packages/client/src/pages/channel.vue, packages/client/src/pages/channels.vue, packages/client/src/pages/clip.vue, packages/client/src/pages/emojis.emoji.vue, packages/client/src/pages/explore.featured.vue, packages/client/src/pages/explore.users.vue, packages/client/src/pages/explore.vue, packages/client/src/pages/follow-requests-sent.vue, packages/client/src/pages/follow-requests.vue, packages/client/src/pages/gallery/edit.vue, packages/client/src/pages/gallery/index.vue, packages/client/src/pages/gallery/post.vue, packages/client/src/pages/instance-info.vue, packages/client/src/pages/messaging/index.vue, packages/client/src/pages/messaging/messaging-room.form.vue, packages/client/src/pages/messaging/messaging-room.message.vue, packages/client/src/pages/messaging/messaging-room.vue, packages/client/src/pages/mfm-cheat-sheet.vue, packages/client/src/pages/miauth.vue, packages/client/src/pages/my-antennas/editor.vue, packages/client/src/pages/my-antennas/index.vue, packages/client/src/pages/my-clips/index.vue, packages/client/src/pages/my-groups/group.vue, packages/client/src/pages/my-groups/index.vue, packages/client/src/pages/my-lists/index.vue, packages/client/src/pages/my-lists/list.vue, packages/client/src/pages/no-graze.vue, packages/client/src/pages/note.vue, packages/client/src/pages/notifications.vue, packages/client/src/pages/oauth.vue, packages/client/src/pages/page-editor/els/page-editor.el.button.vue, packages/client/src/pages/page-editor/els/page-editor.el.if.vue, packages/client/src/pages/page-editor/els/page-editor.el.image.vue, packages/client/src/pages/page-editor/els/page-editor.el.note.vue, packages/client/src/pages/page-editor/els/page-editor.el.switch.vue, packages/client/src/pages/page-editor/els/page-editor.el.text.vue, packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue, packages/client/src/pages/page-editor/page-editor.container.vue, packages/client/src/pages/page-editor/page-editor.script-block.vue, packages/client/src/pages/page-editor/page-editor.vue, packages/client/src/pages/page.vue, packages/client/src/pages/pages.vue, packages/client/src/pages/scratchpad.vue, packages/client/src/pages/search.vue, packages/client/src/pages/settings/2fa.qrdialog.vue, packages/client/src/pages/settings/2fa.vue, packages/client/src/pages/settings/accounts.vue, packages/client/src/pages/settings/apps.vue, packages/client/src/pages/settings/deck.vue, packages/client/src/pages/settings/drive.vue, packages/client/src/pages/settings/general.vue, packages/client/src/pages/settings/import-export.vue, packages/client/src/pages/settings/index.vue, packages/client/src/pages/settings/instance-mute.vue, packages/client/src/pages/settings/migration.vue, packages/client/src/pages/settings/mute-block.vue, packages/client/src/pages/settings/navbar.vue, packages/client/src/pages/settings/other.vue, packages/client/src/pages/settings/plugin.vue, packages/client/src/pages/settings/profile.vue, packages/client/src/pages/settings/reaction.vue, packages/client/src/pages/settings/security.vue, packages/client/src/pages/settings/sounds.vue, packages/client/src/pages/settings/statusbar.vue, packages/client/src/pages/settings/theme.vue, packages/client/src/pages/settings/word-mute.vue, packages/client/src/pages/share.vue, packages/client/src/pages/tag.vue, packages/client/src/pages/theme-editor.vue, packages/client/src/pages/timeline.vue, packages/client/src/pages/user-info.vue, packages/client/src/pages/user-list-timeline.vue, packages/client/src/pages/user/clips.vue, packages/client/src/pages/user/home.vue, packages/client/src/pages/user/index.photos.vue, packages/client/src/pages/user/index.timeline.vue, packages/client/src/pages/user/index.vue, packages/client/src/pages/user/media-list.vue, packages/client/src/pages/user/reactions.vue, packages/client/src/pages/welcome.entrance.a.vue, packages/client/src/pages/welcome.entrance.b.vue, packages/client/src/pages/welcome.entrance.c.vue, packages/client/src/pages/welcome.setup.vue, packages/client/src/pages/welcome.timeline.vue, packages/client/src/scripts/get-note-menu.ts, packages/client/src/scripts/get-user-menu.ts, packages/client/src/store.ts, packages/client/src/style.scss, packages/client/src/ui/_common_/common.vue, packages/client/src/ui/_common_/navbar-for-mobile.vue, packages/client/src/ui/_common_/navbar.vue, packages/client/src/ui/_common_/statusbar-federation.vue, packages/client/src/ui/_common_/statusbar-rss.vue, packages/client/src/ui/_common_/statusbar-user-list.vue, packages/client/src/ui/_common_/statusbars.vue, packages/client/src/ui/_common_/stream-indicator.vue, packages/client/src/ui/_common_/upload.vue, packages/client/src/ui/deck.vue, packages/client/src/ui/deck/antenna-column.vue, packages/client/src/ui/deck/channel-column.vue, packages/client/src/ui/deck/column.vue, packages/client/src/ui/deck/direct-column.vue, packages/client/src/ui/deck/list-column.vue, packages/client/src/ui/deck/mentions-column.vue, packages/client/src/ui/deck/notifications-column.vue, packages/client/src/ui/deck/tl-column.vue, packages/client/src/ui/deck/widgets-column.vue, packages/client/src/ui/universal.vue, packages/client/src/ui/universal.widgets.vue, packages/client/src/ui/visitor/a.vue, packages/client/src/ui/visitor/b.vue, packages/client/src/ui/visitor/header.vue, packages/client/src/ui/visitor/kanban.vue, packages/client/src/ui/zen.vue, packages/client/src/widgets/aiscript.vue, packages/client/src/widgets/calendar.vue, packages/client/src/widgets/clock.vue, packages/client/src/widgets/digital-clock.vue, packages/client/src/widgets/federation.vue, packages/client/src/widgets/instance-cloud.vue, packages/client/src/widgets/job-queue.vue, packages/client/src/widgets/memo.vue, packages/client/src/widgets/notifications.vue, packages/client/src/widgets/online-users.vue, packages/client/src/widgets/photos.vue, packages/client/src/widgets/rss-ticker.vue, packages/client/src/widgets/rss.vue, packages/client/src/widgets/server-info.vue, packages/client/src/widgets/server-metric/cpu-mem.vue, packages/client/src/widgets/server-metric/cpu.vue, packages/client/src/widgets/server-metric/disk.vue, packages/client/src/widgets/server-metric/mem.vue, packages/client/src/widgets/server-metric/pie.vue, packages/client/src/widgets/slideshow.vue, packages/client/src/widgets/timeline.vue, packages/client/src/widgets/trends.vue, packages/client/src/widgets/unix-clock.vue, packages/client/vite.config.ts, packages/firefish-js/package.json, packages/firefish-js/src/index.ts, packages/firefish-js/src/misc/langmap.ts, packages/macro-rs/macros-impl/src/lib.rs, packages/macro-rs/macros/src/lib.rs, packages/sw/package.json, packages/sw/src/scripts/notification-read.ts, packages/sw/vite.config.ts, pnpm-lock.yaml)
2024-08-23 02:17:33 +09:00

570 lines
14 KiB
TypeScript

/**
* Client entry point
*/
// https://vitejs.dev/config/build-options.html#build-modulepreload
import "vite/modulepreload-polyfill";
import "@/style.scss";
import "@phosphor-icons/web/bold";
import "@phosphor-icons/web/duotone";
import "@phosphor-icons/web/fill";
import "@phosphor-icons/web/light";
import "@phosphor-icons/web/regular";
// #region IndexDB migrations
const accounts = localStorage.getItem("accounts");
if (accounts) {
set("accounts", JSON.parse(accounts));
localStorage.removeItem("accounts");
}
localStorage.removeItem("instance");
// #endregion
import {
computed,
createApp,
defineAsyncComponent,
markRaw,
version as vueVersion,
watch,
} from "vue";
import { set } from "@/scripts/idb-proxy";
import { refreshAccount, signIn, signOut, updateAccount } from "@/account";
import components from "@/components";
import { lang, ui, version } from "@/config";
import directives from "@/directives";
import { i18n } from "@/i18n";
import { getInstanceInfo, initializeInstanceCache } from "@/instance";
import { isSignedIn, me } from "@/me";
import { alert, api, confirm, popup, post, toast } from "@/os";
import { deviceKind } from "@/scripts/device-kind";
import { getAccountFromId } from "@/scripts/get-account-from-id";
import { makeHotkey } from "@/scripts/hotkey";
import { initializeSw } from "@/scripts/initialize-sw";
import { isDeviceDarkmode } from "@/scripts/is-device-darkmode";
import { getUrlWithoutLoginId } from "@/scripts/login-id";
import { reactionPicker } from "@/scripts/reaction-picker";
import { search } from "@/scripts/search";
import * as sound from "@/scripts/sound";
import { applyTheme } from "@/scripts/theme";
import { reloadChannel } from "@/scripts/unison-reload";
import { ColdDeviceStorage, defaultStore } from "@/store";
import { isReloading, useStream } from "@/stream";
import widgets from "@/widgets";
function checkForSplash() {
const splash = document.getElementById("splash");
// 念のためnullチェック(HTMLが古い場合があるため(そのうち消す))
if (splash) {
splash.style.opacity = "0";
splash.style.pointerEvents = "none";
// remove splash screen
window.setTimeout(() => {
splash.remove();
}, 1000);
}
}
(async () => {
await initializeInstanceCache();
const instance = getInstanceInfo();
console.info(`Firefish v${version}`);
if (_DEV_) {
console.warn("Development mode!!!");
console.info(`vue ${vueVersion}`);
window.addEventListener("error", (event) => {
console.error(event);
/*
alert({
type: 'error',
title: 'DEV: Unhandled error',
text: event.message
});
*/
});
window.addEventListener("unhandledrejection", (event) => {
console.error(event);
/*
alert({
type: 'error',
title: 'DEV: Unhandled promise rejection',
text: event.reason
});
*/
});
}
// タッチデバイスでCSSの:hoverを機能させる
document.addEventListener("touchend", () => {}, { passive: true });
// 一斉リロード
reloadChannel.addEventListener("message", (path) => {
if (path !== null) location.href = path;
else location.reload();
});
// #region Set lang attr
const html = document.documentElement;
html.setAttribute("lang", lang || "en-US");
html.setAttribute(
"dir",
[
"ar",
"arc",
"dv",
"fa",
"ha",
"he",
"iw",
"ktw",
"ks",
"ku",
"pk",
"ps",
"ug",
"ur",
"xb",
"yi",
].includes((lang ?? "en").split("-")[0])
? "rtl"
: "ltr",
);
const writingMode = localStorage.getItem("writingMode");
switch (writingMode) {
case "vertical-lr-upright":
html.classList.add("vertical-lr");
html.classList.add("upright");
break;
case "vertical-lr":
html.classList.add("vertical-lr");
break;
case "vertical-rl-upright":
html.classList.add("vertical-rl");
html.classList.add("upright");
break;
case "vertical-rl":
html.classList.add("vertical-rl");
break;
}
// #endregion
// #region loginId
const params = new URLSearchParams(location.search);
const loginId = params.get("loginId");
if (loginId) {
const target = getUrlWithoutLoginId(location.href);
if (!me || me.id !== loginId) {
const account = await getAccountFromId(loginId);
if (account) {
await signIn(account.token, target);
}
}
history.replaceState({ misskey: "loginId" }, "", target);
}
// #endregion
// #region Fetch user
if (me?.token) {
if (_DEV_) {
console.log("account cache found. refreshing...");
}
refreshAccount();
} else {
if (_DEV_) {
console.log("no account cache found.");
}
// 連携ログインの場合用にCookieを参照する
const i = (document.cookie.match(/igi=(\w+)/) || [null, null])[1];
if (i != null && i !== "null") {
if (_DEV_) {
console.log("signing...");
}
try {
document.body.innerHTML = "<div>Please wait...</div>";
await signIn(i);
} catch (err) {
// Render the error screen
// TODO: ちゃんとしたコンポーネントをレンダリングする(v10とかのトラブルシューティングゲーム付きのやつみたいな)
document.body.innerHTML = '<div id="err">Oops!</div>';
}
} else {
if (_DEV_) {
console.log("not signed in");
}
}
}
// #endregion
localStorage.setItem("v", instance.version);
// Init service worker
initializeSw();
const app = createApp(
window.location.search === "?zen"
? defineAsyncComponent(() => import("@/ui/zen.vue"))
: !me
? defineAsyncComponent(() => import("@/ui/visitor.vue"))
: ui === "deck"
? defineAsyncComponent(() => import("@/ui/deck.vue"))
: defineAsyncComponent(() => import("@/ui/universal.vue")),
);
if (_DEV_) {
app.config.performance = true;
}
widgets(app);
directives(app);
components(app);
checkForSplash();
// https://github.com/misskey-dev/misskey/pull/8575#issuecomment-1114239210
// なぜかinit.tsの内容が2回実行されることがあるため、mountするdivを1つに制限する
const rootEl = (() => {
const MISSKEY_MOUNT_DIV_ID = "firefish_app";
const currentEl = document.getElementById(MISSKEY_MOUNT_DIV_ID);
if (currentEl) {
console.warn("multiple import detected");
return currentEl;
}
const rootEl = document.createElement("div");
rootEl.id = MISSKEY_MOUNT_DIV_ID;
document.body.appendChild(rootEl);
return rootEl;
})();
app.mount(rootEl);
// boot.jsのやつを解除
window.onerror = null;
window.onunhandledrejection = null;
reactionPicker.init();
checkForSplash();
// クライアントが更新されたか?
const lastVersion = localStorage.getItem("lastVersion");
if (lastVersion !== version) {
localStorage.setItem("lastVersion", version);
// テーマリビルドするため
localStorage.removeItem("theme");
if (
lastVersion != null &&
lastVersion < version &&
defaultStore.state.showUpdates
) {
// ログインしてる場合だけ
if (me) {
popup(
defineAsyncComponent(() => import("@/components/MkUpdated.vue")),
{},
{},
"closed",
);
}
}
}
if (
isSignedIn(me) &&
defaultStore.state.tutorial === -1 &&
!["/announcements", "/announcements/"].includes(window.location.pathname)
) {
api("announcements", { withUnreads: true, limit: 10 })
.then((announcements) => {
const unreadAnnouncements = announcements.filter((item) => {
return !item.isRead;
});
if (unreadAnnouncements.length > 3) {
popup(
defineAsyncComponent(
() => import("@/components/MkManyAnnouncements.vue"),
),
{},
{},
"closed",
);
} else {
for (const item of unreadAnnouncements) {
if (item.showPopup)
popup(
defineAsyncComponent(
() => import("@/components/MkAnnouncement.vue"),
),
{ announcement: item },
{},
"closed",
);
}
}
})
.catch((err) => console.log(err));
}
// NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため)
watch(
defaultStore.reactiveState.darkMode,
(darkMode) => {
applyTheme(
darkMode
? ColdDeviceStorage.get("darkTheme")
: ColdDeviceStorage.get("lightTheme"),
);
},
{ immediate: localStorage.theme == null },
);
const darkTheme = computed(ColdDeviceStorage.makeGetterSetter("darkTheme"));
const lightTheme = computed(ColdDeviceStorage.makeGetterSetter("lightTheme"));
watch(darkTheme, (theme) => {
if (defaultStore.state.darkMode) {
applyTheme(theme);
}
});
watch(lightTheme, (theme) => {
if (!defaultStore.state.darkMode) {
applyTheme(theme);
}
});
// #region Sync dark mode
if (ColdDeviceStorage.get("syncDeviceDarkMode")) {
defaultStore.set("darkMode", isDeviceDarkmode());
}
window.matchMedia("(prefers-color-scheme: dark)").onchange = (mql) => {
if (ColdDeviceStorage.get("syncDeviceDarkMode")) {
defaultStore.set("darkMode", mql.matches);
}
};
// #endregion
const { defaultLightTheme, defaultDarkTheme } = instance;
if (defaultStore.state.themeInitial) {
if (defaultLightTheme != null)
ColdDeviceStorage.set("lightTheme", JSON.parse(defaultLightTheme));
if (defaultDarkTheme != null)
ColdDeviceStorage.set("darkTheme", JSON.parse(defaultDarkTheme));
defaultStore.set("themeInitial", false);
}
watch(
defaultStore.reactiveState.useBlurEffectForModal,
(v) => {
document.documentElement.style.setProperty(
"--modalBgFilter",
v ? "blur(4px)" : "none",
);
},
{ immediate: true },
);
watch(
defaultStore.reactiveState.useBlurEffect,
(v) => {
if (v && deviceKind !== "smartphone") {
document.documentElement.style.removeProperty("--blur");
} else {
document.documentElement.style.setProperty("--blur", "none");
}
},
{ immediate: true },
);
let reloadDialogShowing = false;
const stream = useStream();
stream.on("_disconnected_", async () => {
if (isReloading) return;
if (defaultStore.state.serverDisconnectedBehavior === "reload") {
location.reload();
} else if (defaultStore.state.serverDisconnectedBehavior === "dialog") {
if (reloadDialogShowing) return;
reloadDialogShowing = true;
const { canceled } = await confirm({
type: "warning",
title: i18n.ts.disconnectedFromServer,
text: i18n.ts.reloadConfirm,
});
reloadDialogShowing = false;
if (!canceled) {
location.reload();
}
}
});
stream.on("emojiAdded", (emojiData) => {
// TODO
// store.commit('instance/set', );
});
for (const plugin of ColdDeviceStorage.get("plugins").filter(
(p) => p.active,
)) {
import("./plugin").then(({ install }) => {
install(plugin);
});
}
const hotkeys = {
d: (): void => {
defaultStore.set("darkMode", !defaultStore.state.darkMode);
},
s: search,
};
if (isSignedIn(me)) {
// only add post shortcuts if logged in
hotkeys["p|n"] = post;
if (me.isDeleted) {
alert({
type: "warning",
text: i18n.ts.accountDeletionInProgress,
});
}
const lastUsed = localStorage.getItem("lastUsed");
if (lastUsed) {
const lastUsedDate = Number.parseInt(lastUsed, 10);
// 二時間以上前なら
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
toast(
i18n.t("welcomeBackWithName", {
name: me.name || me.username,
}),
);
}
}
localStorage.setItem("lastUsed", Date.now().toString());
const latestDonationInfoShownAt = localStorage.getItem(
"latestDonationInfoShownAt",
);
const neverShowDonationInfo = localStorage.getItem("neverShowDonationInfo");
if (
neverShowDonationInfo !== "true" &&
new Date(me.createdAt).getTime() < Date.now() - 1000 * 60 * 60 * 24 * 3 &&
!location.pathname.startsWith("/miauth")
) {
if (
latestDonationInfoShownAt == null ||
new Date(latestDonationInfoShownAt).getTime() <
Date.now() - 1000 * 60 * 60 * 24 * 30
) {
popup(
defineAsyncComponent(() => import("@/components/MkDonation.vue")),
{},
{},
"closed",
);
}
}
if ("Notification" in window) {
// 許可を得ていなかったらリクエスト
if (Notification.permission === "default") {
Notification.requestPermission();
}
}
const main = markRaw(stream.useChannel("main", null, "System"));
// 自分の情報が更新されたとき
main.on("meUpdated", (i) => {
updateAccount(i);
});
main.on("readAllNotifications", () => {
updateAccount({ hasUnreadNotification: false });
});
main.on("unreadNotification", () => {
updateAccount({ hasUnreadNotification: true });
});
main.on("unreadMention", () => {
updateAccount({ hasUnreadMentions: true });
});
main.on("readAllUnreadMentions", () => {
updateAccount({ hasUnreadMentions: false });
});
main.on("unreadSpecifiedNote", () => {
updateAccount({ hasUnreadSpecifiedNotes: true });
});
main.on("readAllUnreadSpecifiedNotes", () => {
updateAccount({ hasUnreadSpecifiedNotes: false });
});
main.on("readAllMessagingMessages", () => {
updateAccount({ hasUnreadMessagingMessage: false });
});
main.on("unreadMessagingMessage", () => {
updateAccount({ hasUnreadMessagingMessage: true });
sound.play("chatBg");
});
main.on("readAllAntennas", () => {
updateAccount({ hasUnreadAntenna: false });
});
main.on("unreadAntenna", () => {
updateAccount({ hasUnreadAntenna: true });
sound.play("antenna");
});
main.on("readAllAnnouncements", () => {
updateAccount({ hasUnreadAnnouncement: false });
});
main.on("readAllChannels", () => {
updateAccount({ hasUnreadChannel: false });
});
main.on("unreadChannel", () => {
updateAccount({ hasUnreadChannel: true });
sound.play("channel");
});
// トークンが再生成されたとき
// このままではMisskeyが利用できないので強制的にサインアウトさせる
main.on("myTokenRegenerated", () => {
signOut();
});
}
// shortcut
document.addEventListener("keydown", makeHotkey(hotkeys));
})();