Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(frontend): サーバーの表示をアイコンのみに切り替えられるように #14822

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
2518cf3
Merge pull request #14675 from misskey-dev/develop
misskey-release-bot[bot] Oct 9, 2024
b99e13e
Merge pull request #14741 from misskey-dev/develop
misskey-release-bot[bot] Oct 15, 2024
2dcd911
feat(frontend): サーバーの表示をアイコンのみに切り替えられるように
MattyaDaihuku Oct 23, 2024
40ac246
Merge branch 'misskey-dev:develop' into instanceicon
MattyaDaihuku Oct 29, 2024
8c1dfab
fix(frontend): MkSelectにinstanceIconの設定を含めるように
MattyaDaihuku Nov 3, 2024
1368f58
fix(frontend): MkAvatar内にMkInstanceIconの内容を含めるように
MattyaDaihuku Nov 17, 2024
e9e2e3c
Merge branch 'develop' into instanceicon
MattyaDaihuku Nov 17, 2024
e8518de
Merge pull request #14924 from misskey-dev/develop
misskey-release-bot[bot] Nov 22, 2024
906a776
Merge branch 'misskey-dev:develop' into instanceicon
MattyaDaihuku Dec 30, 2024
3688049
Merge pull request #15279 from misskey-dev/develop
misskey-release-bot[bot] Jan 28, 2025
c93ead7
Merge pull request #15378 from misskey-dev/develop
misskey-release-bot[bot] Feb 5, 2025
4565291
Merge remote-tracking branch 'origin/master' into instanceicon
MattyaDaihuku Feb 17, 2025
b837d51
Merge remote-tracking branch 'origin/develop' into instanceicon
MattyaDaihuku Feb 17, 2025
ecec18f
Merge branch 'misskey-dev:develop' into instanceicon
MattyaDaihuku Feb 17, 2025
9633f55
fix: upstreamに追従して変更
MattyaDaihuku Feb 17, 2025
e09cde1
Merge branch 'misskey-dev:develop' into instanceicon
MattyaDaihuku Feb 21, 2025
bbb16cf
fix
MattyaDaihuku Feb 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7491,13 +7491,21 @@ export interface Locale extends ILocale {
*/
"none": string;
/**
* リモートユーザーに表示
* リモートユーザーに表示(バナー)
*/
"remote": string;
/**
* 常に表示
* 常に表示(バナー)
*/
"always": string;
/**
* リモートユーザーに表示(アイコン)
*/
"remoteIcon": string;
/**
* 常に表示(アイコン)
*/
"alwaysIcon": string;
};
"_serverDisconnectedBehavior": {
/**
Expand Down
6 changes: 4 additions & 2 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1955,8 +1955,10 @@ _displayOfSensitiveMedia:

_instanceTicker:
none: "表示しない"
remote: "リモートユーザーに表示"
always: "常に表示"
remote: "リモートユーザーに表示(バナー)"
always: "常に表示(バナー)"
remoteIcon: "リモートユーザーに表示(アイコン)"
alwaysIcon: "常に表示(アイコン)"

_serverDisconnectedBehavior:
reload: "自動でリロード"
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/components/MkNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
<MkAvatar :class="$style.avatar" :user="appearNote.user" :link="!mock" :preview="!mock"/>
<MkAvatar :class="$style.avatar" :user="appearNote.user" :link="!mock" :preview="!mock" :showInstance="showIcon && !showTicker"/>
<div :class="$style.main">
<MkNoteHeader :note="appearNote" :mini="true"/>
<MkInstanceTicker v-if="showTicker" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
Expand Down Expand Up @@ -288,6 +288,7 @@ const showSoftWordMutedWord = computed(() => defaultStore.state.showSoftWordMute
const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null);
const translating = ref(false);
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
const showIcon = (defaultStore.state.instanceTicker === 'alwaysIcon') || (defaultStore.state.instanceTicker === 'remoteIcon' && appearNote.value.user.instance);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || (appearNote.value.visibility === 'followers' && appearNote.value.userId === $i?.id));
const renoteCollapsed = ref(
defaultStore.state.collapseRenotes && isRenote && (
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/components/MkNoteDetailed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<img v-for="(role, i) in appearNote.user.badgeRoles" :key="i" v-tooltip="role.name" :class="$style.noteHeaderBadgeRole" :src="role.iconUrl!"/>
</div>
</div>
<MkInstanceTicker v-if="showTicker" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
<MkInstanceTicker v-if="showTicker || showInstanceIcon" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
</div>
</header>
<div :class="$style.noteContent">
Expand Down Expand Up @@ -304,6 +304,7 @@ const translating = ref(false);
const parsed = appearNote.value.text ? mfm.parse(appearNote.value.text) : null;
const urls = parsed ? extractUrlFromMfm(parsed).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null;
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
const showInstanceIcon = (defaultStore.state.instanceTicker === 'alwaysIcon') || (defaultStore.state.instanceTicker === 'remoteIcon' && appearNote.value.user.instance);
const conversation = ref<Misskey.entities.Note[]>([]);
const replies = ref<Misskey.entities.Note[]>([]);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || appearNote.value.userId === $i?.id);
Expand Down
60 changes: 59 additions & 1 deletion packages/frontend/src/components/global/MkAvatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</div>
<div v-if="showInstance">
<img v-if="faviconUrl" :class="$style.instanceIcon" :src="faviconUrl" :title="instanceName"/>
</div>
<template v-if="showDecoration">
<img
v-for="decoration in decorations ?? user.avatarDecorations"
Expand All @@ -42,10 +45,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { watch, ref, computed } from 'vue';
import * as Misskey from 'misskey-js';
import { instanceName as localInstanceName } from '@@/js/config.js';
import { extractAvgColorFromBlurhash } from '@@/js/extract-avg-color-from-blurhash.js';
import MkImgWithBlurhash from '../MkImgWithBlurhash.vue';
import MkA from './MkA.vue';
import { getStaticImageUrl } from '@/scripts/media-proxy.js';
import { instance as localInstance } from '@/instance.js';
import { getStaticImageUrl, getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
import { acct, userPage } from '@/filters/user.js';
import MkUserOnlineIndicator from '@/components/MkUserOnlineIndicator.vue';
import { defaultStore } from '@/store.js';
Expand All @@ -62,13 +67,22 @@ const props = withDefaults(defineProps<{
indicator?: boolean;
decorations?: (Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'> & { blink?: boolean; })[];
forceShowDecoration?: boolean;
showInstance?: boolean;
host?: string | null;
instance?: {
faviconUrl?: string | null
name?: string | null
}
}>(), {
target: null,
link: false,
preview: false,
indicator: false,
decorations: undefined,
forceShowDecoration: false,
showInstance: false,
host: null,
instance: undefined,
});

const emit = defineEmits<{
Expand All @@ -77,6 +91,22 @@ const emit = defineEmits<{

const showDecoration = props.forceShowDecoration || defaultStore.state.showAvatarDecorations;

const instanceName = computed(() => props.host == null ? localInstanceName : props.instance?.name ?? props.host);

const faviconUrl = computed(() => {
let imageSrc: string | null = null;
if (props.host == null) {
if (localInstance.iconUrl == null) {
return '/favicon.ico';
} else {
imageSrc = localInstance.iconUrl;
}
} else {
imageSrc = props.instance?.faviconUrl ?? null;
}
return getProxiedImageUrlNullable(imageSrc);
});

const bound = computed(() => props.link
? { to: userPage(props.user), target: props.target }
: {});
Expand Down Expand Up @@ -343,4 +373,32 @@ watch(() => props.user.avatarBlurhash, () => {
filter: brightness(1);
}
}

.instanceIcon {
width: 25px;
height: 25px;
border-radius: 50%;
opacity: 0.65;
z-index: 2;
position: absolute;
left: 0;
bottom: 0;
background: var(--MI_THEME-panel);
box-shadow: 0 0 0 2px var(--MI_THEME-panel);

@container (max-width: 580px) {
width: 21px;
height: 21px;
}

@container (max-width: 450px) {
width: 19px;
height: 19px;
}

@container (max-width: 300px) {
width: 17px;
height: 17px;
}
}
</style>
2 changes: 2 additions & 0 deletions packages/frontend/src/pages/settings/general.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.instanceTicker }}</template>
<option value="none">{{ i18n.ts._instanceTicker.none }}</option>
<option value="remote">{{ i18n.ts._instanceTicker.remote }}</option>
<option value="remoteIcon">{{ i18n.ts._instanceTicker.remoteIcon }}</option>
<option value="always">{{ i18n.ts._instanceTicker.always }}</option>
<option value="alwaysIcon">{{ i18n.ts._instanceTicker.alwaysIcon }}</option>
</MkSelect>

<MkSelect v-model="nsfw">
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ export const defaultStore = markRaw(new Storage('base', {
},
instanceTicker: {
where: 'device',
default: 'remote' as 'none' | 'remote' | 'always',
default: 'remote' as 'none' | 'remote' | 'always' | 'remoteIcon' | 'alwaysIcon',
},
emojiPickerScale: {
where: 'device',
Expand Down
Loading