Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
syuilo committed Aug 31, 2024
1 parent e7171d9 commit aab1c76
Show file tree
Hide file tree
Showing 117 changed files with 587 additions and 568 deletions.
5 changes: 3 additions & 2 deletions packages/frontend-embed/src/components/EmCustomEmoji.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ SPDX-License-Identifier: AGPL-3.0-only

<script lang="ts" setup>
import { computed, inject, ref } from 'vue';
import { getProxiedImageUrl } from '@/to-be-shared/media-proxy.js';
import { customEmojisMap } from '@/custom-emojis.js';

const mediaProxy = inject('mediaProxy');

const props = defineProps<{
name: string;
normal?: boolean;
Expand Down Expand Up @@ -59,7 +60,7 @@ const url = computed(() => {
const proxied =
(rawUrl.value.startsWith('/emoji/') || (props.useOriginalSize && isLocal.value))
? rawUrl.value
: getProxiedImageUrl(
: mediaProxy.getProxiedImageUrl(
rawUrl.value,
props.useOriginalSize ? undefined : 'emoji',
false,
Expand Down
17 changes: 5 additions & 12 deletions packages/frontend-embed/src/components/EmInstanceTicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,19 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { computed } from 'vue';
import { instanceName } from '@/config.js';
import { instance as Instance } from '@/instance.js';
import { getProxiedImageUrlNullable } from '@/to-be-shared/media-proxy.js';
import { computed, inject } from 'vue';

const mediaProxy = inject('mediaProxy');

const props = defineProps<{
instance?: {
instance: {
faviconUrl?: string | null
name?: string | null
themeColor?: string | null
}
}>();

// if no instance data is given, this is for the local instance
const instance = props.instance ?? {
name: instanceName,
themeColor: (document.querySelector('meta[name="theme-color-orig"]') as HTMLMetaElement).content,
};

const faviconUrl = computed(() => props.instance ? getProxiedImageUrlNullable(props.instance.faviconUrl, 'preview') : getProxiedImageUrlNullable(Instance.iconUrl, 'preview') ?? '/favicon.ico');
const faviconUrl = computed(() => mediaProxy.getProxiedImageUrlNullable(props.instance.faviconUrl, 'preview'));

const themeColor = instance.themeColor ?? '#777777';

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-embed/src/components/EmNoteDetailed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ import { userPage } from '@/utils.js';
import { notePage } from '@/utils.js';
import { i18n } from '@/i18n.js';
import { shouldCollapsed } from '@/to-be-shared/collapsed.js';
import { instance } from '@/instance.js';
import { instance } from '@/server-metadata.js';
import { url } from '@/config.js';
import EmMfm from '@/components/EmMfm.js';

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-embed/src/pages/clip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import XNotFound from '@/pages/not-found.vue';
import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { instance } from '@/server-metadata.js';
import { url, instanceName } from '@/config.js';
import { scrollToTop } from '@@/js/scroll.js';
import { isLink } from '@/scripts/is-link.js';
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-embed/src/pages/tag.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import EmNotes from '@/components/EmNotes.vue';
import XNotFound from '@/pages/not-found.vue';
import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { instance } from '@/server-metadata.js';
import { url, instanceName } from '@/config.js';
import { scrollToTop } from '@@/js/scroll.js';
import { isLink } from '@/scripts/is-link.js';
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-embed/src/pages/user-timeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import XNotFound from '@/pages/not-found.vue';
import EmTimelineContainer from '@/components/EmTimelineContainer.vue';
import { misskeyApi } from '@/misskey-api.js';
import { i18n } from '@/i18n.js';
import { instance } from '@/instance.js';
import { instance } from '@/server-metadata.js';
import { url, instanceName } from '@/config.js';
import { defaultEmbedParams } from '@/embed-page.js';

Expand Down
53 changes: 0 additions & 53 deletions packages/frontend-embed/src/to-be-shared/media-proxy.ts

This file was deleted.

4 changes: 0 additions & 4 deletions packages/frontend-shared/js/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ export const ROLE_POLICIES = [
export const CURRENT_STICKY_TOP = 'CURRENT_STICKY_TOP';
export const CURRENT_STICKY_BOTTOM = 'CURRENT_STICKY_BOTTOM';

export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://xn--931a.moe/assets/error.jpg';
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://xn--931a.moe/assets/not-found.jpg';
export const DEFAULT_INFO_IMAGE_URL = 'https://xn--931a.moe/assets/info.jpg';

export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime'];
export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
tada: ['speed=', 'delay='],
Expand Down
62 changes: 62 additions & 0 deletions packages/frontend-shared/js/media-proxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { query } from '@@/js/url.js';
import * as Misskey from 'misskey-js';

export class MediaProxy {
private serverMetadata: Misskey.entities.MetaDetailed;
private url: string;

constructor(serverMetadata: Misskey.entities.MetaDetailed, url: string) {
this.serverMetadata = serverMetadata;
this.url = url;
}

public getProxiedImageUrl(imageUrl: string, type?: 'preview' | 'emoji' | 'avatar', mustOrigin = false, noFallback = false): string {
const localProxy = `${this.url}/proxy`;

if (imageUrl.startsWith(this.serverMetadata.mediaProxy + '/') || imageUrl.startsWith('/proxy/') || imageUrl.startsWith(localProxy + '/')) {
// もう既にproxyっぽそうだったらurlを取り出す
imageUrl = (new URL(imageUrl)).searchParams.get('url') ?? imageUrl;
}

return `${mustOrigin ? localProxy : this.serverMetadata.mediaProxy}/${
type === 'preview' ? 'preview.webp'
: 'image.webp'
}?${query({
url: imageUrl,
...(!noFallback ? { 'fallback': '1' } : {}),
...(type ? { [type]: '1' } : {}),
...(mustOrigin ? { origin: '1' } : {}),
})}`;
}

public getProxiedImageUrlNullable(imageUrl: string | null | undefined, type?: 'preview'): string | null {
if (imageUrl == null) return null;
return this.getProxiedImageUrl(imageUrl, type);
}

public getStaticImageUrl(baseUrl: string): string {
const u = baseUrl.startsWith('http') ? new URL(baseUrl) : new URL(baseUrl, this.url);

if (u.href.startsWith(`${this.url}/emoji/`)) {
// もう既にemojiっぽそうだったらsearchParams付けるだけ
u.searchParams.set('static', '1');
return u.href;
}

if (u.href.startsWith(this.serverMetadata.mediaProxy + '/')) {
// もう既にproxyっぽそうだったらsearchParams付けるだけ
u.searchParams.set('static', '1');
return u.href;
}

return `${this.serverMetadata.mediaProxy}/static.webp?${query({
url: u.href,
static: '1',
})}`;
}
}
33 changes: 15 additions & 18 deletions packages/frontend/src/boot/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@

import { computed, watch, version as vueVersion, App } from 'vue';
import { compareVersions } from 'compare-versions';
import { MediaProxy } from '@@/js/media-proxy.js';
import widgets from '@/widgets/index.js';
import directives from '@/directives/index.js';
import components from '@/components/index.js';
import { version, lang, updateLocale, locale } from '@/config.js';
import { version, lang, updateLocale, locale, url } from '@/config.js';
import { applyTheme } from '@/scripts/theme.js';
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode.js';
import { updateI18n } from '@/i18n.js';
import { $i, refreshAccount, login } from '@/account.js';
import { defaultStore, ColdDeviceStorage } from '@/store.js';
import { fetchInstance, instance } from '@/instance.js';
import { fetchServerMetadata } from '@/server-metadata.js';
import { deviceKind } from '@/scripts/device-kind.js';
import { reloadChannel } from '@/scripts/unison-reload.js';
import { getUrlWithoutLoginId } from '@/scripts/login-id.js';
Expand Down Expand Up @@ -119,11 +120,7 @@ export async function common(createVue: () => App<Element>) {
await defaultStore.ready;
await deckStore.ready;

const fetchInstanceMetaPromise = fetchInstance();

fetchInstanceMetaPromise.then(() => {
miLocalStorage.setItem('v', instance.version);
});
const serverMetadata = await fetchServerMetadata();

//#region loginId
const params = new URLSearchParams(location.search);
Expand Down Expand Up @@ -178,19 +175,17 @@ export async function common(createVue: () => App<Element>) {
});
//#endregion

fetchInstanceMetaPromise.then(() => {
if (defaultStore.state.themeInitial) {
if (instance.defaultLightTheme != null) ColdDeviceStorage.set('lightTheme', JSON.parse(instance.defaultLightTheme));
if (instance.defaultDarkTheme != null) ColdDeviceStorage.set('darkTheme', JSON.parse(instance.defaultDarkTheme));
defaultStore.set('themeInitial', false);
if (defaultStore.state.themeInitial) {
if (serverMetadata.defaultLightTheme != null) ColdDeviceStorage.set('lightTheme', JSON.parse(serverMetadata.defaultLightTheme));
if (serverMetadata.defaultDarkTheme != null) ColdDeviceStorage.set('darkTheme', JSON.parse(serverMetadata.defaultDarkTheme));
defaultStore.set('themeInitial', false);
} else {
if (defaultStore.state.darkMode) {
applyTheme(darkTheme.value);
} else {
if (defaultStore.state.darkMode) {
applyTheme(darkTheme.value);
} else {
applyTheme(lightTheme.value);
}
applyTheme(lightTheme.value);
}
});
}

watch(defaultStore.reactiveState.useBlurEffectForModal, v => {
document.documentElement.style.setProperty('--modalBgFilter', v ? 'blur(4px)' : 'none');
Expand Down Expand Up @@ -239,6 +234,8 @@ export async function common(createVue: () => App<Element>) {
} catch (err) { /* empty */ }

const app = createVue();
app.provide('serverMetadata', serverMetadata);
app.provide('mediaProxy', new MediaProxy(serverMetadata, url));

setupRouter(app, createMainRouter);

Expand Down
5 changes: 3 additions & 2 deletions packages/frontend/src/boot/main-boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { alert, confirm, popup, post, toast } from '@/os.js';
import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { $i, signout, updateAccount } from '@/account.js';
import { instance } from '@/instance.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
import { miLocalStorage } from '@/local-storage.js';
Expand All @@ -23,6 +22,7 @@ import { emojiPicker } from '@/scripts/emoji-picker.js';
import { mainRouter } from '@/router/main.js';
import { type Keymap, makeHotkey } from '@/scripts/hotkey.js';
import { addCustomEmoji, removeCustomEmojis, updateCustomEmojis } from '@/custom-emojis.js';
import { fetchServerMetadata } from '@/server-metadata.js';

export async function mainBoot() {
const { isClientUpdated } = await common(() => createApp(
Expand Down Expand Up @@ -267,8 +267,9 @@ export async function mainBoot() {
}
}

const serverMetadata = await fetchServerMetadata();
const modifiedVersionMustProminentlyOfferInAgplV3Section13Read = miLocalStorage.getItem('modifiedVersionMustProminentlyOfferInAgplV3Section13Read');
if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && instance.repositoryUrl !== 'https://github.com/misskey-dev/misskey') {
if (modifiedVersionMustProminentlyOfferInAgplV3Section13Read !== 'true' && serverMetadata.repositoryUrl !== 'https://github.com/misskey-dev/misskey') {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSourceCodeAvailablePopup.vue')), {}, {
closed: () => dispose(),
});
Expand Down
6 changes: 4 additions & 2 deletions packages/frontend/src/components/MkChannelList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="pagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<img v-if="serverMetadata.infoImageUrl" :src="serverMetadata.infoImageUrl" class="_ghost"/>
<div>{{ i18n.ts.notFound }}</div>
</div>
</template>
Expand All @@ -19,10 +19,12 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { inject } from 'vue';
import MkChannelPreview from '@/components/MkChannelPreview.vue';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';

const serverMetadata = inject('serverMetadata');

const props = withDefaults(defineProps<{
pagination: Paging;
Expand Down
7 changes: 4 additions & 3 deletions packages/frontend/src/components/MkCropperDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { onMounted, shallowRef, ref } from 'vue';
import { onMounted, shallowRef, ref, inject } from 'vue';
import * as Misskey from 'misskey-js';
import Cropper from 'cropperjs';
import tinycolor from 'tinycolor2';
Expand All @@ -41,7 +41,8 @@ import { $i } from '@/account.js';
import { defaultStore } from '@/store.js';
import { apiUrl } from '@/config.js';
import { i18n } from '@/i18n.js';
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';

const mediaProxy = inject('mediaProxy');

const emit = defineEmits<{
(ev: 'ok', cropped: Misskey.entities.DriveFile): void;
Expand All @@ -55,7 +56,7 @@ const props = defineProps<{
uploadFolder?: string | null;
}>();

const imgUrl = getProxiedImageUrl(props.file.url, undefined, true);
const imgUrl = mediaProxy.getProxiedImageUrl(props.file.url, undefined, true);
const dialogEl = shallowRef<InstanceType<typeof MkModalWindow>>();
const imgEl = shallowRef<HTMLImageElement>();
let cropper: Cropper | null = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { action } from '@storybook/addon-actions';
import { StoryObj } from '@storybook/vue3';
import { onBeforeUnmount } from 'vue';
import MkDonation from './MkDonation.vue';
import { instance } from '@/instance.js';
import { instance } from '@/server-metadata.js';
export const Default = {
render(args) {
return {
Expand Down
Loading

0 comments on commit aab1c76

Please sign in to comment.