Several changes

- made selection list component
- generalized selection box component;
  added `LanguageSelection` component
- `DXVK.get()` method was renamed to `DXVK.get()`
- added `DXVK.get()` method to get a DXVK with a specified version
This commit is contained in:
Observer KRypt0n_ 2021-12-26 00:47:08 +02:00
parent 210157a5a8
commit 317557b335
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
14 changed files with 332 additions and 173 deletions

View file

@ -10,7 +10,7 @@
<body theme="light">
<div id="app">
<div class="menu">
<div class="menu-item menu-item-active" anchor="general">General</div>
<div class="menu-item menu-item-active" anchor="general">{{ $t('settings.general.title') }}</div>
</div>
<div class="settings">
@ -21,9 +21,13 @@
<l-checkbox locale="general.test2" prop="test2"></l-checkbox>
<l-checkbox locale="general.test3" prop="test3"></l-checkbox>
<l-selectbox locale="general.lang.launcher" prop="lang.launcher">
<li v-for="(lang, code) in languages" :lang="code">{{ lang }}</li>
</l-selectbox>
<l-language locale="general.lang.launcher" prop="lang.launcher">
<li v-for="(lang, code) in languages" :option="code">{{ lang }}</li>
</l-language>
<l-dxvks>
<l-dxvk-item v-for="dxvk in dxvks" :title="dxvk.version"></l-dxvk-item>
</l-dxvks>
</div>
</div>
</div>

View file

@ -19,9 +19,9 @@ export default defineComponent({
active: false
}),
async created()
created()
{
this.active = await Configs.get(this.prop) as boolean;
Configs.get(this.prop).then((active) => this.active = active as boolean);
},
methods: {

View file

@ -0,0 +1,9 @@
<script lang="ts">
import { defineComponent } from 'vue';
import SelectionListItem from './bases/SelectionListItem.vue';
export default defineComponent({
mixins: [SelectionListItem]
});
</script>

10
src/components/DXVKs.vue Normal file
View file

@ -0,0 +1,10 @@
<script lang="ts">
import { defineComponent } from 'vue';
import Configs from '../ts/Configs';
import SelectionList from './bases/SelectionList.vue';
export default defineComponent({
mixins: [SelectionList]
});
</script>

View file

@ -0,0 +1,52 @@
<script lang="ts">
import { defineComponent } from 'vue';
import Configs from '../ts/Configs';
import Selectbox from './bases/Selectbox.vue';
export default defineComponent({
mixins: [Selectbox],
inject: ['languages'],
data()
{
return {
trueTitle: '',
selectionOpen: false,
options: {
selected: 'en-us',
available: this.languages
}
};
},
created()
{
const group = this.locale.split('.')[0];
const locale = this.locale.substring(this.locale.indexOf('.') + 1);
this.trueTitle = `settings.${group}.items.${locale}`;
Configs.get('lang.launcher').then((lang) => {
this.options.selected = (lang as string|null) ?? 'en-us';
const children = document.getElementById(this.prop)!.children;
/*for (let i = 0; i < children.length; ++i)
if (children[i].getAttribute('lang') === )*/
});
},
methods: {
selectionChanged(value: string)
{
this.$i18n.locale = value;
},
defaultOption(): Promise<string>
{
return Configs.get('lang.launcher') as Promise<string>;
}
}
});
</script>

View file

@ -1,77 +0,0 @@
<template>
<div class="select" :class="{'select-active': selectionOpen}">
<span>{{ $t(this.trueLocale) }}</span>
<div class="select-options">
<ul @click="selectLang">
<slot></slot>
</ul>
</div>
<div class="selected-item" @click="this.selectionOpen = !this.selectionOpen">
<span>{{ lang.available[lang.selected] }}</span>
<img src="../assets/svgs/arrow.svg" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Configs from '../ts/Configs';
export default defineComponent({
props: ['locale', 'prop'],
inject: ['languages'],
data()
{
return {
trueLocale: '',
selectionOpen: false,
lang: {
selected: 'en-us',
available: this.languages
}
};
},
created()
{
const group = this.locale.split('.')[0];
const locale = this.locale.substring(this.locale.indexOf('.') + 1);
this.trueLocale = `settings.${group}.items.${locale}`;
Configs.get('lang.launcher').then((lang) => {
this.lang.selected = (lang as string|null) ?? 'en-us';
});
},
methods: {
selectLang(event: MouseEvent)
{
const li = event.target as HTMLElement;
if (!li.classList.contains('selected'))
{
const children = li.parentElement!.children;
for (let i = 0; i < children.length; ++i)
children[i].classList.remove('selected');
li.classList.add('selected');
this.lang.selected = li.getAttribute('lang')!;
this.selectionOpen = false;
this.$i18n.locale = this.lang.selected;
Configs.set(this.prop, this.lang.selected);
}
}
}
});
</script>
<style src="../sass/components/selectbox.sass" lang="sass"></style>

View file

@ -0,0 +1,85 @@
<template>
<div class="select" :class="{'select-active': selectionOpen}">
<span>{{ $t(this.trueTitle) }}</span>
<div class="select-options">
<ul @click="selectItem" :id="prop">
<slot></slot>
</ul>
</div>
<div class="selected-item" @click="this.selectionOpen = !this.selectionOpen">
<span>{{ options.available[options.selected] }}</span>
<img src="../../assets/svgs/arrow.svg" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Configs from '../../ts/Configs';
export default defineComponent({
props: ['locale', 'prop'],
data()
{
return {
trueTitle: '',
selectionOpen: false,
options: {
selected: '',
available: []
}
};
},
created()
{
const group = this.locale.split('.')[0];
const locale = this.locale.substring(this.locale.indexOf('.') + 1);
this.trueTitle = `settings.${group}.items.${locale}`;
this.defaultOption().then((option) => {
this.options.selected = option;
const children = document.getElementById(this.prop)!.children;
for (let i = 0; i < children.length; ++i)
if (children[i].getAttribute('option') === option)
children[i].classList.add('selected');
});
},
methods: {
selectItem(event: MouseEvent)
{
const li = event.target as HTMLElement;
if (!li.classList.contains('selected'))
{
const children = li.parentElement!.children;
for (let i = 0; i < children.length; ++i)
children[i].classList.remove('selected');
li.classList.add('selected');
this.options.selected = li.getAttribute('option')!;
this.selectionOpen = false;
this.selectionChanged(this.options.selected);
Configs.set(this.prop, this.options.selected);
}
},
selectionChanged(value: string) {},
defaultOption(): Promise<string> { return new Promise((resolve) => resolve('')); }
}
});
</script>
<style src="../../sass/components/selectbox.sass" lang="sass"></style>

View file

@ -0,0 +1,13 @@
<template>
<div class="list">
<slot></slot>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({});
</script>
<style src="../../sass/components/selectionList.sass" lang="sass"></style>

View file

@ -0,0 +1,19 @@
<template>
<div class="list-item">
{{ title }}
<div>
<span></span>
<img class="item-delete" src="../../assets/images/delete.png">
<img class="item-download" src="../../assets/images/download.png">
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
props: ['title']
});
</script>

