merge: Fixes to viewing notes on the remote instance (!1236)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1236

Closes #1206

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
dakkar 2025-10-27 14:58:59 +00:00
commit f7d9770386
7 changed files with 43 additions and 13 deletions

8
locales/index.d.ts vendored
View file

@ -12525,6 +12525,14 @@ export interface Locale extends ILocale {
* Failed to load note
*/
"cannotLoadNote": string;
/**
* Please click [OK] to unsubscribe from announcement e-mails.
*/
"clickToUnsubscribe": string;
/**
* There was a problem unsubscribing.
*/
"unsubscribeError": string;
"_flash": {
/**
* Flash Content Hidden

View file

@ -4,11 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div :class="$style.root"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i>{{ i18n.ts.remoteUserCaution }}<a v-if="href" :class="$style.link" :href="href" rel="nofollow noopener" target="_blank">{{ i18n.ts.showOnRemote }}</a></div>
<div :class="$style.root"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i>{{ i18n.ts.remoteUserCaution }} <a v-if="href" :class="$style.link" :href="href" rel="nofollow noopener" target="_blank" @click.prevent="warningExternalWebsite(href)" @click.stop>{{ i18n.ts.showOnRemote }}</a></div>
</template>
<script lang="ts" setup>
import { i18n } from '@/i18n.js';
import { warningExternalWebsite } from '@/utility/warning-external-website.js';
defineProps<{
href?: string;
@ -27,7 +28,6 @@ defineProps<{
}
.link {
margin-left: 4px;
color: var(--MI_THEME-accent);
}
</style>

View file

@ -79,7 +79,7 @@ Detailed view of a note in the Sharkey style. Used when opening a note onto its
<span v-if="appearNote.updatedAt" ref="menuVersionsButton" style="margin-left: 0.5em;" title="Edited" @mousedown="menuVersions()"><i class="ph-pencil-simple ph-bold ph-lg"></i></span>
<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
</div>
<SkInstanceTicker v-if="showTicker" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
<SkInstanceTicker v-if="showTicker" style="cursor: pointer;" :host="appearNote.user.host" :instance="appearNote.user.instance" @click.stop="showNoteOnOriginalInstance(appearNote)"/>
</div>
</div>
</header>
@ -290,6 +290,7 @@ import SkNoteTranslation from '@/components/SkNoteTranslation.vue';
import { getSelfNoteIds } from '@/utility/get-self-note-ids.js';
import SkUrlPreviewGroup from '@/components/SkUrlPreviewGroup.vue';
import MkNoteSub from '@/components/MkNoteSub.vue';
import { showNoteOnOriginalInstance } from '@/utility/show-note-on-original-instance.js';
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;

View file

@ -40,7 +40,7 @@ Header for a note in the Sharkey style, displaying info such as username and cre
<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ph-television ph-bold ph-lg"></i></span>
</div>
<div :class="$style.info">
<SkInstanceTicker v-if="showTicker" style="cursor: pointer;" :instance="note.user.instance" :host="note.user.host" @click.stop="showOnRemote()"/>
<SkInstanceTicker v-if="showTicker" style="cursor: pointer;" :instance="note.user.instance" :host="note.user.host" @click.stop="showNoteOnOriginalInstance(note)"/>
</div>
</div>
</header>
@ -56,7 +56,7 @@ Header for a note in the Sharkey style, displaying info such as username and cre
<div v-if="note.user.badgeRoles" :class="$style.badgeRoles">
<img v-for="(role, i) in note.user.badgeRoles" :key="i" v-tooltip="role.name" :class="$style.badgeRole" :src="role.iconUrl ?? ''"/>
</div>
<SkInstanceTicker v-if="showTicker && !isMobile && prefer.s.showTickerOnReplies" style="cursor: pointer; max-height: 5px; top: 3px; position: relative; margin-top: 0 !important;" :instance="note.user.instance" :host="note.user.host" @click.stop="showOnRemote()"/>
<SkInstanceTicker v-if="showTicker && !isMobile && prefer.s.showTickerOnReplies" style="cursor: pointer; max-height: 5px; top: 3px; position: relative; margin-top: 0 !important;" :instance="note.user.instance" :host="note.user.host" @click.stop="showNoteOnOriginalInstance(note)"/>
<div :class="$style.classicInfo">
<div v-if="mock">
<MkTime :time="note.createdAt" colored/>
@ -89,6 +89,7 @@ import { prefer } from '@/preferences';
import { useRouter } from '@/router';
import { deviceKind } from '@/utility/device-kind';
import SkInstanceTicker from '@/components/SkInstanceTicker.vue';
import { showNoteOnOriginalInstance } from '@/utility/show-note-on-original-instance.js';
const props = defineProps<{
note: Misskey.entities.Note;
@ -107,11 +108,6 @@ async function menuVersions(): Promise<void> {
popupMenu(menu, menuVersionsButton.value).then(focus).finally(cleanup);
}
function showOnRemote() {
if (props.note.url ?? props.note.uri === undefined) router.push(notePage(props.note));
else window.open(props.note.url ?? props.note.uri);
}
const mock = inject(DI.mock, false);
</script>

View file

@ -25,6 +25,7 @@ import { getAppearNote } from '@/utility/get-appear-note.js';
import { genEmbedCode } from '@/utility/get-embed-code.js';
import { prefer } from '@/preferences.js';
import { getPluginHandlers } from '@/plugin.js';
import { showNoteOnOriginalInstance } from '@/utility/show-note-on-original-instance.js';
export async function getNoteClipMenu(props: {
note: Misskey.entities.Note;
@ -359,7 +360,7 @@ export function getNoteMenu(props: {
icon: 'ti ti-external-link',
text: i18n.ts.showOnRemote,
action: () => {
window.open(appearNote.url ?? appearNote.uri, '_blank', 'noopener');
showNoteOnOriginalInstance(appearNote);
},
});
} else {
@ -548,7 +549,7 @@ export function getNoteMenu(props: {
icon: 'ti ti-external-link',
text: i18n.ts.showOnRemote,
action: () => {
window.open(appearNote.url ?? appearNote.uri, '_blank', 'noopener');
showNoteOnOriginalInstance(appearNote);
},
});
} else {

View file

@ -20,6 +20,7 @@ import { mainRouter } from '@/router.js';
import { genEmbedCode } from '@/utility/get-embed-code.js';
import { prefer } from '@/preferences.js';
import { getPluginHandlers } from '@/plugin.js';
import { warningExternalWebsite } from '@/utility/warning-external-website.js';
export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router = mainRouter) {
const meId = $i ? $i.id : null;
@ -211,7 +212,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
text: i18n.ts.showOnRemote,
action: () => {
if (user.url == null) return;
window.open(user.url, '_blank', 'noopener');
warningExternalWebsite(user.url);
},
});
} else {

View file

@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: bunnybeam and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { entities } from 'misskey-js';
import { warningExternalWebsite } from './warning-external-website';
import { useRouter } from '@/router';
import { notePage } from '@/filters/note.js';
const router = useRouter();
/**
* Show a note on the remote instance, if possible. Otherwise, show the local note.
*/
export function showNoteOnOriginalInstance(note: entities.Note) {
const remoteUrl = note.url ?? note.uri;
if (remoteUrl) {
warningExternalWebsite(remoteUrl);
} else {
router.push(notePage(note));
}
}