Merge branch 'develop' into feat-12997
This commit is contained in:
commit
d7061126cd
|
@ -0,0 +1,203 @@
|
||||||
|
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
# Misskey configuration
|
||||||
|
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
|
# ┌─────┐
|
||||||
|
#───┘ URL └─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Final accessible URL seen by a user.
|
||||||
|
url: 'http://misskey.local'
|
||||||
|
|
||||||
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
|
# URL SETTINGS AFTER THAT!
|
||||||
|
|
||||||
|
# ┌───────────────────────┐
|
||||||
|
#───┘ Port and TLS settings └───────────────────────────────────
|
||||||
|
|
||||||
|
#
|
||||||
|
# Misskey requires a reverse proxy to support HTTPS connections.
|
||||||
|
#
|
||||||
|
# +----- https://example.tld/ ------------+
|
||||||
|
# +------+ |+-------------+ +----------------+|
|
||||||
|
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
||||||
|
# +------+ |+-------------+ +----------------+|
|
||||||
|
# +---------------------------------------+
|
||||||
|
#
|
||||||
|
# You need to set up a reverse proxy. (e.g. nginx)
|
||||||
|
# An encrypted connection with HTTPS is highly recommended
|
||||||
|
# because tokens may be transferred in GET requests.
|
||||||
|
|
||||||
|
# The port that your Misskey server should listen on.
|
||||||
|
port: 61812
|
||||||
|
|
||||||
|
# ┌──────────────────────────┐
|
||||||
|
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||||
|
|
||||||
|
db:
|
||||||
|
host: db
|
||||||
|
port: 5432
|
||||||
|
|
||||||
|
# Database name
|
||||||
|
db: misskey
|
||||||
|
|
||||||
|
# Auth
|
||||||
|
user: postgres
|
||||||
|
pass: postgres
|
||||||
|
|
||||||
|
# Whether disable Caching queries
|
||||||
|
#disableCache: true
|
||||||
|
|
||||||
|
# Extra Connection options
|
||||||
|
#extra:
|
||||||
|
# ssl: true
|
||||||
|
|
||||||
|
dbReplications: false
|
||||||
|
|
||||||
|
# You can configure any number of replicas here
|
||||||
|
#dbSlaves:
|
||||||
|
# -
|
||||||
|
# host:
|
||||||
|
# port:
|
||||||
|
# db:
|
||||||
|
# user:
|
||||||
|
# pass:
|
||||||
|
# -
|
||||||
|
# host:
|
||||||
|
# port:
|
||||||
|
# db:
|
||||||
|
# user:
|
||||||
|
# pass:
|
||||||
|
|
||||||
|
# ┌─────────────────────┐
|
||||||
|
#───┘ Redis configuration └─────────────────────────────────────
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: redis
|
||||||
|
port: 6379
|
||||||
|
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||||
|
#pass: example-pass
|
||||||
|
#prefix: example-prefix
|
||||||
|
#db: 1
|
||||||
|
|
||||||
|
#redisForPubsub:
|
||||||
|
# host: redis
|
||||||
|
# port: 6379
|
||||||
|
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||||
|
# #pass: example-pass
|
||||||
|
# #prefix: example-prefix
|
||||||
|
# #db: 1
|
||||||
|
|
||||||
|
#redisForJobQueue:
|
||||||
|
# host: redis
|
||||||
|
# port: 6379
|
||||||
|
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||||
|
# #pass: example-pass
|
||||||
|
# #prefix: example-prefix
|
||||||
|
# #db: 1
|
||||||
|
|
||||||
|
#redisForTimelines:
|
||||||
|
# host: redis
|
||||||
|
# port: 6379
|
||||||
|
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||||
|
# #pass: example-pass
|
||||||
|
# #prefix: example-prefix
|
||||||
|
# #db: 1
|
||||||
|
|
||||||
|
# ┌───────────────────────────┐
|
||||||
|
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||||
|
|
||||||
|
#meilisearch:
|
||||||
|
# host: meilisearch
|
||||||
|
# port: 7700
|
||||||
|
# apiKey: ''
|
||||||
|
# ssl: true
|
||||||
|
# index: ''
|
||||||
|
|
||||||
|
# ┌───────────────┐
|
||||||
|
#───┘ ID generation └───────────────────────────────────────────
|
||||||
|
|
||||||
|
# You can select the ID generation method.
|
||||||
|
# You don't usually need to change this setting, but you can
|
||||||
|
# change it according to your preferences.
|
||||||
|
|
||||||
|
# Available methods:
|
||||||
|
# aid ... Short, Millisecond accuracy
|
||||||
|
# aidx ... Millisecond accuracy
|
||||||
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
|
# ulid ... Millisecond accuracy
|
||||||
|
# objectid ... This is left for backward compatibility
|
||||||
|
|
||||||
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
|
id: 'aidx'
|
||||||
|
|
||||||
|
# ┌────────────────┐
|
||||||
|
#───┘ Error tracking └──────────────────────────────────────────
|
||||||
|
|
||||||
|
# Sentry is available for error tracking.
|
||||||
|
# See the Sentry documentation for more details on options.
|
||||||
|
|
||||||
|
#sentryForBackend:
|
||||||
|
# enableNodeProfiling: true
|
||||||
|
# options:
|
||||||
|
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||||
|
|
||||||
|
#sentryForFrontend:
|
||||||
|
# options:
|
||||||
|
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||||
|
|
||||||
|
# ┌─────────────────────┐
|
||||||
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
|
# Whether disable HSTS
|
||||||
|
#disableHsts: true
|
||||||
|
|
||||||
|
# Number of worker processes
|
||||||
|
#clusterLimit: 1
|
||||||
|
|
||||||
|
# Job concurrency per worker
|
||||||
|
# deliverJobConcurrency: 128
|
||||||
|
# inboxJobConcurrency: 16
|
||||||
|
|
||||||
|
# Job rate limiter
|
||||||
|
# deliverJobPerSec: 128
|
||||||
|
# inboxJobPerSec: 32
|
||||||
|
|
||||||
|
# Job attempts
|
||||||
|
# deliverJobMaxAttempts: 12
|
||||||
|
# inboxJobMaxAttempts: 8
|
||||||
|
|
||||||
|
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||||
|
#outgoingAddressFamily: ipv4
|
||||||
|
|
||||||
|
# Proxy for HTTP/HTTPS
|
||||||
|
#proxy: http://127.0.0.1:3128
|
||||||
|
|
||||||
|
proxyBypassHosts:
|
||||||
|
- api.deepl.com
|
||||||
|
- api-free.deepl.com
|
||||||
|
- www.recaptcha.net
|
||||||
|
- hcaptcha.com
|
||||||
|
- challenges.cloudflare.com
|
||||||
|
|
||||||
|
# Proxy for SMTP/SMTPS
|
||||||
|
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||||
|
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||||
|
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||||
|
|
||||||
|
# Media Proxy
|
||||||
|
#mediaProxy: https://example.com/proxy
|
||||||
|
|
||||||
|
# Proxy remote files (default: true)
|
||||||
|
proxyRemoteFiles: true
|
||||||
|
|
||||||
|
# Sign to ActivityPub GET request (default: true)
|
||||||
|
signToActivityPubGet: true
|
||||||
|
|
||||||
|
allowedPrivateNetworks: [
|
||||||
|
'127.0.0.1/32'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Upload or download file size limits (bytes)
|
||||||
|
#maxFileSize: 262144000
|
|
@ -3,6 +3,8 @@
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
sudo chown node node_modules
|
sudo chown node node_modules
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
||||||
git config --global --add safe.directory /workspace
|
git config --global --add safe.directory /workspace
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
corepack install
|
corepack install
|
||||||
|
@ -12,3 +14,4 @@ pnpm install --frozen-lockfile
|
||||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
cp .devcontainer/devcontainer.yml .config/default.yml
|
||||||
pnpm build
|
pnpm build
|
||||||
pnpm migrate
|
pnpm migrate
|
||||||
|
pnpm exec cypress install
|
||||||
|
|
|
@ -35,6 +35,7 @@ coverage
|
||||||
!/.config/example.yml
|
!/.config/example.yml
|
||||||
!/.config/docker_example.yml
|
!/.config/docker_example.yml
|
||||||
!/.config/docker_example.env
|
!/.config/docker_example.env
|
||||||
|
!/.config/cypress-devcontainer.yml
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
compose.yml
|
compose.yml
|
||||||
.devcontainer/compose.yml
|
.devcontainer/compose.yml
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
- 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です
|
- 埋め込みコードやウェブサイトへの実装方法の詳細はMisskey Hubに掲載予定です
|
||||||
- Feat: チュートリアルと初期設定ダイアログを統合
|
- Feat: チュートリアルと初期設定ダイアログを統合
|
||||||
- 管理者は新規登録したユーザーにチュートリアルを強制することができるように
|
- 管理者は新規登録したユーザーにチュートリアルを強制することができるように
|
||||||
- サイズ制限を超過するファイルをアップロードしようとした際にエラーを出すように
|
- Enhance: サイズ制限を超過するファイルをアップロードしようとした際にエラーを出すように
|
||||||
- Enhance: アイコンデコレーション管理画面にプレビューを追加
|
- Enhance: アイコンデコレーション管理画面にプレビューを追加
|
||||||
- Fix: サーバーメトリクスが2つ以上あるとリロード直後の表示がおかしくなる問題を修正
|
- Fix: サーバーメトリクスが2つ以上あるとリロード直後の表示がおかしくなる問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- ファイルがサイズの制限を超えてアップロードされた際にエラーを返さなかった問題を修正
|
- Fix: ファイルがサイズの制限を超えてアップロードされた際にエラーを返さなかった問題を修正
|
||||||
|
|
||||||
|
|
||||||
## 2024.8.0
|
## 2024.8.0
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
"cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts",
|
"cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts",
|
||||||
"cy:run": "pnpm cypress run",
|
"cy:run": "pnpm cypress run",
|
||||||
"e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
"e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
||||||
|
"e2e-dev-container": "cp ./.config/cypress-devcontainer.yml ./.config/test.yml && pnpm start-server-and-test start:test http://localhost:61812 cy:run",
|
||||||
"jest": "cd packages/backend && pnpm jest",
|
"jest": "cd packages/backend && pnpm jest",
|
||||||
"jest-and-coverage": "cd packages/backend && pnpm jest-and-coverage",
|
"jest-and-coverage": "cd packages/backend && pnpm jest-and-coverage",
|
||||||
"test": "pnpm -r test",
|
"test": "pnpm -r test",
|
||||||
|
|
|
@ -10,23 +10,42 @@ import '@tabler/icons-webfont/dist/tabler-icons.scss';
|
||||||
|
|
||||||
import '@/style.scss';
|
import '@/style.scss';
|
||||||
import { createApp, defineAsyncComponent } from 'vue';
|
import { createApp, defineAsyncComponent } from 'vue';
|
||||||
import lightTheme from '@@/themes/l-light.json5';
|
import defaultLightTheme from '@@/themes/l-light.json5';
|
||||||
import darkTheme from '@@/themes/d-dark.json5';
|
import defaultDarkTheme from '@@/themes/d-dark.json5';
|
||||||
import { MediaProxy } from '@@/js/media-proxy.js';
|
import { MediaProxy } from '@@/js/media-proxy.js';
|
||||||
import { applyTheme } from './theme.js';
|
import { applyTheme, assertIsTheme } from '@/theme.js';
|
||||||
import { fetchCustomEmojis } from './custom-emojis.js';
|
import { fetchCustomEmojis } from '@/custom-emojis.js';
|
||||||
import { DI } from './di.js';
|
import { DI } from '@/di.js';
|
||||||
import { serverMetadata } from './server-metadata.js';
|
import { serverMetadata } from '@/server-metadata.js';
|
||||||
import { url } from './config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { parseEmbedParams } from '@@/js/embed-page.js';
|
import { parseEmbedParams } from '@@/js/embed-page.js';
|
||||||
import { postMessageToParentWindow, setIframeId } from '@/post-message.js';
|
import { postMessageToParentWindow, setIframeId } from '@/post-message.js';
|
||||||
|
|
||||||
console.info('Misskey Embed');
|
import type { Theme } from '@/theme.js';
|
||||||
|
|
||||||
|
console.log('Misskey Embed');
|
||||||
|
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const embedParams = parseEmbedParams(params);
|
const embedParams = parseEmbedParams(params);
|
||||||
|
|
||||||
console.info(embedParams);
|
if (_DEV_) console.log(embedParams);
|
||||||
|
|
||||||
|
function parseThemeOrNull(theme: string | null): Theme | null {
|
||||||
|
if (theme == null) return null;
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(theme);
|
||||||
|
if (assertIsTheme(parsed)) {
|
||||||
|
return parsed;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lightTheme = parseThemeOrNull(serverMetadata.defaultLightTheme) ?? defaultLightTheme;
|
||||||
|
const darkTheme = parseThemeOrNull(serverMetadata.defaultDarkTheme) ?? defaultDarkTheme;
|
||||||
|
|
||||||
if (embedParams.colorMode === 'dark') {
|
if (embedParams.colorMode === 'dark') {
|
||||||
applyTheme(darkTheme);
|
applyTheme(darkTheme);
|
||||||
|
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { toUnicode } from 'punycode/';
|
import { toUnicode } from 'punycode/';
|
||||||
import { host as hostRaw } from '@/config.js';
|
import { host as hostRaw } from '@@/js/config.js';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
user: Misskey.entities.UserLite;
|
user: Misskey.entities.UserLite;
|
||||||
|
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import DrawBlurhash from '@/workers/draw-blurhash?worker';
|
import DrawBlurhash from '@/workers/draw-blurhash?worker';
|
||||||
import TestWebGL2 from '@/workers/test-webgl2?worker';
|
import TestWebGL2 from '@/workers/test-webgl2?worker';
|
||||||
import { WorkerMultiDispatch } from '@/to-be-shared/worker-multi-dispatch.js';
|
import { WorkerMultiDispatch } from '@@/js/worker-multi-dispatch.js';
|
||||||
import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurhash.js';
|
import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurhash.js';
|
||||||
|
|
||||||
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
||||||
|
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import EmA from './EmA.vue';
|
import EmA from './EmA.vue';
|
||||||
import { url as local } from '@/config.js';
|
import { url as local } from '@@/js/config.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
url: string;
|
url: string;
|
||||||
|
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { toUnicode } from 'punycode';
|
import { toUnicode } from 'punycode';
|
||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { host as localHost } from '@/config.js';
|
import { host as localHost } from '@@/js/config.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
username: string;
|
username: string;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import EmMention from '@/components/EmMention.vue';
|
||||||
import EmEmoji from '@/components/EmEmoji.vue';
|
import EmEmoji from '@/components/EmEmoji.vue';
|
||||||
import EmCustomEmoji from '@/components/EmCustomEmoji.vue';
|
import EmCustomEmoji from '@/components/EmCustomEmoji.vue';
|
||||||
import EmA from '@/components/EmA.vue';
|
import EmA from '@/components/EmA.vue';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
|
|
||||||
function safeParseFloat(str: unknown): number | null {
|
function safeParseFloat(str: unknown): number | null {
|
||||||
if (typeof str !== 'string' || str === '') return null;
|
if (typeof str !== 'string' || str === '') return null;
|
||||||
|
|
|
@ -121,8 +121,8 @@ import EmUserName from '@/components/EmUserName.vue';
|
||||||
import EmTime from '@/components/EmTime.vue';
|
import EmTime from '@/components/EmTime.vue';
|
||||||
import { userPage } from '@/utils.js';
|
import { userPage } from '@/utils.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { shouldCollapsed } from '@/to-be-shared/collapsed.js';
|
import { shouldCollapsed } from '@@/js/collapsed.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
|
|
||||||
function getAppearNote(note: Misskey.entities.Note) {
|
function getAppearNote(note: Misskey.entities.Note) {
|
||||||
return Misskey.note.isPureRenote(note) ? note.renote : note;
|
return Misskey.note.isPureRenote(note) ? note.renote : note;
|
||||||
|
|
|
@ -142,9 +142,9 @@ import EmAcct from '@/components/EmAcct.vue';
|
||||||
import { userPage } from '@/utils.js';
|
import { userPage } from '@/utils.js';
|
||||||
import { notePage } from '@/utils.js';
|
import { notePage } from '@/utils.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { shouldCollapsed } from '@/to-be-shared/collapsed.js';
|
import { shouldCollapsed } from '@@/js/collapsed.js';
|
||||||
import { serverMetadata } from '@/server-metadata.js';
|
import { serverMetadata } from '@/server-metadata.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import EmMfm from '@/components/EmMfm.js';
|
import EmMfm from '@/components/EmMfm.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
|
@ -35,8 +35,8 @@ import * as Misskey from 'misskey-js';
|
||||||
import EmMediaList from '@/components/EmMediaList.vue';
|
import EmMediaList from '@/components/EmMediaList.vue';
|
||||||
import EmPoll from '@/components/EmPoll.vue';
|
import EmPoll from '@/components/EmPoll.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { shouldCollapsed } from '@/to-be-shared/collapsed.js';
|
import { shouldCollapsed } from '@@/js/collapsed.js';
|
||||||
import EmA from '@/components/EmA.vue';
|
import EmA from '@/components/EmA.vue';
|
||||||
import EmMfm from '@/components/EmMfm.js';
|
import EmMfm from '@/components/EmMfm.js';
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, ref, computed } from 'vue';
|
import { onMounted, onUnmounted, ref, computed } from 'vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { dateTimeFormat } from '@/to-be-shared/intl-const.js';
|
import { dateTimeFormat } from '@@/js/intl-const.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
time: Date | string | number | null;
|
time: Date | string | number | null;
|
||||||
|
|
|
@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { toUnicode as decodePunycode } from 'punycode/';
|
import { toUnicode as decodePunycode } from 'punycode/';
|
||||||
import EmA from './EmA.vue';
|
import EmA from './EmA.vue';
|
||||||
import { url as local } from '@/config.js';
|
import { url as local } from '@@/js/config.js';
|
||||||
|
|
||||||
function safeURIDecode(str: string): string {
|
function safeURIDecode(str: string): string {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { markRaw } from 'vue';
|
import { markRaw } from 'vue';
|
||||||
import { I18n } from '@@/js/i18n.js';
|
import { I18n } from '@@/js/i18n.js';
|
||||||
import type { Locale } from '../../../locales/index.js';
|
import type { Locale } from '../../../locales/index.js';
|
||||||
import { locale } from '@/config.js';
|
import { locale } from '@@/js/config.js';
|
||||||
|
|
||||||
export const i18n = markRaw(new I18n<Locale>(locale, _DEV_));
|
export const i18n = markRaw(new I18n<Locale>(locale, _DEV_));
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { apiUrl } from '@/config.js';
|
import { apiUrl } from '@@/js/config.js';
|
||||||
|
|
||||||
export const pendingApiRequestsCount = ref(0);
|
export const pendingApiRequestsCount = ref(0);
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
|
||||||
import { misskeyApi } from '@/misskey-api.js';
|
import { misskeyApi } from '@/misskey-api.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { serverMetadata } from '@/server-metadata.js';
|
import { serverMetadata } from '@/server-metadata.js';
|
||||||
import { url, instanceName } from '@/config.js';
|
import { url, instanceName } from '@@/js/config.js';
|
||||||
import { isLink } from '@/to-be-shared/is-link.js';
|
import { isLink } from '@@/js/is-link.js';
|
||||||
import { defaultEmbedParams } from '@@/js/embed-page.js';
|
import { defaultEmbedParams } from '@@/js/embed-page.js';
|
||||||
import { DI } from '@/di.js';
|
import { DI } from '@/di.js';
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ misskeyApi('clips/show', {
|
||||||
|
|
||||||
.instanceIcon {
|
.instanceIcon {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border-radius: 4px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -46,8 +46,8 @@ import XNotFound from '@/pages/not-found.vue';
|
||||||
import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
|
import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { serverMetadata } from '@/server-metadata.js';
|
import { serverMetadata } from '@/server-metadata.js';
|
||||||
import { url, instanceName } from '@/config.js';
|
import { url, instanceName } from '@@/js/config.js';
|
||||||
import { isLink } from '@/to-be-shared/is-link.js';
|
import { isLink } from '@@/js/is-link.js';
|
||||||
import { DI } from '@/di.js';
|
import { DI } from '@/di.js';
|
||||||
import { defaultEmbedParams } from '@@/js/embed-page.js';
|
import { defaultEmbedParams } from '@@/js/embed-page.js';
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ function top(ev: MouseEvent) {
|
||||||
|
|
||||||
.instanceIcon {
|
.instanceIcon {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border-radius: 4px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -59,7 +59,7 @@ import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
|
||||||
import { misskeyApi } from '@/misskey-api.js';
|
import { misskeyApi } from '@/misskey-api.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { serverMetadata } from '@/server-metadata.js';
|
import { serverMetadata } from '@/server-metadata.js';
|
||||||
import { url, instanceName } from '@/config.js';
|
import { url, instanceName } from '@@/js/config.js';
|
||||||
import { defaultEmbedParams } from '@@/js/embed-page.js';
|
import { defaultEmbedParams } from '@@/js/embed-page.js';
|
||||||
import { DI } from '@/di.js';
|
import { DI } from '@/di.js';
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ misskeyApi('users/show', {
|
||||||
|
|
||||||
.instanceIcon {
|
.instanceIcon {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border-radius: 4px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
import { misskeyApi } from '@/misskey-api.js';
|
import { misskeyApi } from '@/misskey-api.js';
|
||||||
|
|
||||||
const providedMetaEl = document.getElementById('misskey_meta');
|
const providedMetaEl = document.getElementById('misskey_meta');
|
||||||
|
|
||||||
const _serverMetadata = (providedMetaEl && providedMetaEl.textContent) ? JSON.parse(providedMetaEl.textContent) : null;
|
const _serverMetadata: Misskey.entities.MetaDetailed | null = (providedMetaEl && providedMetaEl.textContent) ? JSON.parse(providedMetaEl.textContent) : null;
|
||||||
|
|
||||||
// NOTE: devモードのときしか _serverMetadata が null になることは無い
|
// NOTE: devモードのときしか _serverMetadata が null になることは無い
|
||||||
export const serverMetadata = _serverMetadata ?? await misskeyApi('meta', {
|
export const serverMetadata: Misskey.entities.MetaDetailed = _serverMetadata ?? await misskeyApi('meta', {
|
||||||
detail: true,
|
detail: true,
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,6 +26,10 @@ export type Theme = {
|
||||||
|
|
||||||
let timeout: number | null = null;
|
let timeout: number | null = null;
|
||||||
|
|
||||||
|
export function assertIsTheme(theme: Record<string, unknown>): theme is Theme {
|
||||||
|
return typeof theme === 'object' && theme !== null && 'id' in theme && 'name' in theme && 'author' in theme && 'props' in theme;
|
||||||
|
}
|
||||||
|
|
||||||
export function applyTheme(theme: Theme, persist = true) {
|
export function applyTheme(theme: Theme, persist = true) {
|
||||||
if (timeout) window.clearTimeout(timeout);
|
if (timeout) window.clearTimeout(timeout);
|
||||||
|
|
||||||
|
@ -35,8 +39,6 @@ export function applyTheme(theme: Theme, persist = true) {
|
||||||
document.documentElement.classList.remove('_themeChanging_');
|
document.documentElement.classList.remove('_themeChanging_');
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
const colorScheme = theme.base === 'dark' ? 'dark' : 'light';
|
|
||||||
|
|
||||||
// Deep copy
|
// Deep copy
|
||||||
const _theme = JSON.parse(JSON.stringify(theme));
|
const _theme = JSON.parse(JSON.stringify(theme));
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ export function applyTheme(theme: Theme, persist = true) {
|
||||||
document.documentElement.style.setProperty(`--${k}`, v.toString());
|
document.documentElement.style.setProperty(`--${k}`, v.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
document.documentElement.style.setProperty('color-scheme', colorScheme);
|
// iframeを正常に透過させるために、cssのcolor-schemeは `light dark;` 固定にしてある。style.scss参照
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile(theme: Theme): Record<string, string> {
|
function compile(theme: Theme): Record<string, string> {
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
function defaultUseWorkerNumber(prev: number, totalWorkers: number) {
|
|
||||||
return prev + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WorkerMultiDispatch<POST = any, RETURN = any> {
|
|
||||||
private symbol = Symbol('WorkerMultiDispatch');
|
|
||||||
private workers: Worker[] = [];
|
|
||||||
private terminated = false;
|
|
||||||
private prevWorkerNumber = 0;
|
|
||||||
private getUseWorkerNumber = defaultUseWorkerNumber;
|
|
||||||
private finalizationRegistry: FinalizationRegistry<symbol>;
|
|
||||||
|
|
||||||
constructor(workerConstructor: () => Worker, concurrency: number, getUseWorkerNumber = defaultUseWorkerNumber) {
|
|
||||||
this.getUseWorkerNumber = getUseWorkerNumber;
|
|
||||||
for (let i = 0; i < concurrency; i++) {
|
|
||||||
this.workers.push(workerConstructor());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.finalizationRegistry = new FinalizationRegistry(() => {
|
|
||||||
this.terminate();
|
|
||||||
});
|
|
||||||
this.finalizationRegistry.register(this, this.symbol);
|
|
||||||
|
|
||||||
if (_DEV_) console.log('WorkerMultiDispatch: Created', this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public postMessage(message: POST, options?: Transferable[] | StructuredSerializeOptions, useWorkerNumber: typeof defaultUseWorkerNumber = this.getUseWorkerNumber) {
|
|
||||||
let workerNumber = useWorkerNumber(this.prevWorkerNumber, this.workers.length);
|
|
||||||
workerNumber = Math.abs(Math.round(workerNumber)) % this.workers.length;
|
|
||||||
if (_DEV_) console.log('WorkerMultiDispatch: Posting message to worker', workerNumber, useWorkerNumber);
|
|
||||||
this.prevWorkerNumber = workerNumber;
|
|
||||||
|
|
||||||
// 不毛だがunionをoverloadに突っ込めない
|
|
||||||
// https://stackoverflow.com/questions/66507585/overload-signatures-union-types-and-no-overload-matches-this-call-error
|
|
||||||
// https://github.com/microsoft/TypeScript/issues/14107
|
|
||||||
if (Array.isArray(options)) {
|
|
||||||
this.workers[workerNumber].postMessage(message, options);
|
|
||||||
} else {
|
|
||||||
this.workers[workerNumber].postMessage(message, options);
|
|
||||||
}
|
|
||||||
return workerNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public addListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
|
||||||
this.workers.forEach(worker => {
|
|
||||||
worker.addEventListener('message', callback, options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
|
||||||
this.workers.forEach(worker => {
|
|
||||||
worker.removeEventListener('message', callback, options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public terminate() {
|
|
||||||
this.terminated = true;
|
|
||||||
if (_DEV_) console.log('WorkerMultiDispatch: Terminating', this);
|
|
||||||
this.workers.forEach(worker => {
|
|
||||||
worker.terminate();
|
|
||||||
});
|
|
||||||
this.workers = [];
|
|
||||||
this.finalizationRegistry.unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public isTerminated() {
|
|
||||||
return this.terminated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getWorkers() {
|
|
||||||
return this.workers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getSymbol() {
|
|
||||||
return this.symbol;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -40,7 +40,7 @@ import XNotFound from '@/pages/not-found.vue';
|
||||||
|
|
||||||
const page = location.pathname.split('/')[2];
|
const page = location.pathname.split('/')[2];
|
||||||
const contentId = location.pathname.split('/')[3];
|
const contentId = location.pathname.split('/')[3];
|
||||||
console.log(page, contentId);
|
if (_DEV_) console.log(page, contentId);
|
||||||
|
|
||||||
const embedParams = inject(DI.embedParams, defaultEmbedParams);
|
const embedParams = inject(DI.embedParams, defaultEmbedParams);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
|
|
||||||
export const acct = (user: Misskey.Acct) => {
|
export const acct = (user: Misskey.Acct) => {
|
||||||
return Misskey.acct.toString(user);
|
return Misskey.acct.toString(user);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
type FIXME = any;
|
||||||
|
|
||||||
|
declare const _LANGS_: string[][];
|
||||||
|
declare const _VERSION_: string;
|
||||||
|
declare const _ENV_: string;
|
||||||
|
declare const _DEV_: boolean;
|
||||||
|
declare const _PERF_PREFIX_: string;
|
||||||
|
declare const _DATA_TRANSFER_DRIVE_FILE_: string;
|
||||||
|
declare const _DATA_TRANSFER_DRIVE_FOLDER_: string;
|
||||||
|
declare const _DATA_TRANSFER_DECK_COLUMN_: string;
|
||||||
|
|
||||||
|
// for dev-mode
|
||||||
|
declare const _LANGS_FULL_: string[][];
|
||||||
|
|
||||||
|
// TagCanvas
|
||||||
|
interface Window {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
TagCanvas: any;
|
||||||
|
}
|
|
@ -14,7 +14,11 @@ export default [
|
||||||
},
|
},
|
||||||
...pluginVue.configs['flat/recommended'],
|
...pluginVue.configs['flat/recommended'],
|
||||||
{
|
{
|
||||||
files: ['js/**/*.{ts,vue}', '**/*.vue'],
|
files: [
|
||||||
|
'@types/**/*.ts',
|
||||||
|
'js/**/*.ts',
|
||||||
|
'**/*.vue',
|
||||||
|
],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: {
|
globals: {
|
||||||
...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])),
|
...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])),
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as Misskey from 'misskey-js';
|
||||||
|
|
||||||
export function shouldCollapsed(note: Misskey.entities.Note, urls: string[]): boolean {
|
export function shouldCollapsed(note: Misskey.entities.Note, urls: string[]): boolean {
|
||||||
const collapsed = note.cw == null && (
|
const collapsed = note.cw == null && (
|
||||||
note.text != null && (
|
(note.text != null && (
|
||||||
(note.text.includes('$[x2')) ||
|
(note.text.includes('$[x2')) ||
|
||||||
(note.text.includes('$[x3')) ||
|
(note.text.includes('$[x3')) ||
|
||||||
(note.text.includes('$[x4')) ||
|
(note.text.includes('$[x4')) ||
|
||||||
|
@ -15,7 +15,7 @@ export function shouldCollapsed(note: Misskey.entities.Note, urls: string[]): bo
|
||||||
(note.text.split('\n').length > 9) ||
|
(note.text.split('\n').length > 9) ||
|
||||||
(note.text.length > 500) ||
|
(note.text.length > 500) ||
|
||||||
(urls.length >= 4)
|
(urls.length >= 4)
|
||||||
) || note.files.length >= 5
|
)) || (note.files != null && note.files.length >= 5)
|
||||||
);
|
);
|
||||||
|
|
||||||
return collapsed;
|
return collapsed;
|
|
@ -3,6 +3,9 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { Locale } from '../../../locales/index.js';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||||
const address = new URL(document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || location.href);
|
const address = new URL(document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || location.href);
|
||||||
const siteName = document.querySelector<HTMLMetaElement>('meta[property="og:site_name"]')?.content;
|
const siteName = document.querySelector<HTMLMetaElement>('meta[property="og:site_name"]')?.content;
|
||||||
|
|
||||||
|
@ -10,9 +13,16 @@ export const host = address.host;
|
||||||
export const hostname = address.hostname;
|
export const hostname = address.hostname;
|
||||||
export const url = address.origin;
|
export const url = address.origin;
|
||||||
export const apiUrl = location.origin + '/api';
|
export const apiUrl = location.origin + '/api';
|
||||||
|
export const wsOrigin = location.origin;
|
||||||
export const lang = localStorage.getItem('lang') ?? 'en-US';
|
export const lang = localStorage.getItem('lang') ?? 'en-US';
|
||||||
export const langs = _LANGS_;
|
export const langs = _LANGS_;
|
||||||
const preParseLocale = localStorage.getItem('locale');
|
const preParseLocale = localStorage.getItem('locale');
|
||||||
export const locale = preParseLocale ? JSON.parse(preParseLocale) : null;
|
export let locale: Locale = preParseLocale ? JSON.parse(preParseLocale) : null;
|
||||||
export const instanceName = siteName === 'Misskey' || siteName == null ? host : siteName;
|
export const version = _VERSION_;
|
||||||
|
export const instanceName = (siteName === 'Misskey' || siteName == null) ? host : siteName;
|
||||||
|
export const ui = localStorage.getItem('ui');
|
||||||
export const debug = localStorage.getItem('debug') === 'true';
|
export const debug = localStorage.getItem('debug') === 'true';
|
||||||
|
|
||||||
|
export function updateLocale(newLocale: Locale): void {
|
||||||
|
locale = newLocale;
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ export function char2fluentEmojiFilePath(char: string): string {
|
||||||
// Fluent Emojiは国旗非対応 https://github.com/microsoft/fluentui-emoji/issues/25
|
// Fluent Emojiは国旗非対応 https://github.com/microsoft/fluentui-emoji/issues/25
|
||||||
if (codes[0]?.startsWith('1f1')) return char2twemojiFilePath(char);
|
if (codes[0]?.startsWith('1f1')) return char2twemojiFilePath(char);
|
||||||
if (!codes.includes('200d')) codes = codes.filter(x => x !== 'fe0f');
|
if (!codes.includes('200d')) codes = codes.filter(x => x !== 'fe0f');
|
||||||
codes = codes.filter(x => x && x.length);
|
codes = codes.filter(x => x != null && x.length > 0);
|
||||||
const fileName = codes.map(x => x!.padStart(4, '0')).join('-');
|
const fileName = (codes as string[]).map(x => x.padStart(4, '0')).join('-');
|
||||||
return `${fluentEmojiPngBase}/${fileName}.png`;
|
return `${fluentEmojiPngBase}/${fileName}.png`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { lang } from '@/config.js';
|
import { lang } from '@@/js/config.js';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
export const versatileLang = (lang ?? 'ja-JP').replace('ja-KS', 'ja-JP');
|
export const versatileLang = (lang ?? 'ja-JP').replace('ja-KS', 'ja-JP');
|
||||||
|
|
||||||
let _dateTimeFormat: Intl.DateTimeFormat;
|
let _dateTimeFormat: Intl.DateTimeFormat;
|
|
@ -3,16 +3,18 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function defaultUseWorkerNumber(prev: number, totalWorkers: number) {
|
function defaultUseWorkerNumber(prev: number) {
|
||||||
return prev + 1;
|
return prev + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WorkerMultiDispatch<POST = any, RETURN = any> {
|
type WorkerNumberGetter = (prev: number, totalWorkers: number) => number;
|
||||||
|
|
||||||
|
export class WorkerMultiDispatch<POST = unknown, RETURN = unknown> {
|
||||||
private symbol = Symbol('WorkerMultiDispatch');
|
private symbol = Symbol('WorkerMultiDispatch');
|
||||||
private workers: Worker[] = [];
|
private workers: Worker[] = [];
|
||||||
private terminated = false;
|
private terminated = false;
|
||||||
private prevWorkerNumber = 0;
|
private prevWorkerNumber = 0;
|
||||||
private getUseWorkerNumber = defaultUseWorkerNumber;
|
private getUseWorkerNumber: WorkerNumberGetter;
|
||||||
private finalizationRegistry: FinalizationRegistry<symbol>;
|
private finalizationRegistry: FinalizationRegistry<symbol>;
|
||||||
|
|
||||||
constructor(workerConstructor: () => Worker, concurrency: number, getUseWorkerNumber = defaultUseWorkerNumber) {
|
constructor(workerConstructor: () => Worker, concurrency: number, getUseWorkerNumber = defaultUseWorkerNumber) {
|
||||||
|
@ -29,7 +31,7 @@ export class WorkerMultiDispatch<POST = any, RETURN = any> {
|
||||||
if (_DEV_) console.log('WorkerMultiDispatch: Created', this);
|
if (_DEV_) console.log('WorkerMultiDispatch: Created', this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public postMessage(message: POST, options?: Transferable[] | StructuredSerializeOptions, useWorkerNumber: typeof defaultUseWorkerNumber = this.getUseWorkerNumber) {
|
public postMessage(message: POST, options?: Transferable[] | StructuredSerializeOptions, useWorkerNumber: WorkerNumberGetter = this.getUseWorkerNumber) {
|
||||||
let workerNumber = useWorkerNumber(this.prevWorkerNumber, this.workers.length);
|
let workerNumber = useWorkerNumber(this.prevWorkerNumber, this.workers.length);
|
||||||
workerNumber = Math.abs(Math.round(workerNumber)) % this.workers.length;
|
workerNumber = Math.abs(Math.round(workerNumber)) % this.workers.length;
|
||||||
if (_DEV_) console.log('WorkerMultiDispatch: Posting message to worker', workerNumber, useWorkerNumber);
|
if (_DEV_) console.log('WorkerMultiDispatch: Posting message to worker', workerNumber, useWorkerNumber);
|
||||||
|
@ -46,12 +48,14 @@ export class WorkerMultiDispatch<POST = any, RETURN = any> {
|
||||||
return workerNumber;
|
return workerNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
public addListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
public addListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
||||||
this.workers.forEach(worker => {
|
this.workers.forEach(worker => {
|
||||||
worker.addEventListener('message', callback, options);
|
worker.addEventListener('message', callback, options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
public removeListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
public removeListener(callback: (this: Worker, ev: MessageEvent<RETURN>) => any, options?: boolean | AddEventListenerOptions) {
|
||||||
this.workers.forEach(worker => {
|
this.workers.forEach(worker => {
|
||||||
worker.removeEventListener('message', callback, options);
|
worker.removeEventListener('message', callback, options);
|
|
@ -16,7 +16,13 @@
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"],
|
||||||
|
"@@/*": ["./*"]
|
||||||
|
},
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
|
"./@types",
|
||||||
"./node_modules/@types"
|
"./node_modules/@types"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
|
@ -25,6 +31,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
"@types/**/*.ts",
|
||||||
"js/**/*"
|
"js/**/*"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { i18n } from '@/i18n.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
import { MenuButton } from '@/types/menu.js';
|
import { MenuButton } from '@/types/menu.js';
|
||||||
import { del, get, set } from '@/scripts/idb-proxy.js';
|
import { del, get, set } from '@/scripts/idb-proxy.js';
|
||||||
import { apiUrl } from '@/config.js';
|
import { apiUrl } from '@@/js/config.js';
|
||||||
import { waiting, popup, popupMenu, success, alert } from '@/os.js';
|
import { waiting, popup, popupMenu, success, alert } from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { unisonReload, reloadChannel } from '@/scripts/unison-reload.js';
|
import { unisonReload, reloadChannel } from '@/scripts/unison-reload.js';
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { compareVersions } from 'compare-versions';
|
||||||
import widgets from '@/widgets/index.js';
|
import widgets from '@/widgets/index.js';
|
||||||
import directives from '@/directives/index.js';
|
import directives from '@/directives/index.js';
|
||||||
import components from '@/components/index.js';
|
import components from '@/components/index.js';
|
||||||
import { version, lang, updateLocale, locale } from '@/config.js';
|
import { version, lang, updateLocale, locale } from '@@/js/config.js';
|
||||||
import { applyTheme } from '@/scripts/theme.js';
|
import { applyTheme } from '@/scripts/theme.js';
|
||||||
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js';
|
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js';
|
||||||
import { updateI18n } from '@/i18n.js';
|
import { updateI18n } from '@/i18n.js';
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { createApp, defineAsyncComponent, markRaw } from 'vue';
|
import { createApp, defineAsyncComponent, markRaw } from 'vue';
|
||||||
import { common } from './common.js';
|
import { common } from './common.js';
|
||||||
import type * as Misskey from 'misskey-js';
|
import type * as Misskey from 'misskey-js';
|
||||||
import { ui } from '@/config.js';
|
import { ui } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { alert, confirm, popup, post, toast } from '@/os.js';
|
import { alert, confirm, popup, post, toast } from '@/os.js';
|
||||||
import { useStream } from '@/stream.js';
|
import { useStream } from '@/stream.js';
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { ref } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkMention from './MkMention.vue';
|
import MkMention from './MkMention.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { host as localHost } from '@/config.js';
|
import { host as localHost } from '@@/js/config.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
|
|
||||||
const user = ref<Misskey.entities.UserLite>();
|
const user = ref<Misskey.entities.UserLite>();
|
||||||
|
|
|
@ -39,7 +39,7 @@ import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import { apiUrl } from '@/config.js';
|
import { apiUrl } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';
|
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkLink from '@/components/MkLink.vue';
|
import MkLink from '@/components/MkLink.vue';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
|
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
@close="cancel()"
|
@close="cancel()"
|
||||||
@closed="$emit('closed')"
|
@closed="$emit('closed')"
|
||||||
>
|
>
|
||||||
<template #header>{{ i18n.ts._embedCodeGen.title }}</template>
|
<template #header><i class="ti ti-code"></i> {{ i18n.ts._embedCodeGen.title }}</template>
|
||||||
|
|
||||||
<div :class="$style.embedCodeGenRoot">
|
<div :class="$style.embedCodeGenRoot">
|
||||||
<Transition
|
<Transition
|
||||||
|
@ -103,7 +103,7 @@ import MkInfo from '@/components/MkInfo.vue';
|
||||||
|
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||||
import { normalizeEmbedParams, getEmbedCode } from '@/scripts/get-embed-code.js';
|
import { normalizeEmbedParams, getEmbedCode } from '@/scripts/get-embed-code.js';
|
||||||
import { embedRouteWithScrollbar } from '@@/js/embed-page.js';
|
import { embedRouteWithScrollbar } from '@@/js/embed-page.js';
|
||||||
|
|
|
@ -43,7 +43,7 @@ import { useStream } from '@/stream.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { claimAchievement } from '@/scripts/achievements.js';
|
import { claimAchievement } from '@/scripts/achievements.js';
|
||||||
import { pleaseLogin } from '@/scripts/please-login.js';
|
import { pleaseLogin } from '@/scripts/please-login.js';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import DrawBlurhash from '@/workers/draw-blurhash?worker';
|
import DrawBlurhash from '@/workers/draw-blurhash?worker';
|
||||||
import TestWebGL2 from '@/workers/test-webgl2?worker';
|
import TestWebGL2 from '@/workers/test-webgl2?worker';
|
||||||
import { WorkerMultiDispatch } from '@/scripts/worker-multi-dispatch.js';
|
import { WorkerMultiDispatch } from '@@/js/worker-multi-dispatch.js';
|
||||||
import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurhash.js';
|
import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurhash.js';
|
||||||
|
|
||||||
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(resolve => {
|
||||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { instanceName } from '@/config.js';
|
import { instanceName } from '@@/js/config.js';
|
||||||
import { instance as Instance } from '@/instance.js';
|
import { instance as Instance } from '@/instance.js';
|
||||||
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
|
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, ref } from 'vue';
|
import { defineAsyncComponent, ref } from 'vue';
|
||||||
import { url as local } from '@/config.js';
|
import { url as local } from '@@/js/config.js';
|
||||||
import { useTooltip } from '@/scripts/use-tooltip.js';
|
import { useTooltip } from '@/scripts/use-tooltip.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { isEnabledUrlPreview } from '@/instance.js';
|
import { isEnabledUrlPreview } from '@/instance.js';
|
||||||
|
|
|
@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { toUnicode } from 'punycode';
|
import { toUnicode } from 'punycode';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { host as localHost } from '@/config.js';
|
import { host as localHost } from '@@/js/config.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import { getStaticImageUrl } from '@/scripts/media-proxy.js';
|
import { getStaticImageUrl } from '@/scripts/media-proxy.js';
|
||||||
|
|
|
@ -163,6 +163,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
|
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
|
||||||
import * as mfm from 'mfm-js';
|
import * as mfm from 'mfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
|
import { isLink } from '@@/js/is-link.js';
|
||||||
import MkNoteSub from '@/components/MkNoteSub.vue';
|
import MkNoteSub from '@/components/MkNoteSub.vue';
|
||||||
import MkNoteHeader from '@/components/MkNoteHeader.vue';
|
import MkNoteHeader from '@/components/MkNoteHeader.vue';
|
||||||
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
||||||
|
@ -195,8 +196,8 @@ import { getNoteSummary } from '@/scripts/get-note-summary.js';
|
||||||
import { MenuItem } from '@/types/menu.js';
|
import { MenuItem } from '@/types/menu.js';
|
||||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||||
import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
|
import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
|
||||||
import { shouldCollapsed } from '@/scripts/collapsed.js';
|
import { shouldCollapsed } from '@@/js/collapsed.js';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { isEnabledUrlPreview } from '@/instance.js';
|
import { isEnabledUrlPreview } from '@/instance.js';
|
||||||
import { type Keymap } from '@/scripts/hotkey.js';
|
import { type Keymap } from '@/scripts/hotkey.js';
|
||||||
import { focusPrev, focusNext } from '@/scripts/focus.js';
|
import { focusPrev, focusNext } from '@/scripts/focus.js';
|
||||||
|
@ -506,16 +507,6 @@ function onContextmenu(ev: MouseEvent): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLink = (el: HTMLElement): boolean => {
|
|
||||||
if (el.tagName === 'A') return true;
|
|
||||||
// 再生速度の選択などのために、Audio要素のコンテキストメニューはブラウザデフォルトとする。
|
|
||||||
if (el.tagName === 'AUDIO') return true;
|
|
||||||
if (el.parentElement) {
|
|
||||||
return isLink(el.parentElement);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ev.target && isLink(ev.target as HTMLElement)) return;
|
if (ev.target && isLink(ev.target as HTMLElement)) return;
|
||||||
if (window.getSelection()?.toString() !== '') return;
|
if (window.getSelection()?.toString() !== '') return;
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { computed, inject, onMounted, provide, ref, shallowRef } from 'vue';
|
import { computed, inject, onMounted, provide, ref, shallowRef } from 'vue';
|
||||||
import * as mfm from 'mfm-js';
|
import * as mfm from 'mfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
|
import { isLink } from '@@/js/is-link.js';
|
||||||
import MkNoteSub from '@/components/MkNoteSub.vue';
|
import MkNoteSub from '@/components/MkNoteSub.vue';
|
||||||
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
||||||
import MkReactionsViewer from '@/components/MkReactionsViewer.vue';
|
import MkReactionsViewer from '@/components/MkReactionsViewer.vue';
|
||||||
|
@ -222,7 +223,7 @@ import { reactionPicker } from '@/scripts/reaction-picker.js';
|
||||||
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
|
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { getNoteClipMenu, getNoteMenu, getRenoteMenu } from '@/scripts/get-note-menu.js';
|
import { getNoteClipMenu, getNoteMenu, getRenoteMenu } from '@/scripts/get-note-menu.js';
|
||||||
import { useNoteCapture } from '@/scripts/use-note-capture.js';
|
import { useNoteCapture } from '@/scripts/use-note-capture.js';
|
||||||
import { deepClone } from '@/scripts/clone.js';
|
import { deepClone } from '@/scripts/clone.js';
|
||||||
|
@ -468,14 +469,6 @@ function toggleReact() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onContextmenu(ev: MouseEvent): void {
|
function onContextmenu(ev: MouseEvent): void {
|
||||||
const isLink = (el: HTMLElement): boolean => {
|
|
||||||
if (el.tagName === 'A') return true;
|
|
||||||
if (el.parentElement) {
|
|
||||||
return isLink(el.parentElement);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ev.target && isLink(ev.target as HTMLElement)) return;
|
if (ev.target && isLink(ev.target as HTMLElement)) return;
|
||||||
if (window.getSelection()?.toString() !== '') return;
|
if (window.getSelection()?.toString() !== '') return;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import RouterView from '@/components/global/RouterView.vue';
|
||||||
import MkWindow from '@/components/MkWindow.vue';
|
import MkWindow from '@/components/MkWindow.vue';
|
||||||
import { popout as _popout } from '@/scripts/popout.js';
|
import { popout as _popout } from '@/scripts/popout.js';
|
||||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { useScrollPositionManager } from '@/nirax.js';
|
import { useScrollPositionManager } from '@/nirax.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { PageMetadata, provideMetadataReceiver, provideReactiveMetadata } from '@/scripts/page-metadata.js';
|
import { PageMetadata, provideMetadataReceiver, provideReactiveMetadata } from '@/scripts/page-metadata.js';
|
||||||
|
|
|
@ -35,7 +35,7 @@ import { pleaseLogin } from '@/scripts/please-login.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
|
@ -109,7 +109,7 @@ import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
||||||
import MkNotePreview from '@/components/MkNotePreview.vue';
|
import MkNotePreview from '@/components/MkNotePreview.vue';
|
||||||
import XPostFormAttaches from '@/components/MkPostFormAttaches.vue';
|
import XPostFormAttaches from '@/components/MkPostFormAttaches.vue';
|
||||||
import MkPollEditor, { type PollEditorModelValue } from '@/components/MkPollEditor.vue';
|
import MkPollEditor, { type PollEditorModelValue } from '@/components/MkPollEditor.vue';
|
||||||
import { host, url } from '@/config.js';
|
import { host, url } from '@@/js/config.js';
|
||||||
import { erase, unique } from '@/scripts/array.js';
|
import { erase, unique } from '@/scripts/array.js';
|
||||||
import { extractMentions } from '@/scripts/extract-mentions.js';
|
import { extractMentions } from '@/scripts/extract-mentions.js';
|
||||||
import { formatTimeString } from '@/scripts/format-time-string.js';
|
import { formatTimeString } from '@/scripts/format-time-string.js';
|
||||||
|
|
|
@ -42,7 +42,7 @@ import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
import MkTextarea from '@/components/MkTextarea.vue';
|
import MkTextarea from '@/components/MkTextarea.vue';
|
||||||
import MkRadio from '@/components/MkRadio.vue';
|
import MkRadio from '@/components/MkRadio.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import * as config from '@/config.js';
|
import * as config from '@@/js/config.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
|
|
||||||
const text = ref('');
|
const text = ref('');
|
||||||
|
|
|
@ -72,7 +72,7 @@ import { showSuspendedDialog } from '@/scripts/show-suspended-dialog.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
import MkInfo from '@/components/MkInfo.vue';
|
||||||
import { host as configHost } from '@/config.js';
|
import { host as configHost } from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { login } from '@/account.js';
|
import { login } from '@/account.js';
|
||||||
|
|
|
@ -84,7 +84,7 @@ import * as Misskey from 'misskey-js';
|
||||||
import MkButton from './MkButton.vue';
|
import MkButton from './MkButton.vue';
|
||||||
import MkInput from './MkInput.vue';
|
import MkInput from './MkInput.vue';
|
||||||
import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue';
|
import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue';
|
||||||
import * as config from '@/config.js';
|
import * as config from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { login } from '@/account.js';
|
import { login } from '@/account.js';
|
||||||
|
|
|
@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { instance } from '@/instance.js';
|
import { instance } from '@/instance.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
|
|
|
@ -35,7 +35,7 @@ import * as Misskey from 'misskey-js';
|
||||||
import MkMediaList from '@/components/MkMediaList.vue';
|
import MkMediaList from '@/components/MkMediaList.vue';
|
||||||
import MkPoll from '@/components/MkPoll.vue';
|
import MkPoll from '@/components/MkPoll.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { shouldCollapsed } from '@/scripts/collapsed.js';
|
import { shouldCollapsed } from '@@/js/collapsed.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
note: Misskey.entities.Note;
|
note: Misskey.entities.Note;
|
||||||
|
|
|
@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, shallowRef } from 'vue';
|
import { shallowRef } from 'vue';
|
||||||
import MkModalWindow from '@/components/MkModalWindow.vue';
|
import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||||
import XTutorial from '@/components/MkTutorial.vue';
|
import XTutorial from '@/components/MkTutorial.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { onMounted, shallowRef } from 'vue';
|
||||||
import MkModal from '@/components/MkModal.vue';
|
import MkModal from '@/components/MkModal.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkSparkle from '@/components/MkSparkle.vue';
|
import MkSparkle from '@/components/MkSparkle.vue';
|
||||||
import { version } from '@/config.js';
|
import { version } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { confetti } from '@/scripts/confetti.js';
|
import { confetti } from '@/scripts/confetti.js';
|
||||||
|
|
||||||
|
|
|
@ -85,12 +85,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, onDeactivated, onUnmounted, ref } from 'vue';
|
import { defineAsyncComponent, onDeactivated, onUnmounted, ref } from 'vue';
|
||||||
import type { summaly } from '@misskey-dev/summaly';
|
import type { summaly } from '@misskey-dev/summaly';
|
||||||
import { url as local } from '@/config.js';
|
import { url as local } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { deviceKind } from '@/scripts/device-kind.js';
|
import { deviceKind } from '@/scripts/device-kind.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { versatileLang } from '@/scripts/intl-const.js';
|
import { versatileLang } from '@@/js/intl-const.js';
|
||||||
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
|
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { host as currentHost, hostname } from '@/config.js';
|
import { host as currentHost, hostname } from '@@/js/config.js';
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: 'ok', selected: Misskey.entities.UserDetailed): void;
|
(ev: 'ok', selected: Misskey.entities.UserDetailed): void;
|
||||||
|
|
|
@ -58,7 +58,7 @@ import XSignupDialog from '@/components/MkSignupDialog.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkTimeline from '@/components/MkTimeline.vue';
|
import MkTimeline from '@/components/MkTimeline.vue';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
import MkInfo from '@/components/MkInfo.vue';
|
||||||
import { instanceName } from '@/config.js';
|
import { instanceName } from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
|
@ -57,6 +57,7 @@ import MkButton from '@/components/MkButton.vue';
|
||||||
import { widgets as widgetDefs } from '@/widgets/index.js';
|
import { widgets as widgetDefs } from '@/widgets/index.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
import { isLink } from '@@/js/is-link.js';
|
||||||
|
|
||||||
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
|
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
|
||||||
|
|
||||||
|
@ -98,13 +99,6 @@ const updateWidget = (id, data) => {
|
||||||
|
|
||||||
function onContextmenu(widget: Widget, ev: MouseEvent) {
|
function onContextmenu(widget: Widget, ev: MouseEvent) {
|
||||||
const element = ev.target as HTMLElement | null;
|
const element = ev.target as HTMLElement | null;
|
||||||
const isLink = (el: HTMLElement): boolean => {
|
|
||||||
if (el.tagName === 'A') return true;
|
|
||||||
if (el.parentElement) {
|
|
||||||
return isLink(el.parentElement);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if (element && isLink(element)) return;
|
if (element && isLink(element)) return;
|
||||||
if (element && (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(element.tagName) || element.attributes['contenteditable'])) return;
|
if (element && (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(element.tagName) || element.attributes['contenteditable'])) return;
|
||||||
if (window.getSelection()?.toString() !== '') return;
|
if (window.getSelection()?.toString() !== '') return;
|
||||||
|
|
|
@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import MkWindow from '@/components/MkWindow.vue';
|
import MkWindow from '@/components/MkWindow.vue';
|
||||||
import { versatileLang } from '@/scripts/intl-const.js';
|
import { versatileLang } from '@@/js/intl-const.js';
|
||||||
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
|
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export type MkABehavior = 'window' | 'browser' | null;
|
||||||
import { computed, inject, shallowRef } from 'vue';
|
import { computed, inject, shallowRef } from 'vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { useRouter } from '@/router/supplier.js';
|
import { useRouter } from '@/router/supplier.js';
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { toUnicode } from 'punycode/';
|
import { toUnicode } from 'punycode/';
|
||||||
import { host as hostRaw } from '@/config.js';
|
import { host as hostRaw } from '@@/js/config.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
|
|
@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { instance } from '@/instance.js';
|
import { instance } from '@/instance.js';
|
||||||
import { url as local, host } from '@/config.js';
|
import { url as local, host } from '@@/js/config.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
|
|
|
@ -17,7 +17,7 @@ import MkCodeInline from '@/components/MkCodeInline.vue';
|
||||||
import MkGoogle from '@/components/MkGoogle.vue';
|
import MkGoogle from '@/components/MkGoogle.vue';
|
||||||
import MkSparkle from '@/components/MkSparkle.vue';
|
import MkSparkle from '@/components/MkSparkle.vue';
|
||||||
import MkA, { MkABehavior } from '@/components/global/MkA.vue';
|
import MkA, { MkABehavior } from '@/components/global/MkA.vue';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
function safeParseFloat(str: unknown): number | null {
|
function safeParseFloat(str: unknown): number | null {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { expect } from '@storybook/test';
|
||||||
import { StoryObj } from '@storybook/vue3';
|
import { StoryObj } from '@storybook/vue3';
|
||||||
import MkTime from './MkTime.vue';
|
import MkTime from './MkTime.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { dateTimeFormat } from '@/scripts/intl-const.js';
|
import { dateTimeFormat } from '@@/js/intl-const.js';
|
||||||
const now = new Date('2023-04-01T00:00:00.000Z');
|
const now = new Date('2023-04-01T00:00:00.000Z');
|
||||||
const future = new Date('2024-04-01T00:00:00.000Z');
|
const future = new Date('2024-04-01T00:00:00.000Z');
|
||||||
const oneHourAgo = new Date(now.getTime() - 3600000);
|
const oneHourAgo = new Date(now.getTime() - 3600000);
|
||||||
|
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import isChromatic from 'chromatic/isChromatic';
|
import isChromatic from 'chromatic/isChromatic';
|
||||||
import { onMounted, onUnmounted, ref, computed } from 'vue';
|
import { onMounted, onUnmounted, ref, computed } from 'vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { dateTimeFormat } from '@/scripts/intl-const.js';
|
import { dateTimeFormat } from '@@/js/intl-const.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
time: Date | string | number | null;
|
time: Date | string | number | null;
|
||||||
|
|
|
@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, ref } from 'vue';
|
import { defineAsyncComponent, ref } from 'vue';
|
||||||
import { toUnicode as decodePunycode } from 'punycode/';
|
import { toUnicode as decodePunycode } from 'punycode/';
|
||||||
import { url as local } from '@/config.js';
|
import { url as local } from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { useTooltip } from '@/scripts/use-tooltip.js';
|
import { useTooltip } from '@/scripts/use-tooltip.js';
|
||||||
import { isEnabledUrlPreview } from '@/instance.js';
|
import { isEnabledUrlPreview } from '@/instance.js';
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
|
||||||
|
|
||||||
const address = new URL(document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || location.href);
|
|
||||||
const siteName = document.querySelector<HTMLMetaElement>('meta[property="og:site_name"]')?.content;
|
|
||||||
|
|
||||||
export const host = address.host;
|
|
||||||
export const hostname = address.hostname;
|
|
||||||
export const url = address.origin;
|
|
||||||
export const apiUrl = location.origin + '/api';
|
|
||||||
export const wsOrigin = location.origin;
|
|
||||||
export const lang = miLocalStorage.getItem('lang') ?? 'en-US';
|
|
||||||
export const langs = _LANGS_;
|
|
||||||
const preParseLocale = miLocalStorage.getItem('locale');
|
|
||||||
export let locale = preParseLocale ? JSON.parse(preParseLocale) : null;
|
|
||||||
export const version = _VERSION_;
|
|
||||||
export const instanceName = siteName === 'Misskey' || siteName == null ? host : siteName;
|
|
||||||
export const ui = miLocalStorage.getItem('ui');
|
|
||||||
export const debug = miLocalStorage.getItem('debug') === 'true';
|
|
||||||
|
|
||||||
export function updateLocale(newLocale): void {
|
|
||||||
locale = newLocale;
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { dateTimeFormat } from '@/scripts/intl-const.js';
|
import { dateTimeFormat } from '@@/js/intl-const.js';
|
||||||
|
|
||||||
export default (d: Date | number | undefined) => dateTimeFormat.format(d);
|
export default (d: Date | number | undefined) => dateTimeFormat.format(d);
|
||||||
export const dateString = (d: string) => dateTimeFormat.format(new Date(d));
|
export const dateString = (d: string) => dateTimeFormat.format(new Date(d));
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { numberFormat } from '@/scripts/intl-const.js';
|
import { numberFormat } from '@@/js/intl-const.js';
|
||||||
|
|
||||||
export default n => n == null ? 'N/A' : numberFormat.format(n);
|
export default n => n == null ? 'N/A' : numberFormat.format(n);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
|
|
||||||
export const acct = (user: Misskey.Acct) => {
|
export const acct = (user: Misskey.Acct) => {
|
||||||
return Misskey.acct.toString(user);
|
return Misskey.acct.toString(user);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { markRaw } from 'vue';
|
import { markRaw } from 'vue';
|
||||||
import { I18n } from '@@/js/i18n.js';
|
import { I18n } from '@@/js/i18n.js';
|
||||||
import type { Locale } from '../../../locales/index.js';
|
import type { Locale } from '../../../locales/index.js';
|
||||||
import { locale } from '@/config.js';
|
import { locale } from '@@/js/config.js';
|
||||||
|
|
||||||
export const i18n = markRaw(new I18n<Locale>(locale, _DEV_));
|
export const i18n = markRaw(new I18n<Locale>(locale, _DEV_));
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { openInstanceMenu, openToolsMenu } from '@/ui/_common_/common.js';
|
||||||
import { lookup } from '@/scripts/lookup.js';
|
import { lookup } from '@/scripts/lookup.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { ui } from '@/config.js';
|
import { ui } from '@@/js/config.js';
|
||||||
import { unisonReload } from '@/scripts/unison-reload.js';
|
import { unisonReload } from '@/scripts/unison-reload.js';
|
||||||
|
|
||||||
export const navbarItemDef = reactive({
|
export const navbarItemDef = reactive({
|
||||||
|
|
|
@ -29,7 +29,7 @@ import { ref, computed } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkLink from '@/components/MkLink.vue';
|
import MkLink from '@/components/MkLink.vue';
|
||||||
import { version } from '@/config.js';
|
import { version } from '@@/js/config.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { unisonReload } from '@/scripts/unison-reload.js';
|
import { unisonReload } from '@/scripts/unison-reload.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
|
@ -132,7 +132,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onBeforeUnmount, ref, shallowRef, computed } from 'vue';
|
import { nextTick, onBeforeUnmount, ref, shallowRef, computed } from 'vue';
|
||||||
import { version } from '@/config.js';
|
import { version } from '@@/js/config.js';
|
||||||
import FormLink from '@/components/form/link.vue';
|
import FormLink from '@/components/form/link.vue';
|
||||||
import FormSection from '@/components/form/section.vue';
|
import FormSection from '@/components/form/section.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
|
|
@ -126,7 +126,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { host, version } from '@/config.js';
|
import { host, version } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { instance } from '@/instance.js';
|
import { instance } from '@/instance.js';
|
||||||
import number from '@/filters/number.js';
|
import number from '@/filters/number.js';
|
||||||
|
|
|
@ -220,7 +220,7 @@ import MkFileListForAdmin from '@/components/MkFileListForAdmin.vue';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
import MkInfo from '@/components/MkInfo.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { acct } from '@/filters/user.js';
|
import { acct } from '@/filters/user.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
|
@ -117,7 +117,7 @@ import { i18n } from '@/i18n.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkColorInput from '@/components/MkColorInput.vue';
|
import MkColorInput from '@/components/MkColorInput.vue';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
|
|
||||||
const iconUrl = ref<string | null>(null);
|
const iconUrl = ref<string | null>(null);
|
||||||
const app192IconUrl = ref<string | null>(null);
|
const app192IconUrl = ref<string | null>(null);
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { ref, computed, type Ref } from 'vue';
|
||||||
import XQueue from './queue.chart.vue';
|
import XQueue from './queue.chart.vue';
|
||||||
import XHeader from './_header_.vue';
|
import XHeader from './_header_.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import * as config from '@/config.js';
|
import * as config from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
|
|
@ -82,7 +82,7 @@ import { i18n } from '@/i18n.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { deviceKind } from '@/scripts/device-kind.js';
|
import { deviceKind } from '@/scripts/device-kind.js';
|
||||||
import MkNotes from '@/components/MkNotes.vue';
|
import MkNotes from '@/components/MkNotes.vue';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { favoritedChannelsCache } from '@/cache.js';
|
import { favoritedChannelsCache } from '@/cache.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
|
|
|
@ -39,7 +39,7 @@ import { i18n } from '@/i18n.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { clipsCache } from '@/cache.js';
|
import { clipsCache } from '@/cache.js';
|
||||||
import { isSupportShare } from '@/scripts/navigator.js';
|
import { isSupportShare } from '@/scripts/navigator.js';
|
||||||
|
|
|
@ -206,7 +206,7 @@ import { defaultStore } from '@/store.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
import { apiUrl } from '@/config.js';
|
import { apiUrl } from '@@/js/config.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import * as sound from '@/scripts/sound.js';
|
import * as sound from '@/scripts/sound.js';
|
||||||
import MkRange from '@/components/MkRange.vue';
|
import MkRange from '@/components/MkRange.vue';
|
||||||
|
|
|
@ -68,7 +68,7 @@ import { Interpreter, Parser, values } from '@syuilo/aiscript';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import MkAsUi from '@/components/MkAsUi.vue';
|
import MkAsUi from '@/components/MkAsUi.vue';
|
||||||
|
|
|
@ -72,7 +72,7 @@ import MkContainer from '@/components/MkContainer.vue';
|
||||||
import MkPagination from '@/components/MkPagination.vue';
|
import MkPagination from '@/components/MkPagination.vue';
|
||||||
import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue';
|
import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue';
|
||||||
import MkFollowButton from '@/components/MkFollowButton.vue';
|
import MkFollowButton from '@/components/MkFollowButton.vue';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
|
@ -69,7 +69,7 @@ import MkButton from '@/components/MkButton.vue';
|
||||||
import MkSelect from '@/components/MkSelect.vue';
|
import MkSelect from '@/components/MkSelect.vue';
|
||||||
import MkSwitch from '@/components/MkSwitch.vue';
|
import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { selectFile } from '@/scripts/select-file.js';
|
import { selectFile } from '@/scripts/select-file.js';
|
||||||
|
|
|
@ -104,7 +104,7 @@ import XPage from '@/components/page/page.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import MkMediaImage from '@/components/MkMediaImage.vue';
|
import MkMediaImage from '@/components/MkMediaImage.vue';
|
||||||
import MkImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
|
import MkImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
|
||||||
import MkFollowButton from '@/components/MkFollowButton.vue';
|
import MkFollowButton from '@/components/MkFollowButton.vue';
|
||||||
|
|
|
@ -151,7 +151,7 @@ import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
import { deepClone } from '@/scripts/clone.js';
|
import { deepClone } from '@/scripts/clone.js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
import { signinRequired } from '@/account.js';
|
import { signinRequired } from '@/account.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { userPage } from '@/filters/user.js';
|
import { userPage } from '@/filters/user.js';
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { useStream } from '@/stream.js';
|
||||||
import { signinRequired } from '@/account.js';
|
import { signinRequired } from '@/account.js';
|
||||||
import { useRouter } from '@/router/supplier.js';
|
import { useRouter } from '@/router/supplier.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { url } from '@/config.js';
|
import { url } from '@@/js/config.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import MkUserList from '@/components/MkUserList.vue';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import MkTimeline from '@/components/MkTimeline.vue';
|
import MkTimeline from '@/components/MkTimeline.vue';
|
||||||
import { instanceName } from '@/config.js';
|
import { instanceName } from '@@/js/config.js';
|
||||||
import { serverErrorImageUrl, infoImageUrl } from '@/instance.js';
|
import { serverErrorImageUrl, infoImageUrl } from '@/instance.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
|
|
|
@ -254,7 +254,7 @@ import FormSection from '@/components/form/section.vue';
|
||||||
import FormLink from '@/components/form/link.vue';
|
import FormLink from '@/components/form/link.vue';
|
||||||
import MkLink from '@/components/MkLink.vue';
|
import MkLink from '@/components/MkLink.vue';
|
||||||
import MkInfo from '@/components/MkInfo.vue';
|
import MkInfo from '@/components/MkInfo.vue';
|
||||||
import { langs } from '@/config.js';
|
import { langs } from '@@/js/config.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
|
|
|
@ -49,7 +49,7 @@ import { unisonReload } from '@/scripts/unison-reload.js';
|
||||||
import { useStream } from '@/stream.js';
|
import { useStream } from '@/stream.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { version, host } from '@/config.js';
|
import { version, host } from '@@/js/config.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
const { t, ts } = i18n;
|
const { t, ts } = i18n;
|
||||||
|
|
|
@ -88,7 +88,7 @@ import MkFolder from '@/components/MkFolder.vue';
|
||||||
|
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { Theme, applyTheme } from '@/scripts/theme.js';
|
import { Theme, applyTheme } from '@/scripts/theme.js';
|
||||||
import { host } from '@/config.js';
|
import { host } from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { ColdDeviceStorage, defaultStore } from '@/store.js';
|
import { ColdDeviceStorage, defaultStore } from '@/store.js';
|
||||||
import { addTheme } from '@/theme-store.js';
|
import { addTheme } from '@/theme-store.js';
|
||||||
|
|
|
@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
import { host, version } from '@/config.js';
|
import { host, version } from '@@/js/config.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { login } from '@/account.js';
|
import { login } from '@/account.js';
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { computed, ref } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import XSetup from './welcome.setup.vue';
|
import XSetup from './welcome.setup.vue';
|
||||||
import XEntrance from './welcome.entrance.a.vue';
|
import XEntrance from './welcome.entrance.a.vue';
|
||||||
import { instanceName } from '@/config.js';
|
import { instanceName } from '@@/js/config.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { fetchInstance } from '@/instance.js';
|
import { fetchInstance } from '@/instance.js';
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { miLocalStorage } from '@/local-storage.js';
|
import { miLocalStorage } from '@/local-storage.js';
|
||||||
import { customEmojis } from '@/custom-emojis.js';
|
import { customEmojis } from '@/custom-emojis.js';
|
||||||
import { url, lang } from '@/config.js';
|
import { url, lang } from '@@/js/config.js';
|
||||||
|
|
||||||
export function aiScriptReadline(q: string): Promise<string> {
|
export function aiScriptReadline(q: string): Promise<string> {
|
||||||
return new Promise(ok => {
|
return new Promise(ok => {
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as Misskey from 'misskey-js';
|
|
||||||
|
|
||||||
export function shouldCollapsed(note: Misskey.entities.Note, urls: string[]): boolean {
|
|
||||||
const collapsed = note.cw == null && (
|
|
||||||
note.text != null && (
|
|
||||||
(note.text.includes('$[x2')) ||
|
|
||||||
(note.text.includes('$[x3')) ||
|
|
||||||
(note.text.includes('$[x4')) ||
|
|
||||||
(note.text.includes('$[scale')) ||
|
|
||||||
(note.text.split('\n').length > 9) ||
|
|
||||||
(note.text.length > 500) ||
|
|
||||||
(urls.length >= 4)
|
|
||||||
) || note.files.length >= 5
|
|
||||||
);
|
|
||||||
|
|
||||||
return collapsed;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue