From 048aa6f30657c108d1e9b78a1bc4460867510049 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Mon, 26 Aug 2024 15:28:10 +0900
Subject: [PATCH] wip
---
packages/frontend-embed/package.json | 2 -
.../src/components/EmInstanceTicker.vue | 85 +++++++++++++++++++
.../src/components/EmNoteDetailed.vue | 5 +-
packages/frontend-embed/src/instance.ts | 1 +
.../src/to-be-shared/media-proxy.ts | 53 ++++++++++++
.../frontend-embed/src/to-be-shared/url.ts | 28 ++++++
packages/frontend-embed/vite.config.ts | 2 -
packages/frontend-embed/vite.json5.ts | 48 -----------
8 files changed, 171 insertions(+), 53 deletions(-)
create mode 100644 packages/frontend-embed/src/components/EmInstanceTicker.vue
create mode 100644 packages/frontend-embed/src/to-be-shared/media-proxy.ts
create mode 100644 packages/frontend-embed/src/to-be-shared/url.ts
delete mode 100644 packages/frontend-embed/vite.json5.ts
diff --git a/packages/frontend-embed/package.json b/packages/frontend-embed/package.json
index 816b028cbd..8c9a1b82cb 100644
--- a/packages/frontend-embed/package.json
+++ b/packages/frontend-embed/package.json
@@ -20,7 +20,6 @@
"@twemoji/parser": "15.1.1",
"@vitejs/plugin-vue": "5.1.0",
"@vue/compiler-sfc": "3.4.37",
- "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.11",
"astring": "1.8.6",
"buraha": "0.0.1",
"compare-versions": "6.1.1",
@@ -30,7 +29,6 @@
"eventemitter3": "5.0.1",
"idb-keyval": "6.2.1",
"is-file-animated": "1.0.2",
- "json5": "2.2.3",
"mfm-js": "0.24.0",
"misskey-js": "workspace:*",
"punycode": "2.3.1",
diff --git a/packages/frontend-embed/src/components/EmInstanceTicker.vue b/packages/frontend-embed/src/components/EmInstanceTicker.vue
new file mode 100644
index 0000000000..82c82199b5
--- /dev/null
+++ b/packages/frontend-embed/src/components/EmInstanceTicker.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
{{ instance.name }}
+
+
+
+
+
+
diff --git a/packages/frontend-embed/src/components/EmNoteDetailed.vue b/packages/frontend-embed/src/components/EmNoteDetailed.vue
index 1e8c140ad8..1ab00af036 100644
--- a/packages/frontend-embed/src/components/EmNoteDetailed.vue
+++ b/packages/frontend-embed/src/components/EmNoteDetailed.vue
@@ -129,13 +129,16 @@ SPDX-License-Identifier: AGPL-3.0-only
import { computed, inject, ref } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
-import EmMediaList from './EmMediaList.vue';
+import EmMediaList from '@/components/EmMediaList.vue';
import EmNoteSub from '@/components/EmNoteSub.vue';
import EmNoteSimple from '@/components/EmNoteSimple.vue';
import EmReactionsViewer from '@/components/EmReactionsViewer.vue';
import EmCwButton from '@/components/EmCwButton.vue';
import EmPoll from '@/components/EmPoll.vue';
import EmInstanceTicker from '@/components/EmInstanceTicker.vue';
+import EmA from '@/components/EmA.vue';
+import EmAvatar from '@/components/EmAvatar.vue';
+import EmTime from '@/components/EmTime.vue';
import { userPage } from '@/utils.js';
import { notePage } from '@/utils.js';
import { i18n } from '@/i18n.js';
diff --git a/packages/frontend-embed/src/instance.ts b/packages/frontend-embed/src/instance.ts
index 4d41b2aac0..3b8c7324b2 100644
--- a/packages/frontend-embed/src/instance.ts
+++ b/packages/frontend-embed/src/instance.ts
@@ -9,4 +9,5 @@ import { misskeyApi } from '@/misskey-api.js';
export const instance = {
iconUrl: 'TODO',
+ mediaProxy: 'TODO',
};
diff --git a/packages/frontend-embed/src/to-be-shared/media-proxy.ts b/packages/frontend-embed/src/to-be-shared/media-proxy.ts
new file mode 100644
index 0000000000..a12871c3b1
--- /dev/null
+++ b/packages/frontend-embed/src/to-be-shared/media-proxy.ts
@@ -0,0 +1,53 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { query } from './url.js';
+import { url } from '@/config.js';
+import { instance } from '@/instance.js';
+
+export function getProxiedImageUrl(imageUrl: string, type?: 'preview' | 'emoji' | 'avatar', mustOrigin = false, noFallback = false): string {
+ const localProxy = `${url}/proxy`;
+
+ if (imageUrl.startsWith(instance.mediaProxy + '/') || imageUrl.startsWith('/proxy/') || imageUrl.startsWith(localProxy + '/')) {
+ // もう既にproxyっぽそうだったらurlを取り出す
+ imageUrl = (new URL(imageUrl)).searchParams.get('url') ?? imageUrl;
+ }
+
+ return `${mustOrigin ? localProxy : instance.mediaProxy}/${
+ type === 'preview' ? 'preview.webp'
+ : 'image.webp'
+ }?${query({
+ url: imageUrl,
+ ...(!noFallback ? { 'fallback': '1' } : {}),
+ ...(type ? { [type]: '1' } : {}),
+ ...(mustOrigin ? { origin: '1' } : {}),
+ })}`;
+}
+
+export function getProxiedImageUrlNullable(imageUrl: string | null | undefined, type?: 'preview'): string | null {
+ if (imageUrl == null) return null;
+ return getProxiedImageUrl(imageUrl, type);
+}
+
+export function getStaticImageUrl(baseUrl: string): string {
+ const u = baseUrl.startsWith('http') ? new URL(baseUrl) : new URL(baseUrl, url);
+
+ if (u.href.startsWith(`${url}/emoji/`)) {
+ // もう既にemojiっぽそうだったらsearchParams付けるだけ
+ u.searchParams.set('static', '1');
+ return u.href;
+ }
+
+ if (u.href.startsWith(instance.mediaProxy + '/')) {
+ // もう既にproxyっぽそうだったらsearchParams付けるだけ
+ u.searchParams.set('static', '1');
+ return u.href;
+ }
+
+ return `${instance.mediaProxy}/static.webp?${query({
+ url: u.href,
+ static: '1',
+ })}`;
+}
diff --git a/packages/frontend-embed/src/to-be-shared/url.ts b/packages/frontend-embed/src/to-be-shared/url.ts
new file mode 100644
index 0000000000..5a8265af9e
--- /dev/null
+++ b/packages/frontend-embed/src/to-be-shared/url.ts
@@ -0,0 +1,28 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+/* objを検査して
+ * 1. 配列に何も入っていない時はクエリを付けない
+ * 2. プロパティがundefinedの時はクエリを付けない
+ * (new URLSearchParams(obj)ではそこまで丁寧なことをしてくれない)
+ */
+export function query(obj: Record): string {
+ const params = Object.entries(obj)
+ .filter(([, v]) => Array.isArray(v) ? v.length : v !== undefined)
+ .reduce((a, [k, v]) => (a[k] = v, a), {} as Record);
+
+ return Object.entries(params)
+ .map((p) => `${p[0]}=${encodeURIComponent(p[1])}`)
+ .join('&');
+}
+
+export function appendQuery(url: string, query: string): string {
+ return `${url}${/\?/.test(url) ? url.endsWith('?') ? '' : '&' : '?'}${query}`;
+}
+
+export function extractDomain(url: string) {
+ const match = url.match(/^(?:https?:)?(?:\/\/)?(?:[^@\n]+@)?([^:\/\n]+)/im);
+ return match ? match[1] : null;
+}
diff --git a/packages/frontend-embed/vite.config.ts b/packages/frontend-embed/vite.config.ts
index 61be63ee21..137954b802 100644
--- a/packages/frontend-embed/vite.config.ts
+++ b/packages/frontend-embed/vite.config.ts
@@ -5,7 +5,6 @@ import { type UserConfig, defineConfig } from 'vite';
import locales from '../../locales/index.js';
import meta from '../../package.json';
import packageInfo from './package.json' with { type: 'json' };
-import pluginJson5 from './vite.json5.js';
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json', '.json5', '.svg', '.sass', '.scss', '.css', '.vue'];
@@ -67,7 +66,6 @@ export function getConfig(): UserConfig {
plugins: [
pluginVue(),
- pluginJson5(),
],
resolve: {
diff --git a/packages/frontend-embed/vite.json5.ts b/packages/frontend-embed/vite.json5.ts
deleted file mode 100644
index 87b67c2142..0000000000
--- a/packages/frontend-embed/vite.json5.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-// Original: https://github.com/rollup/plugins/tree/8835dd2aed92f408d7dc72d7cc25a9728e16face/packages/json
-
-import JSON5 from 'json5';
-import { Plugin } from 'rollup';
-import { createFilter, dataToEsm } from '@rollup/pluginutils';
-import { RollupJsonOptions } from '@rollup/plugin-json';
-
-// json5 extends SyntaxError with additional fields (without subclassing)
-// https://github.com/json5/json5/blob/de344f0619bda1465a6e25c76f1c0c3dda8108d9/lib/parse.js#L1111-L1112
-interface Json5SyntaxError extends SyntaxError {
- lineNumber: number;
- columnNumber: number;
-}
-
-export default function json5(options: RollupJsonOptions = {}): Plugin {
- const filter = createFilter(options.include, options.exclude);
- const indent = 'indent' in options ? options.indent : '\t';
-
- return {
- name: 'json5',
-
- // eslint-disable-next-line no-shadow
- transform(json, id) {
- if (id.slice(-6) !== '.json5' || !filter(id)) return null;
-
- try {
- const parsed = JSON5.parse(json);
- return {
- code: dataToEsm(parsed, {
- preferConst: options.preferConst,
- compact: options.compact,
- namedExports: options.namedExports,
- indent,
- }),
- map: { mappings: '' },
- };
- } catch (err) {
- if (!(err instanceof SyntaxError)) {
- throw err;
- }
- const message = 'Could not parse JSON5 file';
- const { lineNumber, columnNumber } = err as Json5SyntaxError;
- this.warn({ message, id, loc: { line: lineNumber, column: columnNumber } });
- return null;
- }
- },
- };
-}