+16
-16
i18n/locales/en.ts
+16
-16
i18n/locales/en.ts
···
1
export default {
2
+
atproto: {
3
+
desktop: {
4
+
instanceBy: 'instance by',
5
+
},
6
+
login: {
7
+
resolver: {
8
+
using: 'using:',
9
+
prompt: 'Use a different service resolver:',
10
+
},
11
+
actions: {
12
+
login: 'Login with ATProto',
13
+
logout: 'Logout',
14
+
},
15
+
},
16
+
},
17
+
}
+44
-45
module.ts
+44
-45
module.ts
···
1
-
import {defineNuxtModule, createResolver, addComponentsDir, addPlugin} from '@nuxt/kit'
2
-
import {registerTailwindPath} from "@owdproject/core";
3
4
export default defineNuxtModule({
5
-
meta: {
6
-
name: 'owd-app-atproto',
7
-
},
8
-
async setup(options, nuxt) {
9
-
const {resolve} = createResolver(import.meta.url);
10
11
-
{
12
13
-
// add components
14
15
-
addComponentsDir({
16
-
path: resolve("./runtime/components"),
17
-
})
18
19
-
}
20
21
-
{
22
23
-
// add plugins
24
25
-
addPlugin(resolve('./runtime/plugin'))
26
-
27
-
}
28
-
29
-
{
30
-
31
-
// configure tailwind
32
-
33
-
registerTailwindPath(nuxt, resolve('./runtime/components/**/*.{vue,mjs,ts}'))
34
-
35
-
}
36
-
37
-
{
38
-
39
-
// import i18n
40
-
41
-
nuxt.hook('i18n:registerModule', register => {
42
-
register({
43
-
// langDir path needs to be resolved
44
-
langDir: resolve('./i18n'),
45
-
locales: [
46
-
{
47
-
code: 'en',
48
-
file: 'locales/en.ts',
49
-
},
50
-
]
51
-
})
52
-
})
53
54
-
}
55
-
56
}
57
})
···
1
+
import {
2
+
defineNuxtModule,
3
+
createResolver,
4
+
addComponentsDir,
5
+
addPlugin,
6
+
} from '@nuxt/kit'
7
+
import { registerTailwindPath } from '@owdproject/core'
8
9
export default defineNuxtModule({
10
+
meta: {
11
+
name: 'owd-app-atproto',
12
+
},
13
+
async setup(options, nuxt) {
14
+
const { resolve } = createResolver(import.meta.url)
15
16
+
{
17
+
// add components
18
19
+
addComponentsDir({
20
+
path: resolve('./runtime/components'),
21
+
})
22
+
}
23
24
+
{
25
+
// add plugins
26
27
+
addPlugin(resolve('./runtime/plugin'))
28
+
}
29
30
+
{
31
+
// configure tailwind
32
33
+
registerTailwindPath(
34
+
nuxt,
35
+
resolve('./runtime/components/**/*.{vue,mjs,ts}'),
36
+
)
37
+
}
38
39
+
{
40
+
// import i18n
41
42
+
nuxt.hook('i18n:registerModule', (register) => {
43
+
register({
44
+
// langDir path needs to be resolved
45
+
langDir: resolve('./i18n'),
46
+
locales: [
47
+
{
48
+
code: 'en',
49
+
file: 'locales/en.ts',
50
+
},
51
+
],
52
+
})
53
+
})
54
}
55
+
},
56
})
+30
-30
runtime/app.config.ts
+30
-30
runtime/app.config.ts
···
1
export default {
2
-
id: "org.owdproject.atproto",
3
-
title: "Account",
4
-
category: "internet",
5
-
provides: {
6
-
name: "auth",
7
-
entry: "atproto",
8
-
},
9
-
icon: "weui:at-filled",
10
-
windows: {
11
-
account: {
12
-
component: () => import('./components/Window/WindowAtprotoAccount.vue'),
13
-
resizable: false,
14
-
size: {
15
-
width: 400,
16
-
height: 500
17
-
},
18
-
position: {
19
-
x: 400,
20
-
y: 240,
21
-
z: 0
22
-
},
23
-
}
24
},
25
-
entries: {
26
-
atproto: {
27
-
command: "atproto"
28
-
},
29
},
30
-
commands: {
31
-
atproto: (app: IApplicationController, args) => {
32
-
app.openWindow("account")
33
-
}
34
},
35
}
···
1
export default {
2
+
id: 'org.owdproject.atproto',
3
+
title: 'Account',
4
+
category: 'internet',
5
+
provides: {
6
+
name: 'auth',
7
+
entry: 'atproto',
8
+
},
9
+
icon: 'weui:at-filled',
10
+
windows: {
11
+
account: {
12
+
component: () => import('./components/Window/WindowAtprotoAccount.vue'),
13
+
resizable: false,
14
+
size: {
15
+
width: 400,
16
+
height: 500,
17
+
},
18
+
position: {
19
+
x: 400,
20
+
y: 240,
21
+
z: 0,
22
+
},
23
},
24
+
},
25
+
entries: {
26
+
atproto: {
27
+
command: 'atproto',
28
},
29
+
},
30
+
commands: {
31
+
atproto: (app: IApplicationController, args) => {
32
+
app.openWindow('account')
33
},
34
+
},
35
}
+26
-13
runtime/components/AtprotoDesktop/AtprotoDesktopOwner.vue
+26
-13
runtime/components/AtprotoDesktop/AtprotoDesktopOwner.vue
···
1
<script setup lang="ts">
2
-
import {routeAtprotoOS, routeBlueskyProfile} from "@owdproject/module-atproto/runtime/utils/utilRoute";
3
-
import {useRuntimeConfig} from "nuxt/app"
4
5
const runtimeConfig = useRuntimeConfig()
6
</script>
···
8
<template>
9
<div class="owd-atproto-desktop-owner text-center">
10
<a :href="routeAtprotoOS('/client')" target="_blank" class="text-2xl">
11
-
<span class="font-light" v-text="runtimeConfig.public.atprotoDesktop.name.title"/>
12
-
<span class="font-bold" v-text="runtimeConfig.public.atprotoDesktop.name.affix"/>
13
</a>
14
<div
15
-
class="-mt-1 mb-3 opacity-30"
16
-
v-text="$t('atproto.desktop.instanceBy')"
17
/>
18
<div>
19
<div class="inline-flex">
20
<div class="flex items-center pr-2">
21
<a
22
-
:href="routeBlueskyProfile(runtimeConfig.public.atprotoDesktop.owner.profile?.handle)"
23
-
target="_blank"
24
>
25
<Avatar
26
-
shape="circle"
27
-
:image="runtimeConfig.public.atprotoDesktop.owner.profile?.avatar"
28
/>
29
</a>
30
</div>
31
<div
32
-
class="flex items-center"
33
-
v-text="runtimeConfig.public.atprotoDesktop.owner.profile.displayName"
34
/>
35
</div>
36
</div>
···
50
}
51
}
52
}
53
-
</style>
···
1
<script setup lang="ts">
2
+
import {
3
+
routeAtprotoOS,
4
+
routeBlueskyProfile,
5
+
} from '@owdproject/module-atproto/runtime/utils/utilRoute'
6
+
import { useRuntimeConfig } from 'nuxt/app'
7
8
const runtimeConfig = useRuntimeConfig()
9
</script>
···
11
<template>
12
<div class="owd-atproto-desktop-owner text-center">
13
<a :href="routeAtprotoOS('/client')" target="_blank" class="text-2xl">
14
+
<span
15
+
class="font-light"
16
+
v-text="runtimeConfig.public.atprotoDesktop.name.title"
17
+
/>
18
+
<span
19
+
class="font-bold"
20
+
v-text="runtimeConfig.public.atprotoDesktop.name.affix"
21
+
/>
22
</a>
23
<div
24
+
class="-mt-1 mb-3 opacity-30"
25
+
v-text="$t('atproto.desktop.instanceBy')"
26
/>
27
<div>
28
<div class="inline-flex">
29
<div class="flex items-center pr-2">
30
<a
31
+
:href="
32
+
routeBlueskyProfile(
33
+
runtimeConfig.public.atprotoDesktop.owner.profile?.handle,
34
+
)
35
+
"
36
+
target="_blank"
37
>
38
<Avatar
39
+
shape="circle"
40
+
:image="runtimeConfig.public.atprotoDesktop.owner.profile?.avatar"
41
/>
42
</a>
43
</div>
44
<div
45
+
class="flex items-center"
46
+
v-text="runtimeConfig.public.atprotoDesktop.owner.profile.displayName"
47
/>
48
</div>
49
</div>
···
63
}
64
}
65
}
66
+
</style>
+54
-39
runtime/components/Window/WindowAtprotoAccount.vue
+54
-39
runtime/components/Window/WindowAtprotoAccount.vue
···
1
<script setup lang="ts">
2
-
import {useAtprotoAccountStore} from "@owdproject/module-atproto/runtime/stores/storeAtprotoAccount";
3
-
import AtprotoDesktopOwner from "../AtprotoDesktop/AtprotoDesktopOwner.vue";
4
-
import {onBeforeMount, watch} from "vue"
5
-
import {computed} from "@vue/reactivity"
6
-
import {useI18n} from "vue-i18n"
7
import { useAtproto } from '#imports'
8
9
const props = defineProps<{
···
13
const atproto = useAtproto()
14
15
const atprotoAccountStore = useAtprotoAccountStore()
16
-
const {t} = useI18n()
17
18
onBeforeMount(() => {
19
if (atprotoAccountStore.isAccountLogged) {
···
21
}
22
})
23
24
-
watch(() => atprotoAccountStore.account, (account) => {
25
-
if (atprotoAccountStore.isAccountLogged) {
26
-
props.window.actions.setTitleOverride(account.handle)
27
-
} else {
28
-
props.window.actions.resetTitleOverride()
29
-
}
30
-
})
31
32
function onServiceResolverChange() {
33
if (atprotoAccountStore.isAccountLogged) {
···
36
}
37
38
const customServiceResolver = window.prompt(
39
-
t('atproto.login.resolver.prompt'),
40
-
atprotoAccountStore.handleResolver
41
)
42
43
if (customServiceResolver) {
···
46
}
47
48
const accountLabel = computed(() => {
49
-
if ((atprotoAccountStore.isAccountLogged && !atprotoAccountStore.account.avatar) || !atprotoAccountStore.isAccountLogged) {
50
return '?'
51
}
52
···
54
})
55
56
const accountAvatar = computed(() => {
57
-
if (atprotoAccountStore.isAccountLogged && atprotoAccountStore.account.avatar) {
58
return atprotoAccountStore.account.avatar
59
}
60
···
72
</script>
73
74
<template>
75
-
<Window v-bind="$props" :content="{padded: true, centered: true}">
76
<div class="flex flex-col h-full">
77
-
78
-
<AtprotoDesktopOwner/>
79
80
<div class="owd-atproto-login flex-1 text-center">
81
-
82
<div>
83
<div>
84
<Avatar
85
-
:label="accountLabel"
86
-
:image="accountAvatar"
87
-
size="xlarge" shape="circle"
88
>
89
<Skeleton
90
-
v-if="atprotoAccountStore.state.fetching"
91
-
width="100%" height="100%" borderRadius="50%"
92
/>
93
</Avatar>
94
</div>
95
96
<Button
97
-
v-if="!atprotoAccountStore.isAccountLogged && !atprotoAccountStore.state.fetching"
98
-
size="large"
99
-
v-text="$t('atproto.login.actions.login')"
100
-
@click="onSignIn"
101
/>
102
103
<Button
104
-
v-if="atprotoAccountStore.isAccountLogged"
105
-
size="large"
106
-
v-text="$t('atproto.login.actions.logout')"
107
-
@click="onSignOut"
108
/>
109
</div>
110
-
111
</div>
112
113
<div class="text-center opacity-35">
114
-
{{ $t('atproto.login.resolver.using') }} <span
115
-
:class="{'cursor-pointer': !atprotoAccountStore.isAccountLogged}"
116
v-text="atprotoAccountStore.handleResolverHostname"
117
@click="onServiceResolverChange()"
118
-
/>
119
</div>
120
-
121
</div>
122
</Window>
123
</template>
···
1
<script setup lang="ts">
2
+
import { useAtprotoAccountStore } from '@owdproject/module-atproto/runtime/stores/storeAtprotoAccount'
3
+
import AtprotoDesktopOwner from '../AtprotoDesktop/AtprotoDesktopOwner.vue'
4
+
import { onBeforeMount, watch } from 'vue'
5
+
import { computed } from '@vue/reactivity'
6
+
import { useI18n } from 'vue-i18n'
7
import { useAtproto } from '#imports'
8
9
const props = defineProps<{
···
13
const atproto = useAtproto()
14
15
const atprotoAccountStore = useAtprotoAccountStore()
16
+
const { t } = useI18n()
17
18
onBeforeMount(() => {
19
if (atprotoAccountStore.isAccountLogged) {
···
21
}
22
})
23
24
+
watch(
25
+
() => atprotoAccountStore.account,
26
+
(account) => {
27
+
if (atprotoAccountStore.isAccountLogged) {
28
+
props.window.actions.setTitleOverride(account.handle)
29
+
} else {
30
+
props.window.actions.resetTitleOverride()
31
+
}
32
+
},
33
+
)
34
35
function onServiceResolverChange() {
36
if (atprotoAccountStore.isAccountLogged) {
···
39
}
40
41
const customServiceResolver = window.prompt(
42
+
t('atproto.login.resolver.prompt'),
43
+
atprotoAccountStore.handleResolver,
44
)
45
46
if (customServiceResolver) {
···
49
}
50
51
const accountLabel = computed(() => {
52
+
if (
53
+
(atprotoAccountStore.isAccountLogged &&
54
+
!atprotoAccountStore.account.avatar) ||
55
+
!atprotoAccountStore.isAccountLogged
56
+
) {
57
return '?'
58
}
59
···
61
})
62
63
const accountAvatar = computed(() => {
64
+
if (
65
+
atprotoAccountStore.isAccountLogged &&
66
+
atprotoAccountStore.account.avatar
67
+
) {
68
return atprotoAccountStore.account.avatar
69
}
70
···
82
</script>
83
84
<template>
85
+
<Window v-bind="$props" :content="{ padded: true, centered: true }">
86
<div class="flex flex-col h-full">
87
+
<AtprotoDesktopOwner />
88
89
<div class="owd-atproto-login flex-1 text-center">
90
<div>
91
<div>
92
<Avatar
93
+
:label="accountLabel"
94
+
:image="accountAvatar"
95
+
size="xlarge"
96
+
shape="circle"
97
>
98
<Skeleton
99
+
v-if="atprotoAccountStore.state.fetching"
100
+
width="100%"
101
+
height="100%"
102
+
borderRadius="50%"
103
/>
104
</Avatar>
105
</div>
106
107
<Button
108
+
v-if="
109
+
!atprotoAccountStore.isAccountLogged &&
110
+
!atprotoAccountStore.state.fetching
111
+
"
112
+
size="large"
113
+
v-text="$t('atproto.login.actions.login')"
114
+
@click="onSignIn"
115
/>
116
117
<Button
118
+
v-if="atprotoAccountStore.isAccountLogged"
119
+
size="large"
120
+
v-text="$t('atproto.login.actions.logout')"
121
+
@click="onSignOut"
122
/>
123
</div>
124
</div>
125
126
<div class="text-center opacity-35">
127
+
{{ $t('atproto.login.resolver.using') }}
128
+
<span
129
+
:class="{
130
+
'cursor-pointer': !atprotoAccountStore.isAccountLogged,
131
+
}"
132
v-text="atprotoAccountStore.handleResolverHostname"
133
@click="onServiceResolverChange()"
134
+
/>
135
</div>
136
</div>
137
</Window>
138
</template>
+5
-5
runtime/plugin.ts
+5
-5
runtime/plugin.ts
···
1
-
import {defineNuxtPlugin} from "nuxt/app"
2
-
import {defineDesktopApp} from "@owdproject/core/runtime/utils/utilDesktop"
3
import configAppAtproto from './app.config'
4
5
export default defineNuxtPlugin((nuxtApp) => {
6
-
nuxtApp.hook('app:created', async () => {
7
-
await defineDesktopApp(configAppAtproto)
8
-
})
9
})
···
1
+
import { defineNuxtPlugin } from 'nuxt/app'
2
+
import { defineDesktopApp } from '@owdproject/core/runtime/utils/utilDesktop'
3
import configAppAtproto from './app.config'
4
5
export default defineNuxtPlugin((nuxtApp) => {
6
+
nuxtApp.hook('app:created', async () => {
7
+
await defineDesktopApp(configAppAtproto)
8
+
})
9
})