Upgrade to Vue3 and Element Plus (#1374)

* Update Vue devtools

* upgrade vue pinia element-plus vue-i18n, add vite

* fix: i18n

* global components

* change v-deep

* upgrade vue-lazyload

* data table

* update enlint and safe-dialog

* package.json and vite.config.js

* el-icon

* el-message

* vue 2 -> vue3 migration changes

* $pinia

* dialog

* el-popover slot

* lint

* chore

* slot

* scss

* remote state access

* misc

* jsconfig

* el-button size mini -> small

* :model-value

* ElMessageBox

* datatable

* remove v-lazyload

* template #dropdown

* mini -> small

* css

* byebye hideTooltips

* use sass-embedded

* Update SQLite, remove unneeded libraries

* Fix shift remove local avatar favorites

* Electron arm64

* arm64 support

* bye pug

* f-word vite hah

* misc

* remove safe dialog component

* Add self invite to launch dialog

* Fix errors

* Icons 1

* improve localfavorite loading performance

* improve favorites world item performance

* dialog visibility changes for Element Plus

* clear element plus error

* import performance

* revert App.vue hah

* hah

* Revert "Add self invite to launch dialog"

This reverts commit 4801cfad58.

* Toggle self invite/open in-game

* Self invite on launch dialog

* el-button icon

* el-icon

* fix user dialog tab switching logic

* fix PlayerList

* Formatting changes

* More icons

* Fix friend log table

* loading margin

* fix markdown

* fix world dialog tab switching issue

* Fixes and formatting

* fix: global i18n.t export

* fix favorites world tab not working

* Create instance, displayName

* Remove group members sort by userId

* Fix loading dialog tabs on swtich

* Star

* charts console.warn

* wip: fix charts

* wip: fix charts

* wip: charts composables

* fix favorite item tooltip warning

* Fixes and formatting

* Clean up image dialogs

* Remove unused method

* Fix platform/size border

* Fix platform/size border

* $vr

* fix friendExportDialogVisible binding

* ElMessageBox and Settings

* Login formatting

* Rename VR overlay query

* Fix image popover and userdialog badges

* Formatting

* Big buttons

* Fixes, update Cef

* Fix gameLog table nav buttons jumping around while using nav buttons

* Fix z-index

* vr overlay

* vite input add theme

* defineAsyncComponent

* ISO 639-1

* fix i18n

* clean t

* Formatting, fix calendar, rotate arrows

* Show user status when user is offline

* Fix VR overlay

* fix theme and clean up

* split InstanceActivity

* tweak

* Fix VR overlay formatting

* fix scss var

* AppDebug hahahaha

* Years

* remove reactive

* improve perf

* state hah…

* fix user rendering poblems when user object is not yet loaded

* improve perf

* Update avatar/world image uploader, licenses, remove previous images dialog (old images are now deleted)

* improve perf 1

* Suppress stray errors

* fix traveling location display issue

* Fix empty instance creator

* improve friend list refresh performance

* fix main charts

* fix chart

* Fix darkmode

* Fix avatar dialog tags

---------

Co-authored-by: pa <maplenagisa@gmail.com>
This commit is contained in:
Natsumi
2025-09-12 10:45:24 +12:00
committed by GitHub
parent b233bbc299
commit 3324d0d279
249 changed files with 12948 additions and 19815 deletions

2023
src/vr/Vr.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
<template>
<span>
<span>{{ text }}</span>
<span v-if="groupName">({{ groupName }})</span>
<span
v-if="region"
class="flags"
:class="region"
style="display: inline-block; margin-bottom: 2px; margin-left: 5px">
</span>
<i v-if="strict" style="display: inline-block; margin-left: 5px" class="ri-lock-line"></i>
</span>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import { parseLocation } from '../../shared/utils/location';
const props = defineProps({
location: String,
hint: {
type: String,
default: ''
},
grouphint: {
type: String,
default: ''
}
});
const text = ref('');
const region = ref('');
const strict = ref(false);
const groupName = ref('');
function parse() {
text.value = props.location;
const L = parseLocation(props.location);
if (L.isOffline) {
text.value = 'Offline';
} else if (L.isPrivate) {
text.value = 'Private';
} else if (L.isTraveling) {
text.value = 'Traveling';
} else if (typeof props.hint === 'string' && props.hint !== '') {
if (L.instanceId) {
text.value = `${props.hint} #${L.instanceName} ${L.accessTypeName}`;
} else {
text.value = props.hint;
}
} else if (L.worldId) {
if (L.instanceId) {
text.value = ` #${L.instanceName} ${L.accessTypeName}`;
} else {
text.value = props.location;
}
}
region.value = '';
if (props.location !== '' && L.instanceId && !L.isOffline && !L.isPrivate) {
region.value = L.region;
if (!L.region) {
region.value = 'us';
}
}
strict.value = L.strict;
groupName.value = props.grouphint;
}
watch(() => props.location, parse);
onMounted(parse);
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

26
src/vr/vr.js Normal file
View File

@@ -0,0 +1,26 @@
// Copyright(c) 2019-2025 pypy, Natsumi and individual contributors.
// All rights reserved.
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
import { createApp } from 'vue';
import { initNoty } from '../plugin/noty';
import { i18n } from '../plugin/i18n';
import InteropApi from '../ipc-electron/interopApi.js';
import Vr from './Vr.vue';
initNoty(true);
if (WINDOWS) {
await CefSharp.BindObjectAsync('AppApiVr');
} else {
// @ts-ignore
window.AppApiVr = InteropApi.AppApiVrElectron;
}
const $app = createApp(Vr);
$app.use(i18n);
$app.mount('#root');

456
src/vr/vr.scss Normal file
View File

@@ -0,0 +1,456 @@
@charset "utf-8";
//
// Copyright(c) 2019-2025 pypy and individual contributors.
// All rights reserved.
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
//
@use '../assets/scss/flags.scss';
@import 'animate.css/animate.min.css';
@import 'noty/lib/noty.css';
@import 'remixicon/fonts/remixicon.css';
/*
마지노선인듯
화면 24px -> 나나 32
손등 18px -> 나나 24
*/
.is-loading {
animation: rotation 2s linear infinite;
display: inline-block;
}
body {
margin: 0;
}
.noty_body {
display: block;
}
.noty_layout {
width: 80% !important;
max-width: none;
}
.noty_theme__relax.noty_bar,
.noty_theme__sunset.noty_bar {
height: 84px;
position: relative;
margin: 8px 0;
overflow: hidden;
border-radius: 8px;
}
.noty_theme__relax.noty_bar .noty_body,
.noty_theme__sunset.noty_bar .noty_body {
font-size: 30px;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
}
.noty_theme__relax.noty_bar .noty_buttons,
.noty_theme__sunset.noty_bar .noty_buttons {
padding: 10px 20px;
}
.noty_theme__relax.noty_type__alert,
.noty_theme__relax.noty_type__notification {
color: #444;
background-color: #fff;
border: 2px solid #dedede;
}
.noty_theme__relax.noty_type__warning {
color: #826200;
background-color: #ffeaa8;
border: 2px solid #ffc237;
}
.noty_theme__relax.noty_type__warning .noty_buttons {
border-color: #dfaa30;
}
.noty_theme__relax.noty_type__error {
color: #fff;
background-color: #ff8181;
border: 2px solid #e25353;
}
.noty_theme__relax.noty_type__error .noty_buttons {
border-color: #8b0000;
}
.noty_theme__relax.noty_type__info,
.noty_theme__relax.noty_type__information {
color: #fff;
background-color: #78c5e7;
border: 2px solid #3badd6;
}
.noty_theme__relax.noty_type__info .noty_buttons,
.noty_theme__relax.noty_type__information .noty_buttons {
border-color: #0b90c4;
}
.noty_theme__relax.noty_type__success {
color: #006400;
background-color: #bcf5bc;
border: 2px solid #7cdd77;
}
.noty_theme__relax.noty_type__success .noty_buttons {
border-color: #50c24e;
}
.noty_theme__sunset.noty_type__alert,
.noty_theme__sunset.noty_type__notification {
color: #fff;
background-color: #073b4c;
}
.noty_theme__sunset.noty_type__alert .noty_progressbar,
.noty_theme__sunset.noty_type__notification .noty_progressbar {
background-color: #fff;
}
.noty_theme__sunset.noty_type__warning {
color: #fff;
background-color: #ffd166;
}
.noty_theme__sunset.noty_type__error {
color: #fff;
background-color: #ef476f;
}
.noty_theme__sunset.noty_type__info,
.noty_theme__sunset.noty_type__information {
color: #fff;
background-color: #118ab2;
}
.noty_theme__sunset.noty_type__success {
color: #fff;
background-color: #06d6a0;
}
.noty_theme__sunset.noty_type__error .noty_progressbar {
opacity: 0.4;
}
.noty_theme__sunset.noty_type__info .noty_progressbar,
.noty_theme__sunset.noty_type__information .noty_progressbar {
opacity: 0.6;
}
.noty_has_timeout.noty_has_progressbar .noty_progressbar {
height: 6px;
}
.noty-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 16px 16px 0 22px;
}
.noty-img {
height: 84px;
float: left;
border-radius: 8px;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
border-radius: 16px;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.25);
border-radius: 16px;
}
@font-face {
font-family: 'ellipsis-font';
src: local('Times New Roman');
unicode-range: U+2026;
}
body,
input,
textarea,
select,
button {
font-family:
'ellipsis-font', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans TC',
'Noto Sans SC', 'Meiryo UI', 'Malgun Gothic', 'Segoe UI', sans-serif;
line-height: normal;
text-shadow:
#000 0px 0px 3px,
#000 0px 0px 3px,
#000 0px 0px 3px,
#000 0px 0px 3px,
#000 0px 0px 3px,
#000 0px 0px 3px;
overflow: hidden;
}
.x-app {
position: absolute;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
overflow: hidden;
}
.x-app-type {
color: #fff;
}
.background {
background: #1f1f1f;
text-shadow: none;
}
.x-container {
position: relative;
flex: none;
padding: 2px 10px 0 10px;
overflow: hidden;
}
.x-containerbottom {
padding: 0px 10px;
overflow: hidden;
font-size: 20px;
white-space: nowrap;
}
.x-containerbottom span {
display: block;
overflow: hidden;
}
.np-progress-bar {
width: 0%;
height: 2px;
background-color: white;
}
.np-progress-circle {
position: absolute;
bottom: 0;
left: 0;
width: 120px;
height: 120px;
transform: rotate(270deg);
}
.np-progress-circle-stroke {
opacity: 0;
stroke-dasharray: 189;
stroke-dashoffset: 189;
}
.x-friend-item {
box-sizing: border-box;
display: flex;
align-items: center;
font-size: 18px;
}
.x-friend-item .time {
margin-right: 5px;
}
.x-friend-item .name {
font-weight: bold;
}
.item .name {
color: #c5c5c5;
}
.friend .name {
color: #fff;
}
.favorite .name {
color: #ff0;
}
.x-friend-item > .avatar {
position: relative;
display: inline-block;
flex: none;
width: 40px;
height: 40px;
margin-right: 8px;
}
.x-friend-item > img.avatar {
width: 50px;
margin-right: 0;
margin-left: 5px;
border-radius: 2px;
}
.x-friend-item > .avatar > img {
width: 100%;
height: 100%;
border-radius: 40%;
object-fit: cover;
}
.x-friend-item > .detail {
flex: 1;
overflow: hidden;
}
.x-friend-item > .detail > .name,
.x-friend-item > .detail > .extra {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.x-friend-item > .detail > .name {
font-weight: bold;
}
.x-friend-item > .detail > .extra {
font-weight: normal;
}
i.x-user-status {
display: inline-block;
width: 13px;
height: 13px;
background: #808080;
border-radius: 50%;
}
i.x-user-status.active {
background: #f4e05e;
}
i.x-user-status.online {
background: #67c23a;
}
i.x-user-status.joinme {
background: #409eff;
mask-image: url(../assets/images/masks/joinme.svg);
}
i.x-user-status.askme {
background: #ff9500;
mask-image: url(../assets/images/masks/askme.svg);
}
i.x-user-status.busy {
background: #ff2c2c;
mask-image: url(../assets/images/masks/busy.svg);
}
.spin {
animation: rotation 2.5s infinite linear;
position: absolute;
width: 24px;
height: 30px;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
.hud-feed {
position: absolute;
right: 0;
width: 100%;
}
.hud-feed .item,
.hud-timeout .item {
margin: 0;
text-align: right;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.hud-feed .item {
font-size: 32px;
}
.hud-feed .combo {
color: #aaa;
}
.hud-timeout .item {
font-size: 40px;
}
.hud-timeout {
position: absolute;
bottom: 0;
right: 0;
}
.hud-timeout-feed {
position: absolute;
bottom: 150px;
right: 0;
color: #ed1b24;
}
.hud-timeout svg {
position: absolute;
right: -160px;
bottom: 0;
}
.tracker-container {
flex: 1 1 auto;
text-align: center;
line-height: 18px;
width: 55px;
}
.tracker-device img {
height: 32px;
transition: all 0.25s linear;
}
.tracker-warning {
color: #fcfb00;
}
.tracker-warning img {
filter: saturate(250%) brightness(151%) hue-rotate(221deg);
}
.tracker-error {
color: #fd4444;
}
.tracker-error img {
filter: saturate(160%) brightness(88%) hue-rotate(161deg);
}