diff --git a/locales/en-US.yml b/locales/en-US.yml index 36a733b94..45ffe4cb2 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1339,3 +1339,8 @@ _translationService: _libreTranslate: endpoint: "LibreTranslate API Endpoint" authKey: "LibreTranslate Auth Key (optional)" +_remoteInteract: + title: "I'm sorry, I'm afraid I can't do that." + description: "You cannot perform this action right now. You probably need to do it on your own instance, or sign in." + urlInstructions: "You can copy this URL. If you paste it into the search field on your instance, you should be taken to the right location." + url: "URL" diff --git a/packages/client/src/components/key-value.vue b/packages/client/src/components/key-value.vue index 2b9c735dd..079c7fbb8 100644 --- a/packages/client/src/components/key-value.vue +++ b/packages/client/src/components/key-value.vue @@ -5,6 +5,7 @@
+
diff --git a/packages/client/src/components/note-detailed.vue b/packages/client/src/components/note-detailed.vue index 3549ef953..83d8b02e2 100644 --- a/packages/client/src/components/note-detailed.vue +++ b/packages/client/src/components/note-detailed.vue @@ -126,7 +126,7 @@ import XRenoteButton from './renote-button.vue'; import MkUrlPreview from '@/components/url-preview.vue'; import MkInstanceTicker from '@/components/instance-ticker.vue'; import MkVisibility from '@/components/visibility.vue'; -import { pleaseLogin } from '@/scripts/please-login'; +import { pleaseLoginOrRemote, urlForNote } from '@/scripts/please-login'; import { checkWordMute } from '@/scripts/check-word-mute'; import { userPage } from '@/filters/user'; import { notePage } from '@/filters/note'; @@ -195,7 +195,8 @@ useNoteCapture({ }); function reply(viaKeyboard = false): void { - pleaseLogin(); + pleaseLoginOrRemote(urlForNote(appearNote)); + os.post({ reply: appearNote, animation: !viaKeyboard, @@ -205,7 +206,8 @@ function reply(viaKeyboard = false): void { } function react(): void { - pleaseLogin(); + pleaseLoginOrRemote(urlForNote(appearNote)); + blur(); reactionPicker.show(reactButton.value, reaction => { os.api('notes/reactions/create', { diff --git a/packages/client/src/components/note.vue b/packages/client/src/components/note.vue index b0938b3c0..8324f083a 100644 --- a/packages/client/src/components/note.vue +++ b/packages/client/src/components/note.vue @@ -115,7 +115,7 @@ import XRenoteButton from './renote-button.vue'; import MkUrlPreview from '@/components/url-preview.vue'; import MkInstanceTicker from '@/components/instance-ticker.vue'; import MkVisibility from '@/components/visibility.vue'; -import { pleaseLogin } from '@/scripts/please-login'; +import { pleaseLoginOrRemote, urlForNote } from '@/scripts/please-login'; import { focusPrev, focusNext } from '@/scripts/focus'; import { checkWordMute } from '@/scripts/check-word-mute'; import { userPage } from '@/filters/user'; @@ -188,7 +188,8 @@ useNoteCapture({ }); function reply(viaKeyboard = false): void { - pleaseLogin(); + pleaseLoginOrRemote(urlForNote(appearNote)); + os.post({ reply: appearNote, animation: !viaKeyboard, @@ -198,7 +199,8 @@ function reply(viaKeyboard = false): void { } function react(): void { - pleaseLogin(); + pleaseLoginOrRemote(urlForNote(appearNote)); + blur(); reactionPicker.show(reactButton.value, reaction => { os.api('notes/reactions/create', { diff --git a/packages/client/src/components/poll.vue b/packages/client/src/components/poll.vue index 92f0961c9..db1363d28 100644 --- a/packages/client/src/components/poll.vue +++ b/packages/client/src/components/poll.vue @@ -25,7 +25,7 @@ import { computed, ref } from 'vue'; import * as foundkey from 'foundkey-js'; import { sum } from '@/scripts/array'; -import { pleaseLogin } from '@/scripts/please-login'; +import { pleaseLoginOrRemote, urlForNote } from '@/scripts/please-login'; import * as os from '@/os'; import { i18n } from '@/i18n'; import { useInterval } from '@/scripts/use-interval'; @@ -68,7 +68,7 @@ if (props.note.poll.expiresAt) { } const vote = async (id) => { - pleaseLogin(); + pleaseLoginOrRemote(urlForNote(props.note)); if (props.readOnly || closed.value || isVoted.value) return; diff --git a/packages/client/src/components/remote-interact.vue b/packages/client/src/components/remote-interact.vue new file mode 100644 index 000000000..c17926435 --- /dev/null +++ b/packages/client/src/components/remote-interact.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/packages/client/src/components/renote-button.vue b/packages/client/src/components/renote-button.vue index 9e4dbb3e6..4f84b783a 100644 --- a/packages/client/src/components/renote-button.vue +++ b/packages/client/src/components/renote-button.vue @@ -17,7 +17,7 @@ import { computed, ref } from 'vue'; import { Note } from 'foundkey-js/built/entities'; import XDetails from '@/components/users-tooltip.vue'; -import { pleaseLogin } from '@/scripts/please-login'; +import { pleaseLoginOrRemote, urlForNote } from '@/scripts/please-login'; import * as os from '@/os'; import { $i } from '@/account'; import { useTooltip } from '@/scripts/use-tooltip'; @@ -51,7 +51,8 @@ useTooltip(buttonRef, async (showing) => { }); function renote(viaKeyboard = false): void { - pleaseLogin(); + pleaseLoginOrRemote(urlForNote(props.note)); + os.popupMenu([{ text: i18n.ts.renote, icon: 'fas fa-retweet', diff --git a/packages/client/src/nirax.ts b/packages/client/src/nirax.ts index 51f1dc20a..795e27eb5 100644 --- a/packages/client/src/nirax.ts +++ b/packages/client/src/nirax.ts @@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3'; import { Component, shallowRef, ShallowRef } from 'vue'; -import { pleaseLogin } from '@/scripts/please-login'; +import { pleaseLoginOrPage } from '@/scripts/please-login'; import { safeURIDecode } from '@/scripts/safe-uri-decode'; type RouteDef = { @@ -174,7 +174,7 @@ export class Router extends EventEmitter<{ } if (res.route.loginRequired) { - pleaseLogin('/'); + pleaseLoginOrPage('/'); } const isSamePath = beforePath === path; diff --git a/packages/client/src/scripts/please-login.ts b/packages/client/src/scripts/please-login.ts index 52862427b..597f32e16 100644 --- a/packages/client/src/scripts/please-login.ts +++ b/packages/client/src/scripts/please-login.ts @@ -2,8 +2,10 @@ import { defineAsyncComponent } from 'vue'; import { $i } from '@/account'; import { i18n } from '@/i18n'; import { popup } from '@/os'; +import { url } from '@/config'; +import { entities } from 'foundkey-js'; -export function pleaseLogin(path?: string) { +export function pleaseLoginOrPage(path?: string) { if ($i) return; popup(defineAsyncComponent(() => import('@/components/signin-dialog.vue')), { @@ -19,3 +21,19 @@ export function pleaseLogin(path?: string) { if (!path) throw new Error('signin required'); } + +export function pleaseLoginOrRemote(remoteUrl: string) { + if ($i) return; + + popup(defineAsyncComponent(() => import('@/components/remote-interact.vue')), { + remoteUrl, + }, {}, 'closed'); + + throw new Error('signin required'); +} + +export function urlForNote(note: entities.Note): string { + return note.url + ?? note.uri + ?? `${url}/notes/${note.id}`; +}