1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useMainStore } from '../store/main'
import { SubsonicApi, useSubsonicApi } from '../subsonicApi'
import { Logo } from '../components/Logo.vine'
export const LoginView = ({ returnTo = '/discover' }: { returnTo?: string }) => {
const
router = useRouter(),
mainStore = useMainStore(),
subsonicApi = useSubsonicApi(),
staticServerUrl = import.meta.env.SERVER_URL ?? null,
serverUrl = ref<string>(mainStore.serverUrl ?? ''),
username = ref<string>(mainStore.serverCredentials?.username ?? ''),
password = ref<string>(''),
error = ref<Error | null>(null),
displayForm = ref<boolean>(false),
hasError = computed(() => error.value !== null),
loginHandler = async() => {
try {
mainStore.isLoading = true
error.value = null
const auth = SubsonicApi.createAuth(username.value, password.value)
subsonicApi.setServerUrl(staticServerUrl ?? serverUrl.value)
subsonicApi.setAuth(auth)
subsonicApi.initialize()
const serverInfo = await subsonicApi.fetchServerInfo()
mainStore.setServerUrl(staticServerUrl ?? serverUrl.value)
mainStore.setServerCredentials(auth)
mainStore.setServerInfo(serverInfo)
router.replace(returnTo)
} catch (err: any) {
console.error(err)
mainStore.isLoading = false
error.value = err
}
}
onMounted(
() => {
if (!mainStore.isAuthenticated()) {
displayForm.value = true
} else {
router.replace(returnTo)
}
}
)
return vine`
<div v-if="!displayForm" class="row justify-content-center">
<span :aria-busy="true" />
</div>
<fieldset v-else class="login" :disabled="mainStore.isLoading">
<form @submit.prevent="loginHandler">
<div class="logo">
<Logo />
</div>
<label v-if="!staticServerUrl">
Server
<input
type="text"
name="serverUrl"
v-model.trim="serverUrl"
:class="{'is-invalid': hasError}"
>
</label>
<label>
Username
<input
type="text"
name="username"
v-model="username"
:class="{'is-invalid': hasError}"
>
</label>
<label>
Password
<input
type="password"
name="password"
v-model="password"
:class="{'is-invalid': hasError}"
>
</label>
<div v-if="error != null" class="alert">
<span class="bold">Error:</span>
{{ error.message }}
</div>
<button :disabled="mainStore.isLoading">
<span :aria-busy="mainStore.isLoading"/> Log in
</button>
<div class="row justify-content-center">
<a href="/app/">NavidromeUI</a>
</div>
</form>
</fieldset>
`;
}