summaryrefslogtreecommitdiff
path: root/packages/frontend/src/scripts
diff options
context:
space:
mode:
authormisskey-release-bot[bot] <157398866+misskey-release-bot[bot]@users.noreply.github.com>2024-08-18 08:08:47 +0000
committerGitHub <noreply@github.com>2024-08-18 08:08:47 +0000
commit882c8b93c164f2841c88b58034ed58d2553a375c (patch)
treea624b844c36c6685755ece1e713febf863faedea /packages/frontend/src/scripts
parentMerge pull request #14233 from misskey-dev/develop (diff)
parentRelease: 2024.8.0 (diff)
downloadsharkey-882c8b93c164f2841c88b58034ed58d2553a375c.tar.gz
sharkey-882c8b93c164f2841c88b58034ed58d2553a375c.tar.bz2
sharkey-882c8b93c164f2841c88b58034ed58d2553a375c.zip
Merge pull request #14391 from misskey-dev/develop
Release: 2024.8.0
Diffstat (limited to 'packages/frontend/src/scripts')
-rw-r--r--packages/frontend/src/scripts/focus-trap.ts64
-rw-r--r--packages/frontend/src/scripts/get-appear-note.ts10
-rw-r--r--packages/frontend/src/scripts/get-note-menu.ts33
-rw-r--r--packages/frontend/src/scripts/isFfVisibleForMe.ts4
4 files changed, 79 insertions, 32 deletions
diff --git a/packages/frontend/src/scripts/focus-trap.ts b/packages/frontend/src/scripts/focus-trap.ts
index a5df36f520..fb7caea830 100644
--- a/packages/frontend/src/scripts/focus-trap.ts
+++ b/packages/frontend/src/scripts/focus-trap.ts
@@ -16,21 +16,57 @@ function containsFocusTrappedElements(el: HTMLElement): boolean {
});
}
+function getZIndex(el: HTMLElement): number {
+ const zIndex = parseInt(window.getComputedStyle(el).zIndex || '0', 10);
+ if (isNaN(zIndex)) {
+ return 0;
+ }
+ return zIndex;
+}
+
+function getHighestZIndexElement(): { el: HTMLElement; zIndex: number; } | null {
+ let highestZIndexElement: HTMLElement | null = null;
+ let highestZIndex = -Infinity;
+
+ focusTrapElements.forEach((el) => {
+ const zIndex = getZIndex(el);
+ if (zIndex > highestZIndex) {
+ highestZIndex = zIndex;
+ highestZIndexElement = el;
+ }
+ });
+
+ return highestZIndexElement == null ? null : {
+ el: highestZIndexElement,
+ zIndex: highestZIndex,
+ };
+}
+
function releaseFocusTrap(el: HTMLElement): void {
focusTrapElements.delete(el);
if (el.inert === true) {
el.inert = false;
}
+
+ const highestZIndexElement = getHighestZIndexElement();
+
if (el.parentElement != null && el !== document.body) {
el.parentElement.childNodes.forEach((siblingNode) => {
const siblingEl = getHTMLElementOrNull(siblingNode);
if (!siblingEl) return;
- if (siblingEl !== el && (focusTrapElements.has(siblingEl) || containsFocusTrappedElements(siblingEl) || focusTrapElements.size === 0)) {
+ if (
+ siblingEl !== el &&
+ (
+ highestZIndexElement == null ||
+ siblingEl === highestZIndexElement.el ||
+ siblingEl.contains(highestZIndexElement.el)
+ )
+ ) {
siblingEl.inert = false;
} else if (
- focusTrapElements.size > 0 &&
- !containsFocusTrappedElements(siblingEl) &&
- !focusTrapElements.has(siblingEl) &&
+ highestZIndexElement != null &&
+ siblingEl !== highestZIndexElement.el &&
+ !siblingEl.contains(highestZIndexElement.el) &&
!ignoreElements.includes(siblingEl.tagName.toLowerCase())
) {
siblingEl.inert = true;
@@ -45,9 +81,29 @@ function releaseFocusTrap(el: HTMLElement): void {
export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEls: boolean, parent: true): void;
export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEls?: boolean, parent?: false): { release: () => void; };
export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEls = false, parent = false): { release: () => void; } | void {
+ const highestZIndexElement = getHighestZIndexElement();
+
+ const highestZIndex = highestZIndexElement == null ? -Infinity : highestZIndexElement.zIndex;
+ const zIndex = getZIndex(el);
+
+ // If the element has a lower z-index than the highest z-index element, focus trap the highest z-index element instead
+ // Focus trapping for this element will be done in the release function
+ if (!parent && zIndex < highestZIndex) {
+ focusTrapElements.add(el);
+ if (highestZIndexElement) {
+ focusTrap(highestZIndexElement.el, hasInteractionWithOtherFocusTrappedEls);
+ }
+ return {
+ release: () => {
+ releaseFocusTrap(el);
+ },
+ };
+ }
+
if (el.inert === true) {
el.inert = false;
}
+
if (el.parentElement != null && el !== document.body) {
el.parentElement.childNodes.forEach((siblingNode) => {
const siblingEl = getHTMLElementOrNull(siblingNode);
diff --git a/packages/frontend/src/scripts/get-appear-note.ts b/packages/frontend/src/scripts/get-appear-note.ts
new file mode 100644
index 0000000000..40ce80eac9
--- /dev/null
+++ b/packages/frontend/src/scripts/get-appear-note.ts
@@ -0,0 +1,10 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import * as Misskey from 'misskey-js';
+
+export function getAppearNote(note: Misskey.entities.Note) {
+ return Misskey.note.isPureRenote(note) ? note.renote : note;
+}
diff --git a/packages/frontend/src/scripts/get-note-menu.ts b/packages/frontend/src/scripts/get-note-menu.ts
index ebb96d1746..2563b0baf3 100644
--- a/packages/frontend/src/scripts/get-note-menu.ts
+++ b/packages/frontend/src/scripts/get-note-menu.ts
@@ -20,6 +20,7 @@ import { clipsCache, favoritedChannelsCache } from '@/cache.js';
import { MenuItem } from '@/types/menu.js';
import MkRippleEffect from '@/components/MkRippleEffect.vue';
import { isSupportShare } from '@/scripts/navigator.js';
+import { getAppearNote } from '@/scripts/get-appear-note.js';
export async function getNoteClipMenu(props: {
note: Misskey.entities.Note;
@@ -34,14 +35,7 @@ export async function getNoteClipMenu(props: {
}
}
- const isRenote = (
- props.note.renote != null &&
- props.note.text == null &&
- props.note.fileIds.length === 0 &&
- props.note.poll == null
- );
-
- const appearNote = isRenote ? props.note.renote as Misskey.entities.Note : props.note;
+ const appearNote = getAppearNote(props.note);
const clips = await clipsCache.fetch();
const menu: MenuItem[] = [...clips.map(clip => ({
@@ -164,14 +158,7 @@ export function getNoteMenu(props: {
isDeleted: Ref<boolean>;
currentClip?: Misskey.entities.Clip;
}) {
- const isRenote = (
- props.note.renote != null &&
- props.note.text == null &&
- props.note.fileIds.length === 0 &&
- props.note.poll == null
- );
-
- const appearNote = isRenote ? props.note.renote as Misskey.entities.Note : props.note;
+ const appearNote = getAppearNote(props.note);
const cleanups = [] as (() => void)[];
@@ -248,6 +235,7 @@ export function getNoteMenu(props: {
}
async function unclip(): Promise<void> {
+ if (!props.currentClip) return;
os.apiWithDialog('clips/remove-note', { clipId: props.currentClip.id, noteId: appearNote.id });
props.isDeleted.value = true;
}
@@ -267,8 +255,8 @@ export function getNoteMenu(props: {
function share(): void {
navigator.share({
- title: i18n.tsx.noteOf({ user: appearNote.user.name }),
- text: appearNote.text,
+ title: i18n.tsx.noteOf({ user: appearNote.user.name ?? appearNote.user.username }),
+ text: appearNote.text ?? '',
url: `${url}/notes/${appearNote.id}`,
});
}
@@ -509,14 +497,7 @@ export function getRenoteMenu(props: {
renoteButton: ShallowRef<HTMLElement | undefined>;
mock?: boolean;
}) {
- const isRenote = (
- props.note.renote != null &&
- props.note.text == null &&
- props.note.fileIds.length === 0 &&
- props.note.poll == null
- );
-
- const appearNote = isRenote ? props.note.renote as Misskey.entities.Note : props.note;
+ const appearNote = getAppearNote(props.note);
const channelRenoteItems: MenuItem[] = [];
const normalRenoteItems: MenuItem[] = [];
diff --git a/packages/frontend/src/scripts/isFfVisibleForMe.ts b/packages/frontend/src/scripts/isFfVisibleForMe.ts
index 406404c462..e28e5725bc 100644
--- a/packages/frontend/src/scripts/isFfVisibleForMe.ts
+++ b/packages/frontend/src/scripts/isFfVisibleForMe.ts
@@ -7,7 +7,7 @@ import * as Misskey from 'misskey-js';
import { $i } from '@/account.js';
export function isFollowingVisibleForMe(user: Misskey.entities.UserDetailed): boolean {
- if ($i && $i.id === user.id) return true;
+ if ($i && ($i.id === user.id || $i.isAdmin || $i.isModerator)) return true;
if (user.followingVisibility === 'private') return false;
if (user.followingVisibility === 'followers' && !user.isFollowing) return false;
@@ -15,7 +15,7 @@ export function isFollowingVisibleForMe(user: Misskey.entities.UserDetailed): bo
return true;
}
export function isFollowersVisibleForMe(user: Misskey.entities.UserDetailed): boolean {
- if ($i && $i.id === user.id) return true;
+ if ($i && ($i.id === user.id || $i.isAdmin || $i.isModerator)) return true;
if (user.followersVisibility === 'private') return false;
if (user.followersVisibility === 'followers' && !user.isFollowing) return false;