build: add name to components which failed lint check
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<div v-lazy:background-image="image" class="image" @click="onClick">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
image: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
onClick: {
|
||||
type: Function,
|
||||
default: f => f
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.image {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
opacity: 0;
|
||||
transition: opacity 300ms ease;
|
||||
will-change: opacity;
|
||||
|
||||
&[lazy='loaded'] {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,96 +0,0 @@
|
||||
<template>
|
||||
<div :class="{ 'is-shown': show, 'is-contained': contained }" class="cover">
|
||||
<ul class="loader">
|
||||
<li />
|
||||
<li />
|
||||
<li />
|
||||
<li />
|
||||
<li />
|
||||
<li />
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
contained: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cover {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 100000;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: all 350ms ease;
|
||||
|
||||
&.is-contained {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.loader li {
|
||||
background: #535353;
|
||||
margin-left: 1px;
|
||||
width: 14px;
|
||||
height: 22px;
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0px 0px 1px #b4b4b4;
|
||||
transform: skew(-25deg, 0deg) scale(0.1);
|
||||
animation: loader 0.5s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes loader {
|
||||
to {
|
||||
transform: skew(-25deg, 0deg) scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.loader li:nth-child(2) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
.loader li:nth-child(3) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
.loader li:nth-child(4) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
.loader li:nth-child(5) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
.loader li:nth-child(6) {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
|
||||
&.is-shown {
|
||||
pointer-events: all;
|
||||
opacity: 1;
|
||||
|
||||
.spinner {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,53 +0,0 @@
|
||||
<template>
|
||||
<div class="message-container">
|
||||
<div class="message">
|
||||
<div class="icon">
|
||||
<slot name="icon" />
|
||||
</div>
|
||||
<h3>{{ message }}</h3>
|
||||
<p>{{ description }}</p>
|
||||
<slot name="extras" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
message: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message-container {
|
||||
margin: 10vh auto;
|
||||
max-width: 420px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
text-align: center;
|
||||
box-shadow: 0px 1px 2px #b4b4b494;
|
||||
|
||||
.icon > * {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
> * {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -97,6 +97,7 @@
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export default {
|
||||
name: 'EventDetail',
|
||||
props: {
|
||||
event: {
|
||||
type: Object,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import Event from '../Event'
|
||||
|
||||
export default {
|
||||
name: 'EventList',
|
||||
components: {
|
||||
Event
|
||||
},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div :key="isAuthenticated">
|
||||
<span v-text="isAuthenticated" />
|
||||
<v-container fluid grid-list-md class="app-fade-in" :key="range">
|
||||
<v-layout row wrap v-if="!isAuthenticated">
|
||||
<v-flex xs12>
|
||||
@@ -97,6 +96,7 @@ import {
|
||||
import { useTranslation } from '../../../plugins/i18n'
|
||||
|
||||
export default {
|
||||
name: 'EventsPage',
|
||||
components: {
|
||||
List
|
||||
},
|
||||
@@ -108,7 +108,7 @@ export default {
|
||||
const { route, router } = useRouter()
|
||||
const range = computed({
|
||||
get: () => route.value.query.range || 'ONE_WEEK',
|
||||
set: value => router.push(`/?range=${value}`)
|
||||
set: (value) => router.push(`/?range=${value}`)
|
||||
})
|
||||
const enabled = ref(false)
|
||||
const { result: data, refetch } = useQuery(
|
||||
@@ -116,11 +116,11 @@ export default {
|
||||
{ includeOrigins: false },
|
||||
() => ({ enabled: enabled.value })
|
||||
)
|
||||
const events = useResult(data, [], result => result.events)
|
||||
const origins = useResult(data, [], result => result.origins)
|
||||
const events = useResult(data, [], (result) => result.events)
|
||||
const origins = useResult(data, [], (result) => result.origins)
|
||||
watch(
|
||||
range,
|
||||
r => {
|
||||
(r) => {
|
||||
enabled.value = true
|
||||
console.log('isAuthenticated', isAuthenticated.value)
|
||||
refetch({
|
||||
@@ -164,7 +164,7 @@ export default {
|
||||
)
|
||||
const { mutate: doToggleIgnoreState } = useMutation(toggleIgnoreState)
|
||||
|
||||
const toggleIgnoreSuccess = name => {
|
||||
const toggleIgnoreSuccess = (name) => {
|
||||
return () => {
|
||||
fetchEvents()
|
||||
snackbar.value.color = 'success'
|
||||
@@ -173,7 +173,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
const toggleIgnoreFailed = name => {
|
||||
const toggleIgnoreFailed = (name) => {
|
||||
return () => {
|
||||
snackbar.value.color = 'error'
|
||||
snackbar.value.text = `${name} kunde inte döljas`
|
||||
@@ -221,7 +221,7 @@ export default {
|
||||
)
|
||||
const fetchAddressFn = () => {
|
||||
if (window.navigator) {
|
||||
window.navigator.geolocation.getCurrentPosition(pos => {
|
||||
window.navigator.geolocation.getCurrentPosition((pos) => {
|
||||
addressEnabled.value = true
|
||||
doFetchAddress({
|
||||
latlng: `${pos.coords.latitude},${pos.coords.longitude}`
|
||||
@@ -231,7 +231,7 @@ export default {
|
||||
})
|
||||
}
|
||||
}
|
||||
const saveOriginFn = o =>
|
||||
const saveOriginFn = (o) =>
|
||||
doSaveOrigin({ origin: o }).then(() => {
|
||||
origin.value = ''
|
||||
fetchEvents()
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FiltersList',
|
||||
props: {
|
||||
model: {
|
||||
type: Array,
|
||||
|
||||
@@ -74,6 +74,7 @@ import { useAuth } from '../../../plugins/auth'
|
||||
import { useTranslation } from '../../../plugins/i18n'
|
||||
|
||||
export default {
|
||||
name: 'FiltersPage',
|
||||
components: {
|
||||
List
|
||||
},
|
||||
@@ -83,11 +84,15 @@ export default {
|
||||
setTitle(t('app.links.filters'))
|
||||
const { isAuthenticated } = useAuth()
|
||||
const { result: data, loading, refetch } = useQuery(fetchFilters)
|
||||
const bands = useResult(data, [], result => result.bands)
|
||||
const cities = useResult(data, [], result => result.cities)
|
||||
const danceHalls = useResult(data, [], result => result.danceHalls)
|
||||
const municipalities = useResult(data, [], result => result.municipalities)
|
||||
const states = useResult(data, [], result => result.states)
|
||||
const bands = useResult(data, [], (result) => result.bands)
|
||||
const cities = useResult(data, [], (result) => result.cities)
|
||||
const danceHalls = useResult(data, [], (result) => result.danceHalls)
|
||||
const municipalities = useResult(
|
||||
data,
|
||||
[],
|
||||
(result) => result.municipalities
|
||||
)
|
||||
const states = useResult(data, [], (result) => result.states)
|
||||
const snackbar = ref({ active: false, color: 'success', text: '' })
|
||||
const { mutate: doToggleIgnoreBand } = useMutation(toggleIgnoreBand)
|
||||
const { mutate: doToggleIgnoreDanceHall } = useMutation(
|
||||
@@ -99,7 +104,7 @@ export default {
|
||||
)
|
||||
const { mutate: doToggleIgnoreState } = useMutation(toggleIgnoreState)
|
||||
|
||||
const toggleIgnoreSuccess = name => {
|
||||
const toggleIgnoreSuccess = (name) => {
|
||||
return () => {
|
||||
refetch()
|
||||
snackbar.value.color = 'success'
|
||||
@@ -108,7 +113,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
const toggleIgnoreFailed = name => {
|
||||
const toggleIgnoreFailed = (name) => {
|
||||
return () => {
|
||||
snackbar.value.color = 'error'
|
||||
snackbar.value.text = t('filters.failure', { name })
|
||||
|
||||
@@ -70,6 +70,7 @@ import { useAuth } from '../../../plugins/auth'
|
||||
import { useTranslation } from '../../../plugins/i18n'
|
||||
|
||||
export default {
|
||||
name: 'OriginsPage',
|
||||
setup() {
|
||||
const { setTitle } = useMutations(['setTitle'])
|
||||
const { t } = useTranslation()
|
||||
@@ -87,22 +88,22 @@ export default {
|
||||
const origin = ref('')
|
||||
const fetchAddressFn = () => {
|
||||
if (window.navigator) {
|
||||
window.navigator.geolocation.getCurrentPosition(pos => {
|
||||
window.navigator.geolocation.getCurrentPosition((pos) => {
|
||||
enabled.value = true
|
||||
doFetchAddress({
|
||||
latlng: `${pos.coords.latitude},${pos.coords.longitude}`
|
||||
}).then(res => {
|
||||
}).then((res) => {
|
||||
origin.value = res.address
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
const saveOriginFn = o =>
|
||||
const saveOriginFn = (o) =>
|
||||
doSaveOrigin({ origin: o }).then(() => {
|
||||
refetch()
|
||||
origin.value = ''
|
||||
})
|
||||
const removeOriginFn = o =>
|
||||
const removeOriginFn = (o) =>
|
||||
doRemoveOrigin({ origin: o }).then(() => refetch())
|
||||
return {
|
||||
isAuthenticated,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { getDarkMode } from '../../utils/localStorage'
|
||||
|
||||
export default {
|
||||
name: 'ThemedLayout',
|
||||
setup(props, context) {
|
||||
context.root.$vuetify.theme.dark = getDarkMode()
|
||||
}
|
||||
|
||||
+6
-10
@@ -103,26 +103,22 @@ import Themed from './components/themed'
|
||||
import { useAuth } from '../plugins/auth'
|
||||
|
||||
export default {
|
||||
name: 'DefaultLayout',
|
||||
components: {
|
||||
Themed
|
||||
},
|
||||
setup(props, context) {
|
||||
const { router } = useRouter()
|
||||
const { title } = useState(['title'])
|
||||
const onRedirectCallback = appState => {
|
||||
const onRedirectCallback = (appState) => {
|
||||
router.push(
|
||||
appState && appState.targetUrl
|
||||
? appState.targetUrl
|
||||
: window.location.pathname
|
||||
)
|
||||
}
|
||||
const {
|
||||
loading,
|
||||
isAuthenticated,
|
||||
user,
|
||||
loginWithRedirect,
|
||||
logout
|
||||
} = useAuth(onRedirectCallback)
|
||||
const { loading, isAuthenticated, user, loginWithRedirect, logout } =
|
||||
useAuth(onRedirectCallback)
|
||||
const doLogin = () => {
|
||||
loginWithRedirect.value()
|
||||
}
|
||||
@@ -133,14 +129,14 @@ export default {
|
||||
}
|
||||
const darkMode = computed({
|
||||
get: () => context.root.$vuetify.theme.dark,
|
||||
set: val => {
|
||||
set: (val) => {
|
||||
context.root.$vuetify.theme.dark = val
|
||||
setDarkMode(context.root.$vuetify.theme.dark)
|
||||
}
|
||||
})
|
||||
const locale = computed({
|
||||
get: () => context.root.$i18n.locale,
|
||||
set: newLocale => {
|
||||
set: (newLocale) => {
|
||||
if (newLocale === 'en') {
|
||||
dayjs.locale(newLocale)
|
||||
} else if (newLocale === 'sv') {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { useAuth } from '../plugins/auth'
|
||||
|
||||
export default async ({ app: { router } }) => {
|
||||
const onRedirectCallback = appState => {
|
||||
const onRedirectCallback = (appState) => {
|
||||
router.push(
|
||||
appState && appState.targetUrl
|
||||
? appState.targetUrl
|
||||
|
||||
+2
-4
@@ -47,8 +47,7 @@ export default {
|
||||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
|
||||
{
|
||||
rel: 'stylesheet',
|
||||
href:
|
||||
'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons'
|
||||
href: 'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons'
|
||||
},
|
||||
{
|
||||
rel: 'stylesheet',
|
||||
@@ -56,8 +55,7 @@ export default {
|
||||
},
|
||||
{
|
||||
rel: 'stylesheet',
|
||||
href:
|
||||
'https://cdn.materialdesignicons.com/3.3.92/css/materialdesignicons.min.css'
|
||||
href: 'https://cdn.materialdesignicons.com/3.3.92/css/materialdesignicons.min.css'
|
||||
}
|
||||
],
|
||||
meta: [
|
||||
|
||||
@@ -7,6 +7,7 @@ import Filters from '../components/pages/filters'
|
||||
import { useTranslation } from '../plugins/i18n'
|
||||
|
||||
export default {
|
||||
name: 'FiltersPage',
|
||||
components: {
|
||||
Filters
|
||||
},
|
||||
|
||||
@@ -7,6 +7,7 @@ import Events from '../components/pages/events'
|
||||
import { useTranslation } from '../plugins/i18n'
|
||||
|
||||
export default {
|
||||
name: 'IndexPage',
|
||||
components: {
|
||||
Events
|
||||
},
|
||||
|
||||
@@ -7,6 +7,7 @@ import Origins from '../components/pages/origins'
|
||||
import { useTranslation } from '../plugins/i18n'
|
||||
|
||||
export default {
|
||||
name: 'OriginsPage',
|
||||
components: {
|
||||
Origins
|
||||
},
|
||||
|
||||
+3
-3
@@ -22,13 +22,13 @@ const httpLink = createHttpLink({
|
||||
uri: apiUrl
|
||||
})
|
||||
|
||||
const getToken = async options => {
|
||||
const getToken = async (options) => {
|
||||
const { getTokenSilently } = useAuth()
|
||||
return getTokenSilently.value(options)
|
||||
}
|
||||
|
||||
const authLink = setContext(async (_, { headers }) => {
|
||||
return getToken().then(token => ({
|
||||
return getToken().then((token) => ({
|
||||
headers: {
|
||||
...headers,
|
||||
authorization: token ? `Bearer ${token}` : ''
|
||||
@@ -52,7 +52,7 @@ const instance = new ApolloClient({
|
||||
}
|
||||
})
|
||||
|
||||
export default function ({app}) {
|
||||
export default function ({ app }) {
|
||||
app.setup = () => {
|
||||
provide(DefaultApolloClient, instance)
|
||||
}
|
||||
|
||||
+22
-22
@@ -31,11 +31,11 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
popupOpen: false,
|
||||
error: null,
|
||||
/** Authenticates the user using a popup window */
|
||||
loginWithPopup: async o => {
|
||||
loginWithPopup: async (o) => {
|
||||
this.popupOpen = true
|
||||
|
||||
try {
|
||||
await instance.auth0Client.then(client => client.loginWithPopup(o))
|
||||
await instance.auth0Client.then((client) => client.loginWithPopup(o))
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line
|
||||
console.error(e)
|
||||
@@ -43,7 +43,7 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
instance.popupOpen = false
|
||||
}
|
||||
|
||||
instance.user = await instance.auth0Client.then(client =>
|
||||
instance.user = await instance.auth0Client.then((client) =>
|
||||
client.getUser()
|
||||
)
|
||||
instance.isAuthenticated = true
|
||||
@@ -52,10 +52,10 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
handleRedirectCallback: async () => {
|
||||
instance.loading = true
|
||||
try {
|
||||
await instance.auth0Client.then(client =>
|
||||
await instance.auth0Client.then((client) =>
|
||||
client.handleRedirectCallback()
|
||||
)
|
||||
instance.user = await instance.auth0Client.then(client =>
|
||||
instance.user = await instance.auth0Client.then((client) =>
|
||||
client.getUser()
|
||||
)
|
||||
instance.isAuthenticated = true
|
||||
@@ -66,36 +66,36 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
}
|
||||
},
|
||||
/** Authenticates the user using the redirect method */
|
||||
loginWithRedirect: o => {
|
||||
return instance.auth0Client.then(client => client.loginWithRedirect(o))
|
||||
loginWithRedirect: (o) => {
|
||||
return instance.auth0Client.then((client) => client.loginWithRedirect(o))
|
||||
},
|
||||
/** Returns all the claims present in the ID token */
|
||||
getIdTokenClaims: o => {
|
||||
return instance.auth0Client.then(client => client.getIdTokenClaims(o))
|
||||
getIdTokenClaims: (o) => {
|
||||
return instance.auth0Client.then((client) => client.getIdTokenClaims(o))
|
||||
},
|
||||
/** Returns the access token. If the token is invalid or missing, a new one is retrieved */
|
||||
getTokenSilently: o => {
|
||||
return instance.auth0Client.then(client => {
|
||||
getTokenSilently: (o) => {
|
||||
return instance.auth0Client.then((client) => {
|
||||
return client.getTokenSilently(o)
|
||||
})
|
||||
},
|
||||
/** Gets the access token using a popup window */
|
||||
getTokenWithPopup: o => {
|
||||
return instance.auth0Client.then(client => client.getTokenWithPopup(o))
|
||||
getTokenWithPopup: (o) => {
|
||||
return instance.auth0Client.then((client) => client.getTokenWithPopup(o))
|
||||
},
|
||||
/** Logs the user out and removes their session on the authorization server */
|
||||
logout: o => {
|
||||
return instance.auth0Client.then(client => client.logout(o))
|
||||
logout: (o) => {
|
||||
return instance.auth0Client.then((client) => client.logout(o))
|
||||
}
|
||||
})
|
||||
|
||||
const fetchUser = () => {
|
||||
instance.auth0Client
|
||||
.then(client => client.isAuthenticated())
|
||||
.then(a => {
|
||||
.then((client) => client.isAuthenticated())
|
||||
.then((a) => {
|
||||
instance.isAuthenticated = a
|
||||
instance.auth0Client.then(client =>
|
||||
client.getUser().then(u => {
|
||||
instance.auth0Client.then((client) =>
|
||||
client.getUser().then((u) => {
|
||||
instance.user = u
|
||||
instance.loading = false
|
||||
})
|
||||
@@ -104,7 +104,7 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
}
|
||||
// Create a new instance of the SDK client using members of the given options object
|
||||
instance.auth0Client = createAuth0Client(options)
|
||||
instance.auth0Client.then(client => {
|
||||
instance.auth0Client.then((client) => {
|
||||
instance.loading = true
|
||||
try {
|
||||
// If the user is returning to the app after authentication..
|
||||
@@ -115,7 +115,7 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
// handle the redirect and retrieve tokens
|
||||
client
|
||||
.handleRedirectCallback()
|
||||
.then(appState => {
|
||||
.then((appState) => {
|
||||
// Notify subscribers that the redirect callback has happened, passing the appState
|
||||
// (useful for retrieving any pre-authentication state)
|
||||
onRedirectCallback(appState)
|
||||
@@ -123,7 +123,7 @@ export const useAuth = (onRedirectCallback = DEFAULT_REDIRECT_CALLBACK) => {
|
||||
fetchUser()
|
||||
})
|
||||
// eslint-disable-next-line no-console
|
||||
.catch(e => console.error('error handling redirect callback', e))
|
||||
.catch((e) => console.error('error handling redirect callback', e))
|
||||
} else {
|
||||
fetchUser()
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ const DARK_MODE_KEY = 'dancefinder-dark-mode'
|
||||
const LOCALE_KEY = 'dancefinder-locale'
|
||||
|
||||
const getDarkMode = () => localStorage.getItem(DARK_MODE_KEY)
|
||||
const setDarkMode = mode => localStorage.setItem(DARK_MODE_KEY, mode)
|
||||
const setDarkMode = (mode) => localStorage.setItem(DARK_MODE_KEY, mode)
|
||||
const getLocale = () => localStorage.getItem(LOCALE_KEY)
|
||||
const setLocale = locale => localStorage.setItem(LOCALE_KEY, locale)
|
||||
const setLocale = (locale) => localStorage.setItem(LOCALE_KEY, locale)
|
||||
|
||||
export { getDarkMode, setDarkMode, getLocale, setLocale }
|
||||
|
||||
Reference in New Issue
Block a user