@abraca/nuxt 2.0.1 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.d.mts +18 -7
- package/dist/module.json +1 -1
- package/dist/module.mjs +21 -5
- package/dist/runtime/assets/aware-tokens.css +1 -0
- package/dist/runtime/components/AAccountSwitcherModal.d.vue.ts +16 -1
- package/dist/runtime/components/AAccountSwitcherModal.vue +33 -4
- package/dist/runtime/components/AAccountSwitcherModal.vue.d.ts +16 -1
- package/dist/runtime/components/AAuthLinkLanding.d.vue.ts +3 -0
- package/dist/runtime/components/AAuthLinkLanding.vue +85 -0
- package/dist/runtime/components/AAuthLinkLanding.vue.d.ts +3 -0
- package/dist/runtime/components/AClaimAccountModal.d.vue.ts +7 -1
- package/dist/runtime/components/AClaimAccountModal.vue +28 -13
- package/dist/runtime/components/AClaimAccountModal.vue.d.ts +7 -1
- package/dist/runtime/components/AEmailVerifyConfirmModal.d.vue.ts +30 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.vue +100 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.vue.d.ts +30 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.d.vue.ts +22 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.vue +65 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.vue.d.ts +22 -0
- package/dist/runtime/components/AMnemonicLoginModal.d.vue.ts +1 -1
- package/dist/runtime/components/AMnemonicLoginModal.vue.d.ts +1 -1
- package/dist/runtime/components/ANodePanel.vue +2 -0
- package/dist/runtime/components/ANotificationBell.d.vue.ts +2 -2
- package/dist/runtime/components/ANotificationBell.vue.d.ts +2 -2
- package/dist/runtime/components/APasswordChangeModal.d.vue.ts +28 -0
- package/dist/runtime/components/APasswordChangeModal.vue +178 -0
- package/dist/runtime/components/APasswordChangeModal.vue.d.ts +28 -0
- package/dist/runtime/components/APasswordLoginModal.d.vue.ts +42 -0
- package/dist/runtime/components/APasswordLoginModal.vue +177 -0
- package/dist/runtime/components/APasswordLoginModal.vue.d.ts +42 -0
- package/dist/runtime/components/APasswordRegisterModal.d.vue.ts +49 -0
- package/dist/runtime/components/APasswordRegisterModal.vue +262 -0
- package/dist/runtime/components/APasswordRegisterModal.vue.d.ts +49 -0
- package/dist/runtime/components/APasswordResetConfirmModal.d.vue.ts +31 -0
- package/dist/runtime/components/APasswordResetConfirmModal.vue +154 -0
- package/dist/runtime/components/APasswordResetConfirmModal.vue.d.ts +31 -0
- package/dist/runtime/components/APasswordResetRequestModal.d.vue.ts +35 -0
- package/dist/runtime/components/APasswordResetRequestModal.vue +113 -0
- package/dist/runtime/components/APasswordResetRequestModal.vue.d.ts +35 -0
- package/dist/runtime/components/ASetPasswordCard.d.vue.ts +26 -0
- package/dist/runtime/components/ASetPasswordCard.vue +139 -0
- package/dist/runtime/components/ASetPasswordCard.vue.d.ts +26 -0
- package/dist/runtime/components/aware/AAccordion.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AAccordion.vue +11 -1
- package/dist/runtime/components/aware/AAccordion.vue.d.ts +2 -0
- package/dist/runtime/components/aware/AButton.vue +3 -3
- package/dist/runtime/components/aware/ACollapsible.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ACollapsible.vue +9 -1
- package/dist/runtime/components/aware/ACollapsible.vue.d.ts +2 -0
- package/dist/runtime/components/aware/AGlobalFocusLayer.vue +1 -1
- package/dist/runtime/components/aware/AHoverItem.vue +28 -3
- package/dist/runtime/components/aware/AMedia.d.vue.ts +1 -1
- package/dist/runtime/components/aware/AMedia.vue.d.ts +1 -1
- package/dist/runtime/components/aware/AModal.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AModal.vue +9 -1
- package/dist/runtime/components/aware/AModal.vue.d.ts +2 -0
- package/dist/runtime/components/aware/APresenceBlobs.vue +1 -1
- package/dist/runtime/components/aware/APresenceCursors.vue +1 -1
- package/dist/runtime/components/aware/AScroll.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AScroll.vue +13 -3
- package/dist/runtime/components/aware/AScroll.vue.d.ts +2 -0
- package/dist/runtime/components/aware/ASlideover.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ASlideover.vue +9 -1
- package/dist/runtime/components/aware/ASlideover.vue.d.ts +2 -0
- package/dist/runtime/components/aware/ASlider.vue +1 -0
- package/dist/runtime/components/aware/ATabs.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ATabs.vue +9 -1
- package/dist/runtime/components/aware/ATabs.vue.d.ts +2 -0
- package/dist/runtime/components/chat/ANodeChatPanel.vue +1 -0
- package/dist/runtime/components/editor/AEditorRedoButton.d.vue.ts +2 -2
- package/dist/runtime/components/editor/AEditorRedoButton.vue.d.ts +2 -2
- package/dist/runtime/components/editor/AEditorUndoButton.d.vue.ts +2 -2
- package/dist/runtime/components/editor/AEditorUndoButton.vue.d.ts +2 -2
- package/dist/runtime/components/shell/AUserMenu.d.vue.ts +2 -2
- package/dist/runtime/components/shell/AUserMenu.vue.d.ts +2 -2
- package/dist/runtime/components/shell/AUserProfilePopover.d.vue.ts +1 -1
- package/dist/runtime/components/shell/AUserProfilePopover.vue.d.ts +1 -1
- package/dist/runtime/composables/useAAField.js +7 -4
- package/dist/runtime/composables/useAAFocus.js +10 -5
- package/dist/runtime/composables/useAAFollowAnchor.js +68 -34
- package/dist/runtime/composables/useAAFollowPeer.d.ts +7 -4
- package/dist/runtime/composables/useAAFollowPeer.js +60 -11
- package/dist/runtime/composables/useAAViewport.d.ts +1 -1
- package/dist/runtime/composables/useAbracadabraAuth.d.ts +2 -0
- package/dist/runtime/composables/useAbracadabraAuth.js +2 -0
- package/dist/runtime/composables/useEmailVerification.d.ts +40 -26
- package/dist/runtime/composables/useEmailVerification.js +95 -43
- package/dist/runtime/composables/usePasswordAuth.d.ts +64 -0
- package/dist/runtime/composables/usePasswordAuth.js +126 -0
- package/dist/runtime/composables/useTiptapHistory.d.ts +2 -2
- package/dist/runtime/composables/useTiptapHistory.js +5 -5
- package/dist/runtime/extensions/views/MetaFieldView.vue +23 -6
- package/dist/runtime/plugin-abracadabra.client.js +57 -8
- package/dist/runtime/plugin-abracadabra.server.js +2 -0
- package/dist/runtime/server/plugins/abracadabra-service.js +20 -9
- package/dist/runtime/types.d.ts +11 -0
- package/dist/runtime/utils/awareRingStyle.js +1 -1
- package/package.json +7 -7
- package/dist/runtime/components/renderers/ASpatialRenderer.d.vue.ts +0 -19
- package/dist/runtime/components/renderers/ASpatialRenderer.vue +0 -459
- package/dist/runtime/components/renderers/ASpatialRenderer.vue.d.ts +0 -19
- package/dist/runtime/components/renderers/spatial/SpatialGround.d.vue.ts +0 -20
- package/dist/runtime/components/renderers/spatial/SpatialGround.vue +0 -26
- package/dist/runtime/components/renderers/spatial/SpatialGround.vue.d.ts +0 -20
- package/dist/runtime/components/renderers/spatial/SpatialObject.d.vue.ts +0 -17
- package/dist/runtime/components/renderers/spatial/SpatialObject.vue +0 -257
- package/dist/runtime/components/renderers/spatial/SpatialObject.vue.d.ts +0 -17
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.d.vue.ts +0 -15
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.vue +0 -18
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.vue.d.ts +0 -15
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.d.vue.ts +0 -16
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.vue +0 -66
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.vue.d.ts +0 -16
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.d.vue.ts +0 -8
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.vue +0 -53
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.vue.d.ts +0 -8
- package/dist/runtime/composables/useSpatialCamera.d.ts +0 -16
- package/dist/runtime/composables/useSpatialCamera.js +0 -175
- package/dist/runtime/composables/useSpatialDrag.d.ts +0 -14
- package/dist/runtime/composables/useSpatialDrag.js +0 -137
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
open: { type: Boolean, required: false },
|
|
5
|
+
loading: { type: Boolean, required: false, default: false },
|
|
6
|
+
sent: { type: Boolean, required: false, default: false },
|
|
7
|
+
error: { type: [String, null], required: false },
|
|
8
|
+
title: { type: String, required: false, default: "Reset your password" },
|
|
9
|
+
subtitle: { type: String, required: false, default: "Enter your username or email and we'll send you a reset link." },
|
|
10
|
+
showSignInLink: { type: Boolean, required: false, default: true }
|
|
11
|
+
});
|
|
12
|
+
const emit = defineEmits(["update:open", "submit", "signin"]);
|
|
13
|
+
const open = computed({
|
|
14
|
+
get: () => !!props.open,
|
|
15
|
+
set: (v) => emit("update:open", v)
|
|
16
|
+
});
|
|
17
|
+
const identifier = ref("");
|
|
18
|
+
watch(() => props.open, (v) => {
|
|
19
|
+
if (!v) return;
|
|
20
|
+
identifier.value = "";
|
|
21
|
+
});
|
|
22
|
+
const canSubmit = computed(
|
|
23
|
+
() => !!identifier.value.trim() && !props.loading && !props.sent
|
|
24
|
+
);
|
|
25
|
+
function submit() {
|
|
26
|
+
if (!canSubmit.value) return;
|
|
27
|
+
emit("submit", { identifier: identifier.value.trim() });
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<UModal
|
|
33
|
+
v-model:open="open"
|
|
34
|
+
:title="title"
|
|
35
|
+
:ui="{ content: 'sm:max-w-md' }"
|
|
36
|
+
>
|
|
37
|
+
<template #body>
|
|
38
|
+
<div class="flex flex-col gap-4">
|
|
39
|
+
<UAlert
|
|
40
|
+
v-if="sent"
|
|
41
|
+
color="success"
|
|
42
|
+
variant="soft"
|
|
43
|
+
icon="i-lucide-mail-check"
|
|
44
|
+
title="Check your inbox"
|
|
45
|
+
description="If an account matches that identifier, we've sent a password reset link. The link expires shortly — use it soon."
|
|
46
|
+
/>
|
|
47
|
+
|
|
48
|
+
<template v-else>
|
|
49
|
+
<p class="text-sm text-(--ui-text-muted)">
|
|
50
|
+
{{ subtitle }}
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
<UAlert
|
|
54
|
+
v-if="error"
|
|
55
|
+
color="error"
|
|
56
|
+
variant="soft"
|
|
57
|
+
icon="i-lucide-triangle-alert"
|
|
58
|
+
:description="error"
|
|
59
|
+
/>
|
|
60
|
+
|
|
61
|
+
<div class="flex flex-col gap-1">
|
|
62
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">Username or email</label>
|
|
63
|
+
<UInput
|
|
64
|
+
v-model="identifier"
|
|
65
|
+
size="md"
|
|
66
|
+
autofocus
|
|
67
|
+
autocomplete="username"
|
|
68
|
+
placeholder="your-handle or you@example.com"
|
|
69
|
+
icon="i-lucide-mail-question"
|
|
70
|
+
@keydown.enter="submit"
|
|
71
|
+
/>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div
|
|
75
|
+
v-if="showSignInLink"
|
|
76
|
+
class="-mt-1 text-xs"
|
|
77
|
+
>
|
|
78
|
+
<UButton
|
|
79
|
+
variant="link"
|
|
80
|
+
color="neutral"
|
|
81
|
+
size="xs"
|
|
82
|
+
label="Back to sign in"
|
|
83
|
+
@click="emit('signin')"
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</template>
|
|
87
|
+
</div>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<template #footer>
|
|
91
|
+
<div class="flex items-center justify-end gap-2 w-full">
|
|
92
|
+
<UButton
|
|
93
|
+
variant="ghost"
|
|
94
|
+
color="neutral"
|
|
95
|
+
size="sm"
|
|
96
|
+
:label="sent ? 'Close' : 'Cancel'"
|
|
97
|
+
:disabled="loading"
|
|
98
|
+
@click="open = false"
|
|
99
|
+
/>
|
|
100
|
+
<UButton
|
|
101
|
+
v-if="!sent"
|
|
102
|
+
color="primary"
|
|
103
|
+
size="sm"
|
|
104
|
+
icon="i-lucide-mail"
|
|
105
|
+
label="Send reset link"
|
|
106
|
+
:loading="loading"
|
|
107
|
+
:disabled="!canSubmit"
|
|
108
|
+
@click="submit"
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</template>
|
|
112
|
+
</UModal>
|
|
113
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Flip to true after the consumer's submit handler resolves; flips the modal to the
|
|
6
|
+
* "we sent an email if that account exists" confirmation copy.
|
|
7
|
+
*/
|
|
8
|
+
sent?: boolean;
|
|
9
|
+
error?: string | null;
|
|
10
|
+
title?: string;
|
|
11
|
+
subtitle?: string;
|
|
12
|
+
/** Show the "Back to sign in" link in the footer. */
|
|
13
|
+
showSignInLink?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
|
+
submit: (payload: {
|
|
17
|
+
identifier: string;
|
|
18
|
+
}) => any;
|
|
19
|
+
"update:open": (v: boolean) => any;
|
|
20
|
+
signin: () => any;
|
|
21
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
22
|
+
onSubmit?: ((payload: {
|
|
23
|
+
identifier: string;
|
|
24
|
+
}) => any) | undefined;
|
|
25
|
+
"onUpdate:open"?: ((v: boolean) => any) | undefined;
|
|
26
|
+
onSignin?: (() => any) | undefined;
|
|
27
|
+
}>, {
|
|
28
|
+
subtitle: string;
|
|
29
|
+
title: string;
|
|
30
|
+
loading: boolean;
|
|
31
|
+
sent: boolean;
|
|
32
|
+
showSignInLink: boolean;
|
|
33
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
loading?: boolean;
|
|
3
|
+
error?: string | null;
|
|
4
|
+
/** Flip to true after a successful set — card shows a success state. */
|
|
5
|
+
success?: boolean;
|
|
6
|
+
title?: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
minLength?: number;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
submit: (payload: {
|
|
12
|
+
password: string;
|
|
13
|
+
}) => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
onSubmit?: ((payload: {
|
|
16
|
+
password: string;
|
|
17
|
+
}) => any) | undefined;
|
|
18
|
+
}>, {
|
|
19
|
+
subtitle: string;
|
|
20
|
+
title: string;
|
|
21
|
+
success: boolean;
|
|
22
|
+
minLength: number;
|
|
23
|
+
loading: boolean;
|
|
24
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
loading: { type: Boolean, required: false, default: false },
|
|
5
|
+
error: { type: [String, null], required: false },
|
|
6
|
+
success: { type: Boolean, required: false, default: false },
|
|
7
|
+
title: { type: String, required: false, default: "Add a password" },
|
|
8
|
+
subtitle: { type: String, required: false, default: "Your account currently relies on this device's passkey. Adding a password lets you sign in from a second device or recover access if this device is lost." },
|
|
9
|
+
minLength: { type: Number, required: false, default: 8 }
|
|
10
|
+
});
|
|
11
|
+
const emit = defineEmits(["submit"]);
|
|
12
|
+
const password = ref("");
|
|
13
|
+
const confirm = ref("");
|
|
14
|
+
const showPassword = ref(false);
|
|
15
|
+
watch(() => props.success, (v) => {
|
|
16
|
+
if (!v) return;
|
|
17
|
+
password.value = "";
|
|
18
|
+
confirm.value = "";
|
|
19
|
+
showPassword.value = false;
|
|
20
|
+
});
|
|
21
|
+
const passwordTooShort = computed(
|
|
22
|
+
() => password.value.length > 0 && password.value.length < props.minLength
|
|
23
|
+
);
|
|
24
|
+
const confirmMismatch = computed(
|
|
25
|
+
() => confirm.value.length > 0 && confirm.value !== password.value
|
|
26
|
+
);
|
|
27
|
+
const canSubmit = computed(
|
|
28
|
+
() => password.value.length >= props.minLength && confirm.value === password.value && !props.loading && !props.success
|
|
29
|
+
);
|
|
30
|
+
function submit() {
|
|
31
|
+
if (!canSubmit.value) return;
|
|
32
|
+
emit("submit", { password: password.value });
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<div class="set-pw-card">
|
|
38
|
+
<div class="set-pw-head">
|
|
39
|
+
<UIcon
|
|
40
|
+
name="i-lucide-key-square"
|
|
41
|
+
class="size-5 text-(--ui-primary) shrink-0"
|
|
42
|
+
/>
|
|
43
|
+
<div class="flex-1">
|
|
44
|
+
<h4 class="set-pw-title">
|
|
45
|
+
{{ title }}
|
|
46
|
+
</h4>
|
|
47
|
+
<p class="set-pw-sub">
|
|
48
|
+
{{ subtitle }}
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<UAlert
|
|
54
|
+
v-if="success"
|
|
55
|
+
color="success"
|
|
56
|
+
variant="soft"
|
|
57
|
+
icon="i-lucide-check"
|
|
58
|
+
title="Password set"
|
|
59
|
+
description="You can now sign in with your username and password from another device."
|
|
60
|
+
/>
|
|
61
|
+
|
|
62
|
+
<UAlert
|
|
63
|
+
v-else-if="error"
|
|
64
|
+
color="error"
|
|
65
|
+
variant="soft"
|
|
66
|
+
icon="i-lucide-triangle-alert"
|
|
67
|
+
:description="error"
|
|
68
|
+
/>
|
|
69
|
+
|
|
70
|
+
<template v-if="!success">
|
|
71
|
+
<div class="set-pw-field">
|
|
72
|
+
<label class="set-pw-label">New password</label>
|
|
73
|
+
<UInput
|
|
74
|
+
v-model="password"
|
|
75
|
+
:type="showPassword ? 'text' : 'password'"
|
|
76
|
+
size="md"
|
|
77
|
+
autocomplete="new-password"
|
|
78
|
+
:placeholder="`${minLength}+ characters`"
|
|
79
|
+
icon="i-lucide-lock"
|
|
80
|
+
:ui="{ trailing: 'pe-1' }"
|
|
81
|
+
@keydown.enter="submit"
|
|
82
|
+
>
|
|
83
|
+
<template #trailing>
|
|
84
|
+
<UButton
|
|
85
|
+
tabindex="-1"
|
|
86
|
+
variant="ghost"
|
|
87
|
+
color="neutral"
|
|
88
|
+
size="xs"
|
|
89
|
+
:icon="showPassword ? 'i-lucide-eye-off' : 'i-lucide-eye'"
|
|
90
|
+
:aria-label="showPassword ? 'Hide password' : 'Show password'"
|
|
91
|
+
@click="showPassword = !showPassword"
|
|
92
|
+
/>
|
|
93
|
+
</template>
|
|
94
|
+
</UInput>
|
|
95
|
+
<p
|
|
96
|
+
v-if="passwordTooShort"
|
|
97
|
+
class="set-pw-err"
|
|
98
|
+
>
|
|
99
|
+
At least {{ minLength }} characters.
|
|
100
|
+
</p>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div class="set-pw-field">
|
|
104
|
+
<label class="set-pw-label">Confirm</label>
|
|
105
|
+
<UInput
|
|
106
|
+
v-model="confirm"
|
|
107
|
+
:type="showPassword ? 'text' : 'password'"
|
|
108
|
+
size="md"
|
|
109
|
+
autocomplete="new-password"
|
|
110
|
+
placeholder="Type it again"
|
|
111
|
+
icon="i-lucide-shield-check"
|
|
112
|
+
@keydown.enter="submit"
|
|
113
|
+
/>
|
|
114
|
+
<p
|
|
115
|
+
v-if="confirmMismatch"
|
|
116
|
+
class="set-pw-err"
|
|
117
|
+
>
|
|
118
|
+
Passwords don't match.
|
|
119
|
+
</p>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="set-pw-actions">
|
|
123
|
+
<UButton
|
|
124
|
+
color="primary"
|
|
125
|
+
size="sm"
|
|
126
|
+
icon="i-lucide-key-round"
|
|
127
|
+
label="Set password"
|
|
128
|
+
:loading="loading"
|
|
129
|
+
:disabled="!canSubmit"
|
|
130
|
+
@click="submit"
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
</template>
|
|
134
|
+
</div>
|
|
135
|
+
</template>
|
|
136
|
+
|
|
137
|
+
<style scoped>
|
|
138
|
+
.set-pw-card{background:var(--ui-bg);border:1px solid var(--ui-border);border-radius:.6rem;display:flex;flex-direction:column;gap:.75rem;padding:1rem}.set-pw-head{align-items:flex-start;display:flex;gap:.6rem}.set-pw-title{color:var(--ui-text-highlighted);font-size:.875rem;font-weight:600;margin:0}.set-pw-sub{color:var(--ui-text-muted);font-size:.8125rem;line-height:1.5;margin:.2rem 0 0}.set-pw-field{display:flex;flex-direction:column;gap:.25rem}.set-pw-label{color:var(--ui-text-muted);font-size:.7rem;font-weight:500}.set-pw-err{color:var(--ui-color-error-500);font-size:.7rem;margin:0}.set-pw-actions{display:flex;justify-content:flex-end;padding-top:.25rem}
|
|
139
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
loading?: boolean;
|
|
3
|
+
error?: string | null;
|
|
4
|
+
/** Flip to true after a successful set — card shows a success state. */
|
|
5
|
+
success?: boolean;
|
|
6
|
+
title?: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
minLength?: number;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
submit: (payload: {
|
|
12
|
+
password: string;
|
|
13
|
+
}) => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
onSubmit?: ((payload: {
|
|
16
|
+
password: string;
|
|
17
|
+
}) => any) | undefined;
|
|
18
|
+
}>, {
|
|
19
|
+
subtitle: string;
|
|
20
|
+
title: string;
|
|
21
|
+
success: boolean;
|
|
22
|
+
minLength: number;
|
|
23
|
+
loading: boolean;
|
|
24
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
@@ -2,6 +2,7 @@ type __VLS_Props = {
|
|
|
2
2
|
fieldKey: string;
|
|
3
3
|
awareness?: boolean;
|
|
4
4
|
live?: boolean;
|
|
5
|
+
followOnly?: boolean;
|
|
5
6
|
total?: boolean;
|
|
6
7
|
};
|
|
7
8
|
declare var __VLS_9: string, __VLS_10: any, __VLS_27: string, __VLS_28: any;
|
|
@@ -13,6 +14,7 @@ type __VLS_Slots = {} & {
|
|
|
13
14
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
14
15
|
awareness: boolean;
|
|
15
16
|
live: boolean;
|
|
17
|
+
followOnly: boolean;
|
|
16
18
|
total: boolean;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
20
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { computed, ref, useAttrs, watch } from "vue";
|
|
3
3
|
import { useAAField } from "../../composables/useAAField";
|
|
4
4
|
import { useAAUIState } from "../../composables/useAAUIState";
|
|
5
|
+
import { useAAFollowPeer } from "../../composables/useAAFollowPeer";
|
|
5
6
|
import AHoverItem from "./AHoverItem.vue";
|
|
6
7
|
function itemId(item) {
|
|
7
8
|
if (item == null) return "";
|
|
@@ -18,10 +19,12 @@ const props = defineProps({
|
|
|
18
19
|
fieldKey: { type: String, required: true },
|
|
19
20
|
awareness: { type: Boolean, required: false, default: true },
|
|
20
21
|
live: { type: Boolean, required: false, default: false },
|
|
22
|
+
followOnly: { type: Boolean, required: false, default: false },
|
|
21
23
|
total: { type: Boolean, required: false, default: false }
|
|
22
24
|
});
|
|
25
|
+
const { isFollowing } = useAAFollowPeer();
|
|
23
26
|
const enableAwareness = computed(() => props.awareness || props.total);
|
|
24
|
-
const enableLive = computed(() => props.live || props.total);
|
|
27
|
+
const enableLive = computed(() => props.live || props.total || props.followOnly && isFollowing.value);
|
|
25
28
|
const attrs = useAttrs();
|
|
26
29
|
const { hoverers, focusers, hoverHandlers } = useAAField(() => props.fieldKey);
|
|
27
30
|
const liveExpanded = useAAUIState(() => `${props.fieldKey}:expanded`, { defaultValue: "" });
|
|
@@ -37,6 +40,13 @@ watch(local, (val) => {
|
|
|
37
40
|
if (!enableLive.value) return;
|
|
38
41
|
if (JSON.stringify(liveExpanded.value) !== JSON.stringify(val)) liveExpanded.value = val;
|
|
39
42
|
});
|
|
43
|
+
watch(enableLive, (now, prev) => {
|
|
44
|
+
if (!now || prev) return;
|
|
45
|
+
const incoming = liveExpanded.value;
|
|
46
|
+
if (incoming != null && JSON.stringify(local.value) !== JSON.stringify(incoming)) {
|
|
47
|
+
local.value = incoming;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
40
50
|
const ringStyle = computed(() => {
|
|
41
51
|
if (!enableAwareness.value) return void 0;
|
|
42
52
|
const focusColor = focusers.value[0]?.user?.color;
|
|
@@ -2,6 +2,7 @@ type __VLS_Props = {
|
|
|
2
2
|
fieldKey: string;
|
|
3
3
|
awareness?: boolean;
|
|
4
4
|
live?: boolean;
|
|
5
|
+
followOnly?: boolean;
|
|
5
6
|
total?: boolean;
|
|
6
7
|
};
|
|
7
8
|
declare var __VLS_9: string, __VLS_10: any, __VLS_27: string, __VLS_28: any;
|
|
@@ -13,6 +14,7 @@ type __VLS_Slots = {} & {
|
|
|
13
14
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
14
15
|
awareness: boolean;
|
|
15
16
|
live: boolean;
|
|
17
|
+
followOnly: boolean;
|
|
16
18
|
total: boolean;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
20
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -7,7 +7,7 @@ const props = defineProps({
|
|
|
7
7
|
fieldKey: { type: String, required: true },
|
|
8
8
|
max: { type: Number, required: false, default: 3 }
|
|
9
9
|
});
|
|
10
|
-
const { hoverers, focusers, pressers, isPressed, handlers } = useAAField(() => props.fieldKey);
|
|
10
|
+
const { hoverers, focusers, pressers, isPressed, localPress, handlers } = useAAField(() => props.fieldKey);
|
|
11
11
|
const ringStyle = computed(() => awareRingStyle({
|
|
12
12
|
hover: hoverers.value[0]?.user?.color,
|
|
13
13
|
focus: focusers.value[0]?.user?.color,
|
|
@@ -31,7 +31,7 @@ const overlayPeers = computed(() => {
|
|
|
31
31
|
return out;
|
|
32
32
|
});
|
|
33
33
|
const pulseKey = ref(0);
|
|
34
|
-
watch(
|
|
34
|
+
watch(localPress, (val, prev) => {
|
|
35
35
|
if (val && !prev) pulseKey.value++;
|
|
36
36
|
});
|
|
37
37
|
const pulseColor = computed(
|
|
@@ -72,5 +72,5 @@ const pulseColor = computed(
|
|
|
72
72
|
</template>
|
|
73
73
|
|
|
74
74
|
<style scoped>
|
|
75
|
-
.aa-host{border-radius:var(--ui-radius,.375rem);position:relative;transition:filter
|
|
75
|
+
.aa-host{border-radius:var(--ui-radius,.375rem);position:relative;transition:filter var(--aa-state-fade-filter),box-shadow var(--aa-state-fade-shadow)}.aa-host--inline{display:inline-flex}.aa-host--pressed{filter:brightness(.88)}.aa-press-pulse{animation:aa-press-pulse var(--aa-pulse-duration) var(--aa-pulse-easing) forwards;border-radius:inherit;inset:0;pointer-events:none;position:absolute}@keyframes aa-press-pulse{0%{box-shadow:0 0 0 0 var(--aa-pulse-color);opacity:var(--aa-pulse-opacity-start-button)}to{box-shadow:0 0 0 var(--aa-pulse-radius-button) var(--aa-pulse-color);opacity:0}}.aa-overlay{display:flex;pointer-events:none;position:absolute;right:0;top:-.625rem;z-index:10}.aa-overlay>*+*{margin-left:-.25rem}.aa-peer-enter-active,.aa-peer-leave-active{transition:opacity var(--aa-peer-fade-duration) var(--aa-peer-fade-easing)}.aa-peer-enter-from,.aa-peer-leave-to{opacity:0}
|
|
76
76
|
</style>
|
|
@@ -2,6 +2,7 @@ type __VLS_Props = {
|
|
|
2
2
|
fieldKey: string;
|
|
3
3
|
awareness?: boolean;
|
|
4
4
|
live?: boolean;
|
|
5
|
+
followOnly?: boolean;
|
|
5
6
|
total?: boolean;
|
|
6
7
|
};
|
|
7
8
|
declare var __VLS_10: string, __VLS_11: any, __VLS_22: string, __VLS_23: any;
|
|
@@ -13,6 +14,7 @@ type __VLS_Slots = {} & {
|
|
|
13
14
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
14
15
|
awareness: boolean;
|
|
15
16
|
live: boolean;
|
|
17
|
+
followOnly: boolean;
|
|
16
18
|
total: boolean;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
20
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref, useAttrs, watch } from "vue";
|
|
3
3
|
import { useAAUIState } from "../../composables/useAAUIState";
|
|
4
|
+
import { useAAFollowPeer } from "../../composables/useAAFollowPeer";
|
|
4
5
|
defineOptions({ inheritAttrs: false });
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
fieldKey: { type: String, required: true },
|
|
7
8
|
awareness: { type: Boolean, required: false, default: true },
|
|
8
9
|
live: { type: Boolean, required: false, default: false },
|
|
10
|
+
followOnly: { type: Boolean, required: false, default: false },
|
|
9
11
|
total: { type: Boolean, required: false, default: false }
|
|
10
12
|
});
|
|
11
|
-
const
|
|
13
|
+
const { isFollowing } = useAAFollowPeer();
|
|
14
|
+
const enableLive = computed(() => props.live || props.total || props.followOnly && isFollowing.value);
|
|
12
15
|
const attrs = useAttrs();
|
|
13
16
|
const liveOpen = useAAUIState(() => `${props.fieldKey}:open`, { defaultValue: false });
|
|
14
17
|
const hasExternalOpen = computed(() => "open" in attrs || "onUpdate:open" in attrs);
|
|
@@ -22,6 +25,11 @@ watch(local, (val) => {
|
|
|
22
25
|
if (!enableLive.value) return;
|
|
23
26
|
if (!!liveOpen.value !== val) liveOpen.value = val;
|
|
24
27
|
});
|
|
28
|
+
watch(enableLive, (now, prev) => {
|
|
29
|
+
if (!now || prev) return;
|
|
30
|
+
const incoming = !!liveOpen.value;
|
|
31
|
+
if (local.value !== incoming) local.value = incoming;
|
|
32
|
+
});
|
|
25
33
|
</script>
|
|
26
34
|
|
|
27
35
|
<template>
|
|
@@ -2,6 +2,7 @@ type __VLS_Props = {
|
|
|
2
2
|
fieldKey: string;
|
|
3
3
|
awareness?: boolean;
|
|
4
4
|
live?: boolean;
|
|
5
|
+
followOnly?: boolean;
|
|
5
6
|
total?: boolean;
|
|
6
7
|
};
|
|
7
8
|
declare var __VLS_10: string, __VLS_11: any, __VLS_22: string, __VLS_23: any;
|
|
@@ -13,6 +14,7 @@ type __VLS_Slots = {} & {
|
|
|
13
14
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
14
15
|
awareness: boolean;
|
|
15
16
|
live: boolean;
|
|
17
|
+
followOnly: boolean;
|
|
16
18
|
total: boolean;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
20
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -8,7 +8,7 @@ const props = defineProps({
|
|
|
8
8
|
showFlag: { type: Boolean, required: false, default: true },
|
|
9
9
|
tinted: { type: Boolean, required: false, default: true }
|
|
10
10
|
});
|
|
11
|
-
const { hoverers, focusers, pressers,
|
|
11
|
+
const { hoverers, focusers, pressers, localPress, onMouseenter, onMouseleave, onMousedown, onMouseup } = useAAField(() => props.fieldKey);
|
|
12
12
|
const wrapperRef = ref(null);
|
|
13
13
|
const rowEl = ref(null);
|
|
14
14
|
const ROW_SELECTOR = [
|
|
@@ -23,6 +23,20 @@ const ROW_SELECTOR = [
|
|
|
23
23
|
".aa-row-target"
|
|
24
24
|
].join(", ");
|
|
25
25
|
let savedStyle = { background: "", boxShadow: "", position: "" };
|
|
26
|
+
let kbHighlighted = false;
|
|
27
|
+
let kbObserver = null;
|
|
28
|
+
function isKeyboardHighlighted(row) {
|
|
29
|
+
return row.hasAttribute("data-highlighted") || row.getAttribute("data-state") === "checked" || row.getAttribute("aria-selected") === "true";
|
|
30
|
+
}
|
|
31
|
+
function syncKeyboardHighlight() {
|
|
32
|
+
const row = rowEl.value;
|
|
33
|
+
if (!row) return;
|
|
34
|
+
const next = isKeyboardHighlighted(row);
|
|
35
|
+
if (next === kbHighlighted) return;
|
|
36
|
+
kbHighlighted = next;
|
|
37
|
+
if (next) onMouseenter();
|
|
38
|
+
else onMouseleave();
|
|
39
|
+
}
|
|
26
40
|
function attachToRow() {
|
|
27
41
|
const wrapper = wrapperRef.value;
|
|
28
42
|
if (!wrapper) return;
|
|
@@ -39,6 +53,13 @@ function attachToRow() {
|
|
|
39
53
|
row.addEventListener("mouseleave", onMouseleave);
|
|
40
54
|
row.addEventListener("mousedown", onMousedown);
|
|
41
55
|
row.addEventListener("mouseup", onMouseup);
|
|
56
|
+
kbObserver?.disconnect();
|
|
57
|
+
kbObserver = new MutationObserver(syncKeyboardHighlight);
|
|
58
|
+
kbObserver.observe(row, {
|
|
59
|
+
attributes: true,
|
|
60
|
+
attributeFilter: ["data-highlighted", "data-state", "aria-selected"]
|
|
61
|
+
});
|
|
62
|
+
syncKeyboardHighlight();
|
|
42
63
|
}
|
|
43
64
|
function detachFromRow() {
|
|
44
65
|
const row = rowEl.value;
|
|
@@ -49,6 +70,10 @@ function detachFromRow() {
|
|
|
49
70
|
row.removeEventListener("mouseup", onMouseup);
|
|
50
71
|
row.style.backgroundColor = savedStyle.background;
|
|
51
72
|
row.style.boxShadow = savedStyle.boxShadow;
|
|
73
|
+
if (kbHighlighted) onMouseleave();
|
|
74
|
+
kbHighlighted = false;
|
|
75
|
+
kbObserver?.disconnect();
|
|
76
|
+
kbObserver = null;
|
|
52
77
|
rowEl.value = null;
|
|
53
78
|
}
|
|
54
79
|
onMounted(attachToRow);
|
|
@@ -90,7 +115,7 @@ const flagPeer = computed(
|
|
|
90
115
|
() => pressers.value[0] ?? focusers.value[0] ?? hoverers.value[0]
|
|
91
116
|
);
|
|
92
117
|
const pulseKey = ref(0);
|
|
93
|
-
watch(
|
|
118
|
+
watch(localPress, (val, prev) => {
|
|
94
119
|
if (val && !prev) pulseKey.value++;
|
|
95
120
|
});
|
|
96
121
|
const pulseColor = computed(() => pressers.value[0]?.user?.color ?? "currentColor");
|
|
@@ -120,5 +145,5 @@ const pulseColor = computed(() => pressers.value[0]?.user?.color ?? "currentColo
|
|
|
120
145
|
</template>
|
|
121
146
|
|
|
122
147
|
<style scoped>
|
|
123
|
-
.aa-item{border-radius:inherit;display:contents;position:relative}.aa-item--inline{align-items:center;display:inline-flex}.aa-item__pulse{animation:aa-item-pulse
|
|
148
|
+
.aa-item{border-radius:inherit;display:contents;position:relative}.aa-item--inline{align-items:center;display:inline-flex}.aa-item__pulse{animation:aa-item-pulse var(--aa-pulse-duration) var(--aa-pulse-easing) forwards;border-radius:inherit;inset:0;pointer-events:none;position:absolute}@keyframes aa-item-pulse{0%{box-shadow:0 0 0 0 var(--aa-pulse-color);opacity:var(--aa-pulse-opacity-start-item)}to{box-shadow:0 0 0 var(--aa-pulse-radius-item) var(--aa-pulse-color);opacity:0}}.aa-item__flag{border-radius:.25rem .25rem .25rem 0;box-shadow:0 1px 2px rgba(0,0,0,.18);color:#fff;font-size:.55rem;font-weight:500;line-height:1;padding:.18rem .35rem;pointer-events:none;position:absolute;right:.25rem;top:-.55rem;white-space:nowrap;z-index:5}.aa-flag-enter-active,.aa-flag-leave-active{transition:opacity var(--aa-flag-fade-duration) var(--aa-flag-fade-easing),transform var(--aa-flag-fade-duration) var(--aa-flag-fade-easing)}.aa-flag-enter-from,.aa-flag-leave-to{opacity:0;transform:translateY(2px)}
|
|
124
149
|
</style>
|
|
@@ -12,8 +12,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
12
12
|
awareness: boolean;
|
|
13
13
|
tag: "video" | "audio";
|
|
14
14
|
live: boolean;
|
|
15
|
-
total: boolean;
|
|
16
15
|
controls: boolean;
|
|
16
|
+
total: boolean;
|
|
17
17
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
18
|
declare const _default: typeof __VLS_export;
|
|
19
19
|
export default _default;
|
|
@@ -12,8 +12,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
12
12
|
awareness: boolean;
|
|
13
13
|
tag: "video" | "audio";
|
|
14
14
|
live: boolean;
|
|
15
|
-
total: boolean;
|
|
16
15
|
controls: boolean;
|
|
16
|
+
total: boolean;
|
|
17
17
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
18
|
declare const _default: typeof __VLS_export;
|
|
19
19
|
export default _default;
|
|
@@ -2,6 +2,7 @@ type __VLS_Props = {
|
|
|
2
2
|
fieldKey: string;
|
|
3
3
|
awareness?: boolean;
|
|
4
4
|
live?: boolean;
|
|
5
|
+
followOnly?: boolean;
|
|
5
6
|
total?: boolean;
|
|
6
7
|
};
|
|
7
8
|
declare var __VLS_8: {}, __VLS_11: {}, __VLS_14: {}, __VLS_17: {}, __VLS_20: {}, __VLS_31: string, __VLS_32: any;
|
|
@@ -21,6 +22,7 @@ type __VLS_Slots = {} & {
|
|
|
21
22
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
22
23
|
awareness: boolean;
|
|
23
24
|
live: boolean;
|
|
25
|
+
followOnly: boolean;
|
|
24
26
|
total: boolean;
|
|
25
27
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
26
28
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref, useAttrs, watch } from "vue";
|
|
3
3
|
import { useAAUIState, useAAUIStateAuthor } from "../../composables/useAAUIState";
|
|
4
|
+
import { useAAFollowPeer } from "../../composables/useAAFollowPeer";
|
|
4
5
|
import { useAwareness } from "../../composables/useAwareness";
|
|
5
6
|
defineOptions({ inheritAttrs: false });
|
|
6
7
|
const props = defineProps({
|
|
7
8
|
fieldKey: { type: String, required: true },
|
|
8
9
|
awareness: { type: Boolean, required: false, default: true },
|
|
9
10
|
live: { type: Boolean, required: false, default: false },
|
|
11
|
+
followOnly: { type: Boolean, required: false, default: false },
|
|
10
12
|
total: { type: Boolean, required: false, default: false }
|
|
11
13
|
});
|
|
12
|
-
const
|
|
14
|
+
const { isFollowing } = useAAFollowPeer();
|
|
15
|
+
const enableLive = computed(() => props.live || props.total || props.followOnly && isFollowing.value);
|
|
13
16
|
const attrs = useAttrs();
|
|
14
17
|
const liveOpen = useAAUIState(() => `${props.fieldKey}:open`, { defaultValue: false });
|
|
15
18
|
const author = useAAUIStateAuthor(() => `${props.fieldKey}:open`);
|
|
@@ -25,6 +28,11 @@ watch(local, (val) => {
|
|
|
25
28
|
if (!enableLive.value) return;
|
|
26
29
|
if (!!liveOpen.value !== val) liveOpen.value = val;
|
|
27
30
|
});
|
|
31
|
+
watch(enableLive, (now, prev) => {
|
|
32
|
+
if (!now || prev) return;
|
|
33
|
+
const incoming = !!liveOpen.value;
|
|
34
|
+
if (local.value !== incoming) local.value = incoming;
|
|
35
|
+
});
|
|
28
36
|
const openedByUser = computed(() => {
|
|
29
37
|
if (!enableLive.value || !local.value || author.value == null) return null;
|
|
30
38
|
const state = states.value.get(author.value);
|