You've already forked AstralRinth
forked from didirus/AstralRinth
* sample languages refactor * feat: consistency + dedupe impl of i18n * fix: broken imports * fix: intl formatted component * fix: use relative imports * fix: imports * fix: comment out incomplete locales + fix imports * feat: cleanup * fix: ui imports * fix: lint * fix: admonition import * make footer a component, fix language reactivity * make copyright notice untranslatable --------- Co-authored-by: Calum H. <contact@cal.engineer>
151 lines
3.8 KiB
Vue
151 lines
3.8 KiB
Vue
<template>
|
|
<div class="universal-card">
|
|
<h2 class="text-2xl">{{ formatMessage(commonSettingsMessages.sessions) }}</h2>
|
|
<p class="preserve-lines">
|
|
{{ formatMessage(messages.sessionsDescription) }}
|
|
</p>
|
|
<div v-for="session in sessions" :key="session.id" class="universal-card recessed session mt-4">
|
|
<div>
|
|
<div>
|
|
<strong>
|
|
{{ session.os ?? formatMessage(messages.unknownOsLabel) }} ⋅
|
|
{{ session.platform ?? formatMessage(messages.unknownPlatformLabel) }} ⋅
|
|
{{ session.ip }}
|
|
</strong>
|
|
</div>
|
|
<div>
|
|
<template v-if="session.city">{{ session.city }}, {{ session.country }} ⋅ </template>
|
|
<span
|
|
v-tooltip="
|
|
formatMessage(commonMessages.dateAtTimeTooltip, {
|
|
date: new Date(session.last_login),
|
|
time: new Date(session.last_login),
|
|
})
|
|
"
|
|
>
|
|
{{
|
|
formatMessage(messages.lastAccessedAgoLabel, {
|
|
ago: formatRelativeTime(session.last_login),
|
|
})
|
|
}}
|
|
</span>
|
|
⋅
|
|
<span
|
|
v-tooltip="
|
|
formatMessage(commonMessages.dateAtTimeTooltip, {
|
|
date: new Date(session.created),
|
|
time: new Date(session.created),
|
|
})
|
|
"
|
|
>
|
|
{{
|
|
formatMessage(messages.createdAgoLabel, {
|
|
ago: formatRelativeTime(session.created),
|
|
})
|
|
}}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="input-group">
|
|
<i v-if="session.current">{{ formatMessage(messages.currentSessionLabel) }}</i>
|
|
<button v-else class="iconified-button raised-button" @click="revokeSession(session.id)">
|
|
<XIcon /> {{ formatMessage(messages.revokeSessionButton) }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
import { XIcon } from '@modrinth/assets'
|
|
import {
|
|
commonMessages,
|
|
commonSettingsMessages,
|
|
defineMessages,
|
|
injectNotificationManager,
|
|
useRelativeTime,
|
|
useVIntl,
|
|
} from '@modrinth/ui'
|
|
|
|
definePageMeta({
|
|
middleware: 'auth',
|
|
})
|
|
|
|
const { addNotification } = injectNotificationManager()
|
|
const { formatMessage } = useVIntl()
|
|
const formatRelativeTime = useRelativeTime()
|
|
|
|
const messages = defineMessages({
|
|
currentSessionLabel: {
|
|
id: 'settings.sessions.current-session',
|
|
defaultMessage: 'Current session',
|
|
},
|
|
revokeSessionButton: {
|
|
id: 'settings.sessions.action.revoke-session',
|
|
defaultMessage: 'Revoke session',
|
|
},
|
|
createdAgoLabel: {
|
|
id: 'settings.sessions.created-ago',
|
|
defaultMessage: 'Created {ago}',
|
|
},
|
|
sessionsDescription: {
|
|
id: 'settings.sessions.description',
|
|
defaultMessage:
|
|
"Here are all the devices that are currently logged in with your Modrinth account. You can log out of each one individually.\n\nIf you see an entry you don't recognize, log out of that device and change your Modrinth account password immediately.",
|
|
},
|
|
lastAccessedAgoLabel: {
|
|
id: 'settings.sessions.last-accessed-ago',
|
|
defaultMessage: 'Last accessed {ago}',
|
|
},
|
|
unknownOsLabel: {
|
|
id: 'settings.sessions.unknown-os',
|
|
defaultMessage: 'Unknown OS',
|
|
},
|
|
unknownPlatformLabel: {
|
|
id: 'settings.sessions.unknown-platform',
|
|
defaultMessage: 'Unknown platform',
|
|
},
|
|
})
|
|
|
|
useHead({
|
|
title: () => `${formatMessage(commonSettingsMessages.sessions)} - Modrinth`,
|
|
})
|
|
|
|
const { data: sessions, refresh } = await useAsyncData('session/list', () =>
|
|
useBaseFetch('session/list'),
|
|
)
|
|
|
|
async function revokeSession(id) {
|
|
startLoading()
|
|
try {
|
|
sessions.value = sessions.value.filter((x) => x.id !== id)
|
|
await useBaseFetch(`session/${id}`, {
|
|
method: 'DELETE',
|
|
})
|
|
await refresh()
|
|
} catch (err) {
|
|
addNotification({
|
|
title: formatMessage(commonMessages.errorNotificationTitle),
|
|
text: err.data ? err.data.description : err,
|
|
type: 'error',
|
|
})
|
|
}
|
|
stopLoading()
|
|
}
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.session {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
|
|
@media screen and (min-width: 800px) {
|
|
flex-direction: row;
|
|
align-items: center;
|
|
|
|
.input-group {
|
|
margin-left: auto;
|
|
}
|
|
}
|
|
}
|
|
</style>
|