You've already forked AstralRinth
forked from didirus/AstralRinth
feat: add info event listener and payload for enhanced event handling
- Implemented `info_listener` in `events.js` to listen for 'info' events and handle payloads. - Added `emit_info` function in `emit.rs` to emit 'info' events with a message payload. - Defined `InfoPayload` struct in `mod.rs` to structure the data for 'info' events. - Integrated `emit_info` calls in the Minecraft launch logic to provide feedback on account types. - Introduced a new offline icon in SVG format and removed outdated pirate icons from assets. - Updated asset index to include the new offline icon and removed references to deleted icons.
This commit is contained in:
@@ -73,7 +73,7 @@ import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
import { debugAnalytics, initAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
||||
import { check_reachable } from '@/helpers/auth.js'
|
||||
import { get_user } from '@/helpers/cache.js'
|
||||
import { command_listener, warning_listener } from '@/helpers/events.js'
|
||||
import { command_listener, warning_listener, info_listener } from '@/helpers/events.js'
|
||||
import { useFetch } from '@/helpers/fetch.js'
|
||||
import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.ts'
|
||||
import { list } from '@/helpers/profile.js'
|
||||
@@ -286,6 +286,15 @@ async function setupApp() {
|
||||
}),
|
||||
)
|
||||
|
||||
// [AR] Info listener
|
||||
await info_listener((e) =>
|
||||
addNotification({
|
||||
title: 'Info',
|
||||
text: e.message,
|
||||
type: 'info',
|
||||
}),
|
||||
)
|
||||
|
||||
useFetch(
|
||||
`https://api.modrinth.com/appCriticalAnnouncement.json?version=${version}`,
|
||||
'criticalAnnouncements',
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
<template>
|
||||
<div v-if="mode !== 'isolated'" ref="button"
|
||||
<div
|
||||
v-if="mode !== 'isolated'"
|
||||
ref="button"
|
||||
class="button-base mt-2 px-3 py-2 bg-button-bg rounded-xl flex items-center gap-2"
|
||||
:class="{ expanded: mode === 'expanded' }" @click="toggleMenu">
|
||||
<Avatar size="36px" :src="selectedAccount ? avatarUrl : 'https://launcher-files.modrinth.com/assets/steve_head.png'
|
||||
" />
|
||||
:class="{ expanded: mode === 'expanded' }"
|
||||
@click="toggleMenu"
|
||||
>
|
||||
<Avatar
|
||||
size="36px"
|
||||
:src="
|
||||
selectedAccount ? avatarUrl : 'https://launcher-files.modrinth.com/assets/steve_head.png'
|
||||
"
|
||||
/>
|
||||
<div class="flex flex-col w-full">
|
||||
<span>
|
||||
<component :is="getAccountType(selectedAccount)" v-if="selectedAccount" class="vector-icon" />
|
||||
<component
|
||||
:is="getAccountType(selectedAccount)"
|
||||
v-if="selectedAccount"
|
||||
class="vector-icon"
|
||||
/>
|
||||
{{ selectedAccount ? selectedAccount.profile.name : 'Select account' }}
|
||||
</span>
|
||||
<span class="text-secondary text-xs">Minecraft account</span>
|
||||
@@ -14,32 +26,46 @@
|
||||
<DropdownIcon class="w-5 h-5 shrink-0" />
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<Card v-if="showCard || mode === 'isolated'" ref="card" class="account-card"
|
||||
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }">
|
||||
<Card
|
||||
v-if="showCard || mode === 'isolated'"
|
||||
ref="card"
|
||||
class="account-card"
|
||||
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }"
|
||||
>
|
||||
<div v-if="selectedAccount" class="selected account">
|
||||
<Avatar size="xs" :src="avatarUrl" />
|
||||
<div>
|
||||
<h4>
|
||||
<component :is="getAccountType(selectedAccount)" class="vector-icon" /> {{
|
||||
selectedAccount.profile.name }}
|
||||
<component :is="getAccountType(selectedAccount)" class="vector-icon" />
|
||||
{{ selectedAccount.profile.name }}
|
||||
</h4>
|
||||
<p>Selected</p>
|
||||
</div>
|
||||
<Button v-tooltip="'Log out'" icon-only color="raised" @click="logout(selectedAccount.profile.id)">
|
||||
<Button
|
||||
v-tooltip="'Log out'"
|
||||
icon-only
|
||||
color="raised"
|
||||
@click="logout(selectedAccount.profile.id)"
|
||||
>
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<div v-else class="login-section account">
|
||||
<h4>Not signed in</h4>
|
||||
<Button v-tooltip="'Log via Microsoft'" :disabled="microsoftLoginDisabled" icon-only @click="login()">
|
||||
<Button
|
||||
v-tooltip="'Log via Microsoft'"
|
||||
:disabled="microsoftLoginDisabled"
|
||||
icon-only
|
||||
@click="login()"
|
||||
>
|
||||
<MicrosoftIcon v-if="!microsoftLoginDisabled" />
|
||||
<SpinnerIcon v-else class="animate-spin" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Add offline account'" icon-only @click="showOfflineLoginModal()">
|
||||
<PirateIcon />
|
||||
<OfflineIcon />
|
||||
</Button>
|
||||
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElybyLoginModal()">
|
||||
<ElyByIcon v-if="!elybyLoginDisabled" />
|
||||
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElyByLoginModal()">
|
||||
<ElyByIcon v-if="!elyByLoginDisabled" />
|
||||
<SpinnerIcon v-else class="animate-spin" />
|
||||
</Button>
|
||||
</div>
|
||||
@@ -63,23 +89,37 @@
|
||||
<SpinnerIcon v-else class="animate-spin" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Add offline account'" icon-only @click="showOfflineLoginModal()">
|
||||
<PirateIcon />
|
||||
<OfflineIcon />
|
||||
</Button>
|
||||
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElybyLoginModal()">
|
||||
<ElyByIcon v-if="!elybyLoginDisabled" />
|
||||
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElyByLoginModal()">
|
||||
<ElyByIcon v-if="!elyByLoginDisabled" />
|
||||
<SpinnerIcon v-else class="animate-spin" />
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</transition>
|
||||
<ModalWrapper ref="addElybyModal" class="modal" header="Authenticate with Ely.by">
|
||||
<ModalWrapper ref="requestElybyTwoFactorCodeModal" class="modal"
|
||||
header="Ely.by requested 2FA code for authentication">
|
||||
<ModalWrapper ref="addElyByModal" class="modal" header="Authenticate with Ely.by">
|
||||
<ModalWrapper
|
||||
ref="requestElyByTwoFactorCodeModal"
|
||||
class="modal"
|
||||
header="Ely.by requested 2FA code for authentication"
|
||||
>
|
||||
<div class="flex flex-col gap-4 px-6 py-5">
|
||||
<label class="label">Enter your 2FA code</label>
|
||||
<input v-model="elybyTwoFactorCode" type="text" placeholder="Your 2FA code here..." class="input" />
|
||||
<input
|
||||
v-model="elyByTwoFactorCode"
|
||||
type="text"
|
||||
placeholder="Your 2FA code here..."
|
||||
class="input"
|
||||
/>
|
||||
<div class="mt-6 ml-auto">
|
||||
<Button icon-only color="primary" class="continue-button" @click="addElybyProfile()">
|
||||
<Button
|
||||
:disabled="elyByLoginDisabled"
|
||||
icon-only
|
||||
color="primary"
|
||||
class="continue-button"
|
||||
@click="addElyByProfile()"
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
@@ -87,11 +127,27 @@
|
||||
</ModalWrapper>
|
||||
<div class="flex flex-col gap-4 px-6 py-5">
|
||||
<label class="label">Enter your player name or email (preferred)</label>
|
||||
<input v-model="elybyLogin" type="text" placeholder="Your player name or email here..." class="input" />
|
||||
<input
|
||||
v-model="elyByLogin"
|
||||
type="text"
|
||||
placeholder="Your player name or email here..."
|
||||
class="input"
|
||||
/>
|
||||
<label class="label">Enter your password</label>
|
||||
<input v-model="elybyPassword" type="password" placeholder="Your password here..." class="input" />
|
||||
<input
|
||||
v-model="elyByPassword"
|
||||
type="password"
|
||||
placeholder="Your password here..."
|
||||
class="input"
|
||||
/>
|
||||
<div class="mt-6 ml-auto">
|
||||
<Button icon-only color="primary" class="continue-button" @click="addElybyProfile()">
|
||||
<Button
|
||||
:disabled="elyByLoginDisabled"
|
||||
icon-only
|
||||
color="primary"
|
||||
class="continue-button"
|
||||
@click="addElyByProfile()"
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
</div>
|
||||
@@ -100,7 +156,12 @@
|
||||
<ModalWrapper ref="addOfflineModal" class="modal" header="Add new offline account">
|
||||
<div class="flex flex-col gap-4 px-6 py-5">
|
||||
<label class="label">Enter your player name</label>
|
||||
<input v-model="offlinePlayerName" type="text" placeholder="Your player name here..." class="input" />
|
||||
<input
|
||||
v-model="offlinePlayerName"
|
||||
type="text"
|
||||
placeholder="Your player name here..."
|
||||
class="input"
|
||||
/>
|
||||
<div class="mt-6 ml-auto">
|
||||
<Button icon-only color="primary" class="continue-button" @click="addOfflineProfile()">
|
||||
Login
|
||||
@@ -108,21 +169,28 @@
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
<ModalWrapper ref="authenticationElybyErrorModal" class="modal"
|
||||
header="Error while proceeding authentication event with Ely.by">
|
||||
<ModalWrapper
|
||||
ref="authenticationElyByErrorModal"
|
||||
class="modal"
|
||||
header="Error while proceeding authentication event with Ely.by"
|
||||
>
|
||||
<div class="flex flex-col gap-4 px-6 py-5">
|
||||
<label class="text-base font-medium text-red-700">
|
||||
An error occurred while logging in.
|
||||
</label>
|
||||
|
||||
<div class="mt-6 ml-auto">
|
||||
<Button color="primary" class="retry-button" @click="retryAddElybyProfile">
|
||||
<Button color="primary" class="retry-button" @click="retryAddElyByProfile">
|
||||
Try again
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
<ModalWrapper ref="inputElybyErrorModal" class="modal" header="Error while proceeding input event with Ely.by">
|
||||
<ModalWrapper
|
||||
ref="inputElyByErrorModal"
|
||||
class="modal"
|
||||
header="Error while proceeding input event with Ely.by"
|
||||
>
|
||||
<div class="flex flex-col gap-4 px-6 py-5">
|
||||
<label class="text-base font-medium text-red-700">
|
||||
An error occurred while adding the Ely.by account. Please follow the instructions below.
|
||||
@@ -134,13 +202,17 @@
|
||||
</ul>
|
||||
|
||||
<div class="mt-6 ml-auto">
|
||||
<Button color="primary" class="retry-button" @click="retryAddElybyProfile">
|
||||
<Button color="primary" class="retry-button" @click="retryAddElyByProfile">
|
||||
Try again
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
<ModalWrapper ref="inputErrorModal" class="modal" header="Error while proceeding input event with offline account">
|
||||
<ModalWrapper
|
||||
ref="inputOfflineErrorModal"
|
||||
class="modal"
|
||||
header="Error while proceeding input event with offline account"
|
||||
>
|
||||
<div class="flex flex-col gap-4 px-6 py-5">
|
||||
<label class="text-base font-medium text-red-700">
|
||||
An error occurred while adding the offline account. Please follow the instructions below.
|
||||
@@ -149,9 +221,10 @@
|
||||
<ul class="list-disc list-inside text-sm space-y-1">
|
||||
<li>Check that you have entered the correct player name.</li>
|
||||
<li>
|
||||
Player name must be at least {{ minOfflinePlayerNameLength }} characters long and no more than
|
||||
{{ maxOfflinePlayerNameLength }} characters.
|
||||
Player name must be at least {{ minOfflinePlayerNameLength }} characters long and no more
|
||||
than {{ maxOfflinePlayerNameLength }} characters.
|
||||
</li>
|
||||
<li>Make sure your name meets the format requirement `{{ nameExp }}`</li>
|
||||
</ul>
|
||||
|
||||
<div class="mt-6 ml-auto">
|
||||
@@ -161,7 +234,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
<ModalWrapper ref="exceptionErrorModal" class="modal" header="Unexpected error occurred">
|
||||
<ModalWrapper ref="unexpectedErrorModal" class="modal" header="Unexpected error occurred">
|
||||
<div class="modal-body">
|
||||
<label class="label">An unexpected error has occurred. Please try again later.</label>
|
||||
</div>
|
||||
@@ -169,35 +242,32 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
DropdownIcon,
|
||||
TrashIcon,
|
||||
PirateIcon as Offline,
|
||||
MicrosoftIcon as License,
|
||||
ElyByIcon as Elyby,
|
||||
MicrosoftIcon,
|
||||
PirateIcon,
|
||||
ElyByIcon,
|
||||
SpinnerIcon
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
|
||||
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import {
|
||||
elyby_auth_authenticate,
|
||||
elyby_login,
|
||||
get_default_user,
|
||||
login as login_flow,
|
||||
offline_login,
|
||||
users,
|
||||
remove_user,
|
||||
set_default_user,
|
||||
login as login_flow,
|
||||
get_default_user,
|
||||
users,
|
||||
} from '@/helpers/auth'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
import { get_available_skins } from '@/helpers/skins'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import {
|
||||
DropdownIcon,
|
||||
ElyByIcon,
|
||||
MicrosoftIcon,
|
||||
OfflineIcon,
|
||||
SpinnerIcon,
|
||||
TrashIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
|
||||
import { computed, onBeforeUnmount, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
@@ -213,34 +283,36 @@ const emit = defineEmits(['change'])
|
||||
|
||||
const accounts = ref({})
|
||||
const microsoftLoginDisabled = ref(false)
|
||||
const elybyLoginDisabled = ref(false)
|
||||
const elyByLoginDisabled = ref(false)
|
||||
const defaultUser = ref()
|
||||
|
||||
// [AR] • Feature
|
||||
const clientToken = "astralrinth"
|
||||
const clientToken = 'astralrinth'
|
||||
const addOfflineModal = ref(null)
|
||||
const addElybyModal = ref(null)
|
||||
const requestElybyTwoFactorCodeModal = ref(null)
|
||||
const authenticationElybyErrorModal = ref(null)
|
||||
const inputElybyErrorModal = ref(null)
|
||||
const inputErrorModal = ref(null)
|
||||
const exceptionErrorModal = ref(null)
|
||||
const addElyByModal = ref(null)
|
||||
const requestElyByTwoFactorCodeModal = ref(null)
|
||||
const authenticationElyByErrorModal = ref(null)
|
||||
const inputElyByErrorModal = ref(null)
|
||||
const inputOfflineErrorModal = ref(null)
|
||||
const unexpectedErrorModal = ref(null)
|
||||
const offlinePlayerName = ref('')
|
||||
const elybyLogin = ref('')
|
||||
const elybyPassword = ref('')
|
||||
const elybyTwoFactorCode = ref('')
|
||||
const minOfflinePlayerNameLength = 2
|
||||
const elyByLogin = ref('')
|
||||
const elyByPassword = ref('')
|
||||
const elyByTwoFactorCode = ref('')
|
||||
const minOfflinePlayerNameLength = 3
|
||||
const maxOfflinePlayerNameLength = 20
|
||||
const nameExp = 'a-zA-Z0-9_'
|
||||
const nameRegex = new RegExp(`^[${nameExp}]+$`)
|
||||
|
||||
// [AR] • Feature
|
||||
function getAccountType(account) {
|
||||
switch (account.account_type) {
|
||||
case 'microsoft':
|
||||
return License
|
||||
return MicrosoftIcon
|
||||
case 'pirate':
|
||||
return Offline
|
||||
return OfflineIcon
|
||||
case 'elyby':
|
||||
return Elyby
|
||||
return ElyByIcon
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,30 +322,31 @@ function showOfflineLoginModal() {
|
||||
}
|
||||
|
||||
// [AR] • Feature
|
||||
function showElybyLoginModal() {
|
||||
addElybyModal.value?.show()
|
||||
function showElyByLoginModal() {
|
||||
addElyByModal.value?.show()
|
||||
}
|
||||
|
||||
// [AR] • Feature
|
||||
function retryAddOfflineProfile() {
|
||||
inputErrorModal.value?.hide()
|
||||
inputOfflineErrorModal.value?.hide()
|
||||
clearOfflineFields()
|
||||
showOfflineLoginModal()
|
||||
}
|
||||
|
||||
// [AR] • Feature
|
||||
function retryAddElybyProfile() {
|
||||
authenticationElybyErrorModal.value?.hide()
|
||||
inputElybyErrorModal.value?.hide()
|
||||
clearElybyFields()
|
||||
showElybyLoginModal()
|
||||
function retryAddElyByProfile() {
|
||||
authenticationElyByErrorModal.value?.hide()
|
||||
inputElyByErrorModal.value?.hide()
|
||||
elyByLoginDisabled.value = false
|
||||
clearElyByFields()
|
||||
showElyByLoginModal()
|
||||
}
|
||||
|
||||
// [AR] • Feature
|
||||
function clearElybyFields() {
|
||||
elybyLogin.value = ''
|
||||
elybyPassword.value = ''
|
||||
elybyTwoFactorCode.value = ''
|
||||
function clearElyByFields() {
|
||||
elyByLogin.value = ''
|
||||
elyByPassword.value = ''
|
||||
elyByTwoFactorCode.value = ''
|
||||
}
|
||||
|
||||
// [AR] • Feature
|
||||
@@ -284,11 +357,14 @@ function clearOfflineFields() {
|
||||
// [AR] • Feature
|
||||
async function addOfflineProfile() {
|
||||
const name = offlinePlayerName.value.trim()
|
||||
const isValidName = name.length >= minOfflinePlayerNameLength && name.length <= maxOfflinePlayerNameLength
|
||||
const isValidName =
|
||||
nameRegex.test(name) &&
|
||||
name.length >= minOfflinePlayerNameLength &&
|
||||
name.length <= maxOfflinePlayerNameLength
|
||||
|
||||
if (!isValidName) {
|
||||
addOfflineModal.value?.hide()
|
||||
inputErrorModal.value?.show()
|
||||
inputOfflineErrorModal.value?.show()
|
||||
clearOfflineFields()
|
||||
return
|
||||
}
|
||||
@@ -302,39 +378,36 @@ async function addOfflineProfile() {
|
||||
await setAccount(result)
|
||||
await refreshValues()
|
||||
} else {
|
||||
exceptionErrorModal.value?.show()
|
||||
unexpectedErrorModal.value?.show()
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
exceptionErrorModal.value?.show()
|
||||
unexpectedErrorModal.value?.show()
|
||||
} finally {
|
||||
clearOfflineFields()
|
||||
}
|
||||
}
|
||||
|
||||
// [AR] • Feature
|
||||
async function addElybyProfile() {
|
||||
if (!elybyLogin.value || !elybyPassword.value) {
|
||||
addElybyModal.value?.hide()
|
||||
inputElybyErrorModal.value?.show()
|
||||
clearElybyFields()
|
||||
async function addElyByProfile() {
|
||||
elyByLoginDisabled.value = true
|
||||
if (!elyByLogin.value || !elyByPassword.value) {
|
||||
addElyByModal.value?.hide()
|
||||
inputElyByErrorModal.value?.show()
|
||||
clearElyByFields()
|
||||
return
|
||||
}
|
||||
elybyLoginDisabled.value = true
|
||||
|
||||
const login = elybyLogin.value.trim()
|
||||
let password = elybyPassword.value.trim()
|
||||
const twoFactorCode = elybyTwoFactorCode.value.trim()
|
||||
// Parse ely.by credential fields
|
||||
const login = elyByLogin.value.trim()
|
||||
let password = elyByPassword.value.trim()
|
||||
const twoFactorCode = elyByTwoFactorCode.value.trim()
|
||||
if (password && twoFactorCode) {
|
||||
password = `${password}:${twoFactorCode}`
|
||||
}
|
||||
|
||||
try {
|
||||
const raw_result = await elyby_auth_authenticate(
|
||||
login,
|
||||
password,
|
||||
clientToken
|
||||
)
|
||||
const raw_result = await elyby_auth_authenticate(login, password, clientToken)
|
||||
|
||||
const json_data = JSON.parse(raw_result)
|
||||
|
||||
@@ -346,13 +419,13 @@ async function addElybyProfile() {
|
||||
json_data.error === 'ForbiddenOperationException' &&
|
||||
json_data.errorMessage?.includes('two factor')
|
||||
) {
|
||||
requestElybyTwoFactorCodeModal.value?.show()
|
||||
requestElyByTwoFactorCodeModal.value?.show()
|
||||
return
|
||||
}
|
||||
|
||||
addElybyModal.value?.hide()
|
||||
requestElybyTwoFactorCodeModal.value?.hide()
|
||||
authenticationElybyErrorModal.value?.show()
|
||||
addElyByModal.value?.hide()
|
||||
requestElyByTwoFactorCodeModal.value?.hide()
|
||||
authenticationElyByErrorModal.value?.show()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -362,18 +435,18 @@ async function addElybyProfile() {
|
||||
|
||||
const result = await elyby_login(selectedProfileId, selectedProfileName, accessToken)
|
||||
|
||||
addElybyModal.value?.hide()
|
||||
requestElybyTwoFactorCodeModal.value?.hide()
|
||||
addElyByModal.value?.hide()
|
||||
requestElyByTwoFactorCodeModal.value?.hide()
|
||||
|
||||
clearElybyFields()
|
||||
clearElyByFields()
|
||||
|
||||
await setAccount(result)
|
||||
await refreshValues()
|
||||
} catch (err) {
|
||||
handleError(err)
|
||||
exceptionErrorModal.value?.show()
|
||||
unexpectedErrorModal.value?.show()
|
||||
} finally {
|
||||
elybyLoginDisabled.value = false
|
||||
elyByLoginDisabled.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,7 +616,6 @@ onUnmounted(() => {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.vector-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
|
||||
@@ -97,3 +97,8 @@ export async function warning_listener(callback) {
|
||||
export async function friend_listener(callback) {
|
||||
return await listen('friend', (event) => callback(event.payload))
|
||||
}
|
||||
|
||||
// [AR] Payload for the 'info' event
|
||||
export async function info_listener(callback) {
|
||||
return await listen('info', (event) => callback(event.payload))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user