Files
STARTLINER/src/components/OptionList.vue
2025-03-03 20:44:00 +00:00

184 lines
5.2 KiB
Vue

<script setup lang="ts">
import { Ref, computed, ref } from 'vue';
import InputNumber from 'primevue/inputnumber';
import InputText from 'primevue/inputtext';
import Select from 'primevue/select';
import SelectButton from 'primevue/selectbutton';
import Toggle from 'primevue/toggleswitch';
import { invoke as unproxied_invoke } from '@tauri-apps/api/core';
import OptionCategory from './OptionCategory.vue';
import OptionRow from './OptionRow.vue';
import { invoke } from '../invoke';
import { usePrfStore } from '../stores';
const prf = usePrfStore();
const _cfg = <T extends string | number | boolean>(key: string, dflt: T) =>
computed({
get() {
return (prf.cfg(key) as T) ?? dflt;
},
async set(value) {
await prf.setCfg(key, value ?? dflt);
},
});
const cfgIntel = _cfg('intel', false);
const cfgRezW = _cfg('rez-w', 1080);
const cfgRezH = _cfg('rez-h', 1920);
const cfgDisplayMode = _cfg('display-mode', 'borderless');
const displayModeList = [
{ title: 'Window', value: 'window' },
{ title: 'Borderless window', value: 'borderless' },
{ title: 'Fullscreen', value: 'fullscreen' },
];
const cfgDisplay = _cfg('display', 'default');
const cfgDisplayRotation = _cfg('display-rotation', 0);
const displayRotationList = [
{ title: 'Unchanged', value: 0 },
{ title: 'Portrait', value: 90 },
{ title: 'Portrait (flipped)', value: 270 },
];
const cfgAime = _cfg('aime', false);
const aimeCode = ref('');
const capabilities: Ref<string[]> = ref([]);
const displayList: Ref<{ title: string; value: string }[]> = ref([
{
title: 'Primary',
value: 'default',
},
]);
unproxied_invoke('read_profile_data', {
path: 'aime.txt',
})
.then((v: unknown) => {
if (typeof v === 'string') {
aimeCode.value = v;
} else {
aimeCode.value = '';
}
})
.catch(() => {
aimeCode.value = '';
});
invoke('list_platform_capabilities')
.then(async (v: unknown) => {
if (Array.isArray(v)) {
capabilities.value.push(...v);
}
if (capabilities.value.includes('display')) {
for (const [devName, devString] of (await invoke(
'list_displays'
)) as Array<[string, string]>) {
displayList.value.push({
title: `${devName.replace('\\\\.\\', '')} (${devString})`,
value: devName,
});
}
}
})
.catch(() => {});
const aimeCodeModel = computed({
get() {
return aimeCode.value;
},
async set(value: string) {
aimeCode.value = value;
if (value.match(/^[0-9]{20}$/)) {
await invoke('write_profile_data', {
path: 'aime.txt',
content: aimeCode.value,
});
}
},
});
</script>
<template>
<OptionCategory title="Display options">
<OptionRow
v-if="capabilities.includes('display')"
title="Target display"
>
<Select
v-model="cfgDisplay"
:options="displayList"
option-label="title"
option-value="value"
></Select>
</OptionRow>
<OptionRow id="resolution" title="Resolution">
<InputNumber
class="shrink"
size="small"
:min="480"
:max="9999"
:use-grouping="false"
v-model="cfgRezW"
/>
x
<InputNumber
class="shrink"
size="small"
:min="640"
:max="9999"
:use-grouping="false"
v-model="cfgRezH"
/>
</OptionRow>
<OptionRow title="Display mode">
<SelectButton
v-model="cfgDisplayMode"
:options="displayModeList"
option-label="title"
option-value="value"
/>
</OptionRow>
<OptionRow
title="Display rotation"
v-if="capabilities.includes('display')"
>
<SelectButton
v-model="cfgDisplayRotation"
:options="displayRotationList"
option-label="title"
option-value="value"
:disabled="cfgDisplay === 'default'"
/>
</OptionRow>
</OptionCategory>
<OptionCategory title="Misc">
<OptionRow title="OpenSSL bug workaround for Intel ≥10th gen">
<Toggle v-model="cfgIntel" />
</OptionRow>
<OptionRow title="Aime emulation">
<Toggle inputId="switch2" v-model="cfgAime" />
</OptionRow>
<OptionRow title="Aime code">
<InputText
class="shrink"
size="small"
:disabled="prf.cfg('aime') !== true"
:maxlength="20"
placeholder="00000000000000000000"
v-model="aimeCodeModel"
/>
</OptionRow>
</OptionCategory>
</template>
<style>
#resolution .p-inputnumber-input {
width: 4rem;
}
.p-inputtext {
font-family: monospace;
}
</style>