View file

@ -4,9 +4,13 @@ import { createI18n } from 'vue-i18n';
import Window from '../ts/neutralino/Window';
import Locales from '../ts/core/Locales';
import DXVK from '../ts/core/DXVK';
import Configs from '../ts/Configs';
import Checkbox from '../components/Checkbox.vue';
import Selectbox from '../components/Selectbox.vue';
import LanguageSelection from '../components/LanguageSelection.vue';
import DXVKS from '../components/DXVKs.vue';
import DXVKItem from '../components/DXVKItem.vue';
const app = createApp({
data: () => ({
@ -15,8 +19,10 @@ const app = createApp({
// Languages selection
languages: {
'en-us': 'English (US)',
'ru-ru': 'Russian'
}
'ru-ru': 'Русский'
},
dxvks: []
}),
provide()
@ -26,17 +32,26 @@ const app = createApp({
};
},
created()
{
DXVK.list().then((list) => this.dxvks = list);
},
components: {
'l-checkbox': Checkbox,
'l-selectbox': Selectbox
'l-language': LanguageSelection,
'l-dxvks': DXVKS,
'l-dxvk-item': DXVKItem
},
mounted: () => Window.current.show()
});
Locales.get().then((locales) => {
Locales.get().then(async (locales) => {
const locale = await Configs.get('lang.launcher');
app.use(createI18n({
locale: 'en-us',
locale: locale as string,
fallbackLocale: 'en-us',
// @ts-expect-error

View file

@ -145,81 +145,6 @@
.button:not(:last-child)
margin-right: 8px
/* List of buttons */
.list-item
display: flex
align-items: center
height: 52px
margin-bottom: 8px
padding: 0 12px
border-radius: 12px
background-color: map.get($theme-map, "background1")
font-size: 18px
cursor: pointer
@if $theme-name == dark
img
filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(219deg) brightness(102%) contrast(104%)
&:hover
background-color: map.get($theme-map, "background2")
> div
width: auto
height: 52px
min-width: 52px
margin-left: auto
display: flex
align-items: center
img
width: 16px
height: 16px
margin: auto
img.item-delete
// filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(93deg) brightness(103%) contrast(103%)
width: 20px
height: 20px
display: none
.list-item-active
background-color: map.get($theme-map, "primary") !important
color: white !important
img.item-delete
display: none !important
.list-item-disabled
background-color: map.get($theme-map, "background1") !important
color: #abadbd !important
cursor: default !important
img
filter: invert(70%) sepia(13%) saturate(241%) hue-rotate(196deg) brightness(97%) contrast(91%)
.list-item-downloading
img
display: none !important
.list-item-downloaded
> div
img.item-download
display: none
img.item-delete
display: block
/* Buttons */
.button

View file

@ -0,0 +1,82 @@
@use "sass:map"
@mixin themable($theme-name, $theme-map)
body[theme=#{$theme-name}]
.list-item
display: flex
align-items: center
height: 52px
margin-bottom: 8px
padding: 0 12px
border-radius: 12px
background-color: map.get($theme-map, "background1")
font-size: 18px
cursor: pointer
@if $theme-name == dark
img
filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(219deg) brightness(102%) contrast(104%)
&:hover
background-color: map.get($theme-map, "background2")
> div
width: auto
height: 52px
min-width: 52px
margin-left: auto
display: flex
align-items: center
img
width: 16px
height: 16px
margin: auto
img.item-delete
// filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(93deg) brightness(103%) contrast(103%)
width: 20px
height: 20px
display: none
.list-item-active
background-color: map.get($theme-map, "primary") !important
color: white !important
img.item-delete
display: none !important
.list-item-disabled
background-color: map.get($theme-map, "background1") !important
color: #abadbd !important
cursor: default !important
img
filter: invert(70%) sepia(13%) saturate(241%) hue-rotate(196deg) brightness(97%) contrast(91%)
.list-item-downloading
img
display: none !important
.list-item-downloaded
> div
img.item-download
display: none
img.item-delete
display: block
@import "../themes/light"
@import "../themes/dark"
@include themable(light, $light)
@include themable(dark, $dark)

View file

@ -18,7 +18,7 @@ export default class DXVK
/**
* Get DXVKs list
*/
public static get(): Promise<TDXVK[]>
public static list(): Promise<TDXVK[]>
{
return new Promise((resolve) => {
constants.paths.dxvksDir.then(async (dxvksDir: string) => {
@ -46,6 +46,26 @@ export default class DXVK
});
}
/**
* Get DXVK with specified version
*/
public static get(version: string): Promise<DXVK|null>
{
return new Promise((resolve) => {
this.list().then((list) => {
for (const dxvk of list)
if (dxvk.version === version)
{
resolve(dxvk);
return;
}
resolve(null);
});
});
}
/**
* Download DXVK to the [constants.paths.dxvks] directory
*
@ -59,14 +79,16 @@ export default class DXVK
// then we should find this DXVK version and call this method for it
if (typeof dxvk == 'string')
{
let foundDXVK;
(await this.get()).forEach((currDxvk) => {
if (currDxvk.version == dxvk)
foundDXVK = currDxvk;
this.list().then((list) => {
let foundDXVK;
list.forEach((currDxvk) => {
if (currDxvk.version == dxvk)
foundDXVK = currDxvk;
});
resolve(foundDXVK === null ? null : new Stream(foundDXVK));
});
resolve(foundDXVK === null ? null : new Stream(foundDXVK));
}
// Otherwise we can use dxvk.uri and so on to download DXVK

View file

@ -14,7 +14,7 @@ export default (launcher: Launcher): Promise<void> => {
let wineExeutable = 'wine';
const runner = await Runners.current;
if (runner !== null)
{
wineExeutable = `${await constants.paths.runnersDir}/${runner.name}/${runner.files.wine}`;