zaphyra's git: domsonic

subsonic web-client

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>
  `;
}