Merge branch 'dev' into feature/funk

This commit is contained in:
Alec Schitzkat
2026-08-09 02:25:24 +02:00
7 changed files with 448 additions and 49 deletions
@@ -0,0 +1,31 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="Settings">
<defs>
<linearGradient id="settings-bg" x1="18" y1="8" x2="111" y2="121" gradientUnits="userSpaceOnUse">
<stop stop-color="#c8ccd3"/>
<stop offset="0.48" stop-color="#858b96"/>
<stop offset="1" stop-color="#505660"/>
</linearGradient>
<linearGradient id="settings-gear" x1="38" y1="31" x2="89" y2="98" gradientUnits="userSpaceOnUse">
<stop stop-color="#ffffff"/>
<stop offset="1" stop-color="#e7e9ee"/>
</linearGradient>
<filter id="settings-shadow" x="15" y="15" width="98" height="98" filterUnits="userSpaceOnUse">
<feDropShadow dx="0" dy="3" stdDeviation="3" flood-color="#20242b" flood-opacity=".32"/>
</filter>
</defs>
<rect width="128" height="128" rx="29" fill="url(#settings-bg)"/>
<path d="M12 34C30 17 52 10 80 13c18 2 30 9 38 18v-2C118 13 105 0 89 0H29C13 0 0 13 0 29v25c2-7 6-14 12-20Z" fill="#ffffff" fill-opacity=".18"/>
<g fill="url(#settings-gear)" filter="url(#settings-shadow)">
<rect x="57" y="20" width="14" height="27" rx="6"/>
<rect x="57" y="81" width="14" height="27" rx="6"/>
<rect x="81" y="57" width="27" height="14" rx="6"/>
<rect x="20" y="57" width="27" height="14" rx="6"/>
<rect x="76" y="25" width="14" height="29" rx="6" transform="rotate(45 83 39.5)"/>
<rect x="38" y="74" width="14" height="29" rx="6" transform="rotate(45 45 88.5)"/>
<rect x="74" y="76" width="29" height="14" rx="6" transform="rotate(45 88.5 83)"/>
<rect x="25" y="38" width="29" height="14" rx="6" transform="rotate(45 39.5 45)"/>
<circle cx="64" cy="64" r="34"/>
</g>
<circle cx="64" cy="64" r="15" fill="#626873"/>
<circle cx="64" cy="64" r="11" fill="#747a85" stroke="#ffffff" stroke-opacity=".35" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

+161 -35
View File
@@ -111,6 +111,9 @@ const forecastLow = computed(() =>
const weatherIcon = computed(
() => weatherIcons[weather.forecast.value?.condition ?? 'partly_cloudy'],
)
const visibleHourlyWeather = computed(
() => weather.forecast.value?.hourly.slice(0, 5) ?? [],
)
const balance = computed(() =>
props.instance.settings.balanceSource === 'cash'
? bank.overview.value.cash
@@ -148,6 +151,13 @@ function avatar(name: string): string {
return name.trim().charAt(0).toLocaleUpperCase(phone.lang) || '?'
}
function formatForecastHour(timestamp: number): string {
return new Intl.DateTimeFormat(phone.lang, {
hour: '2-digit',
minute: '2-digit',
}).format(timestamp)
}
function clearHold(): void {
if (holdTimer !== undefined) window.clearTimeout(holdTimer)
holdTimer = undefined
@@ -326,6 +336,13 @@ onBeforeUnmount(() => {
<small v-if="instance.size !== 'small'" class="widget-weather-range">
H: {{ forecastHigh ?? '--' }}° &nbsp; L: {{ forecastLow ?? '--' }}°
</small>
<div v-if="instance.size !== 'small'" class="widget-weather-hourly">
<div v-for="hour in visibleHourlyWeather" :key="hour.timestamp">
<time>{{ formatForecastHour(hour.timestamp) }}</time>
<component :is="weatherIcons[hour.condition]" :size="21" />
<strong>{{ hour.temperature }}°</strong>
</div>
</div>
</template>
<template v-else-if="instance.kind === 'music'">
@@ -492,30 +509,46 @@ onBeforeUnmount(() => {
.home-widget {
width: 100%;
height: 100%;
padding: 14px;
padding: 15px;
overflow: hidden;
border: 0.5px solid rgb(255 255 255 / 18%);
border-radius: 22px;
border: 0.75px solid rgb(255 255 255 / 17%);
border-radius: 25px;
outline: none;
color: #fff;
background: rgb(28 28 30 / 76%);
background: rgb(25 25 27 / 91%);
box-shadow:
0 8px 24px rgb(0 0 0 / 24%),
inset 0 0.5px rgb(255 255 255 / 18%);
0 10px 25px rgb(0 0 0 / 28%),
inset 0 0.75px rgb(255 255 255 / 15%);
backdrop-filter: blur(26px) saturate(125%);
-webkit-backdrop-filter: blur(26px) saturate(125%);
cursor: pointer;
font-family:
-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text',
'Segoe UI', sans-serif;
user-select: none;
-webkit-user-select: none;
touch-action: none;
}
.home-widget-shell--small .home-widget {
padding: 13px;
border-radius: 23px;
}
.home-widget-shell--large .home-widget {
padding: 18px;
border-radius: 28px;
}
.home-widget:active {
filter: brightness(1.08);
}
.home-widget small,
.widget-eyebrow {
color: rgb(255 255 255 / 68%);
color: rgb(255 255 255 / 62%);
font-size: 11px;
font-weight: 500;
line-height: 1.25;
}
@@ -528,25 +561,30 @@ onBeforeUnmount(() => {
justify-content: flex-end;
}
.home-widget--clock {
background: rgb(12 12 13 / 94%);
}
.widget-clock {
margin: 1px 0;
font-size: 31px;
font-weight: 400;
letter-spacing: -1.6px;
margin: 2px 0;
font-size: 28px;
font-weight: 500;
letter-spacing: -1.8px;
line-height: 1;
white-space: nowrap;
}
.home-widget-shell--medium .widget-clock {
font-size: 45px;
font-size: 48px;
}
.home-widget--date {
background: rgb(247 247 247 / 88%);
color: #111;
background: rgb(24 24 26 / 94%);
color: #fff;
}
.home-widget--date small {
color: #6e6e73;
color: rgb(255 255 255 / 58%);
}
.widget-date-month {
@@ -557,8 +595,8 @@ onBeforeUnmount(() => {
}
.widget-date-day {
font-size: 48px;
font-weight: 300;
font-size: 52px;
font-weight: 400;
letter-spacing: -2px;
line-height: 0.95;
}
@@ -567,7 +605,7 @@ onBeforeUnmount(() => {
display: flex;
flex-direction: column;
justify-content: space-between;
background: rgb(25 69 112 / 82%);
background: rgb(34 42 78 / 95%);
}
.widget-weather-top {
@@ -582,14 +620,72 @@ onBeforeUnmount(() => {
}
.widget-weather-top strong {
font-size: 34px;
font-weight: 300;
font-size: 38px;
font-weight: 400;
letter-spacing: -1.5px;
line-height: 1;
}
.widget-weather-range {
margin-top: 4px;
margin-top: 3px;
color: rgb(255 255 255 / 86%) !important;
font-weight: 600 !important;
}
.widget-weather-hourly {
display: grid;
margin-top: 12px;
padding-top: 11px;
grid-template-columns: repeat(5, minmax(0, 1fr));
border-top: 0.5px solid rgb(255 255 255 / 18%);
}
.widget-weather-hourly > div {
display: grid;
min-width: 0;
justify-items: center;
gap: 6px;
}
.widget-weather-hourly time {
color: rgb(255 255 255 / 58%);
font-size: 9px;
font-weight: 600;
}
.widget-weather-hourly strong {
font-size: 12px;
font-weight: 650;
}
.home-widget-shell--medium .home-widget--weather {
padding: 13px 15px;
}
.home-widget-shell--medium .widget-weather-top strong {
font-size: 32px;
}
.home-widget-shell--medium .widget-weather-hourly {
margin-top: 7px;
padding-top: 7px;
}
.home-widget-shell--medium .widget-weather-hourly > div {
gap: 3px;
}
.home-widget-shell--medium .widget-weather-hourly svg {
width: 18px;
height: 18px;
}
.home-widget-shell--medium .widget-weather-hourly time {
font-size: 8px;
}
.home-widget-shell--medium .widget-weather-hourly strong {
font-size: 11px;
}
.home-widget--music {
@@ -597,6 +693,7 @@ onBeforeUnmount(() => {
align-items: center;
grid-template-columns: auto minmax(0, 1fr) auto;
gap: 12px;
background: rgb(25 25 28 / 94%);
}
.home-widget-shell--large .home-widget--music {
@@ -610,10 +707,12 @@ onBeforeUnmount(() => {
width: 58px;
height: 58px;
place-items: center;
border-radius: 13px;
border-radius: 14px;
color: #fff;
background: #b33a3a;
box-shadow: inset 0 0 0 0.5px rgb(255 255 255 / 22%);
background: #5653b8;
box-shadow:
inset 0 0 0 0.5px rgb(255 255 255 / 25%),
0 5px 13px rgb(0 0 0 / 24%);
font-size: 13px;
font-weight: 800;
letter-spacing: 1.5px;
@@ -640,6 +739,10 @@ onBeforeUnmount(() => {
white-space: nowrap;
}
.widget-music-copy strong {
font-size: 13px;
}
.widget-music-controls {
display: flex;
align-items: center;
@@ -655,7 +758,11 @@ onBeforeUnmount(() => {
border: 0;
border-radius: 50%;
color: #fff;
background: rgb(255 255 255 / 13%);
background: rgb(255 255 255 / 11%);
}
.home-widget--wallet {
background: rgb(25 26 29 / 94%);
}
.widget-wallet-icon {
@@ -667,14 +774,14 @@ onBeforeUnmount(() => {
height: 36px;
place-items: center;
border-radius: 11px;
color: #0a84ff;
background: rgb(10 132 255 / 15%);
color: #64d2ff;
background: rgb(100 210 255 / 13%);
}
.widget-balance {
margin: 2px 0;
font-size: 28px;
font-weight: 600;
font-size: 30px;
font-weight: 650;
letter-spacing: -1.2px;
}
@@ -684,14 +791,26 @@ onBeforeUnmount(() => {
flex-direction: column;
}
.home-widget--transactions {
background: rgb(29 29 31 / 94%);
}
.home-widget--contacts {
background: rgb(25 26 29 / 94%);
}
.widget-list-header {
display: flex;
margin-bottom: 7px;
align-items: center;
justify-content: space-between;
color: rgb(255 255 255 / 72%);
font-size: 12px;
font-weight: 600;
color: #64d2ff;
font-size: 13px;
font-weight: 700;
}
.home-widget--transactions .widget-list-header {
color: #30d158;
}
.widget-transaction {
@@ -701,7 +820,7 @@ onBeforeUnmount(() => {
align-items: center;
justify-content: space-between;
border: 0;
border-top: 0.5px solid rgb(255 255 255 / 12%);
border-top: 0.5px solid rgb(255 255 255 / 11%);
color: #fff;
background: transparent;
text-align: left;
@@ -715,6 +834,12 @@ onBeforeUnmount(() => {
.widget-transaction strong {
font-size: 12px;
font-weight: 650;
}
.widget-transaction small {
margin-top: 1px;
font-size: 9px;
}
.widget-transaction b {
@@ -756,6 +881,7 @@ onBeforeUnmount(() => {
border-radius: 50%;
color: #fff;
background: #5e5ce6;
box-shadow: inset 0 1px rgb(255 255 255 / 20%);
font-size: 16px;
font-weight: 650;
}
@@ -784,8 +910,8 @@ onBeforeUnmount(() => {
.widget-contacts button {
width: 25px;
height: 25px;
color: #0a84ff;
background: rgb(10 132 255 / 14%);
color: #64d2ff;
background: rgb(100 210 255 / 12%);
}
.home-widget-remove {
+1 -1
View File
@@ -41,7 +41,7 @@ import notesIcon from '@/assets/img/app-icons/notes.webp'
import radioIcon from '@/assets/img/app-icons/radio.svg'
import photosIcon from '@/assets/img/app-icons/gallery.webp'
import phoneIcon from '@/assets/img/app-icons/phone.webp'
import settingsIcon from '@/assets/img/app-icons/settings.webp'
import settingsIcon from '@/assets/img/app-icons/settings.svg'
import snakeIcon from '@/assets/img/app-icons/snake.webp'
import memoryIcon from '@/assets/img/app-icons/memory.webp'
import numberMergeIcon from '@/assets/img/app-icons/number-merge.webp'
+1
View File
@@ -49,6 +49,7 @@ export function useClockService() {
time: computed(() =>
new Intl.DateTimeFormat(phone.lang, {
hour: '2-digit',
hour12: false,
minute: '2-digit',
}).format(now.value),
),
+21 -4
View File
@@ -1511,6 +1511,17 @@ const defaultLocales: LocaleTree = {
general: 'General Settings',
security: 'Passcode & Security',
appearance: 'Appearance',
connectivity: 'Connectivity',
connections: 'Connections',
wifi: 'Wi-Fi',
bluetooth: 'Bluetooth',
cellular: 'Cellular',
connectivityDescription:
'Airplane Mode temporarily disables wireless connections. Wi-Fi, Bluetooth, and cellular settings are saved on this phone.',
focus: 'Focus',
focusMode: 'Focus',
focusDescription:
'Focus silences non-critical notifications while keeping alarms and important alerts available.',
allowNotifications: 'Allow Notifications',
notificationSounds: 'Sounds',
notificationDuration: 'Notification Duration',
@@ -1525,6 +1536,8 @@ const defaultLocales: LocaleTree = {
dark: 'Dark',
phoneScale: 'Phone Scale',
phoneFrame: 'Phone Frame',
screenBrightness: 'Screen Brightness',
rotationLock: 'Rotation Lock',
about: 'About',
deviceName: 'Device Name',
deviceNameValue: 'Sky Phone',
@@ -1591,6 +1604,11 @@ const defaultLocales: LocaleTree = {
toggle: {
airplaneMode: 'Toggle Airplane Mode',
streamerMode: 'Toggle Streamer Mode',
focusMode: 'Toggle Focus',
wifiEnabled: 'Toggle Wi-Fi',
bluetoothEnabled: 'Toggle Bluetooth',
cellularEnabled: 'Toggle Cellular Data',
rotationLocked: 'Toggle Rotation Lock',
notifications: 'Toggle notifications for {app}',
notificationSounds: 'Toggle notification sounds for {app}',
},
@@ -1896,10 +1914,9 @@ export const usePhoneStore = defineStore('phone', {
async unlockWithPasscode(
passcode: string,
): Promise<NuiResponse<PasscodeResponseData>> {
const response = await nuiCall<PasscodeResponseData>(
'security:unlock',
{ passcode },
)
const response = await nuiCall<PasscodeResponseData>('security:unlock', {
passcode,
})
if (response.success && response.data?.security) {
this.security = response.data.security
}
+226 -8
View File
@@ -24,17 +24,22 @@ import {
} from 'konsta/vue'
import {
BellRing,
Bluetooth,
Check,
EyeOff,
KeyRound,
Monitor,
Moon,
Plane,
RotateCcw,
RotateCw,
Settings,
Signal,
Smartphone,
Sun,
UserRound,
Volume2,
Wifi,
} from 'lucide-vue-next'
import {
computed,
@@ -81,10 +86,18 @@ type SettingsView =
| 'notifications'
| 'notification-detail'
| 'sounds'
| 'connectivity'
| 'focus'
| 'general'
| 'appearance'
| 'wallpaper'
type RootToggleKey = 'airplaneMode' | 'streamerMode'
type RootToggleKey =
| 'airplaneMode'
| 'streamerMode'
| 'focusMode'
| 'wifiEnabled'
| 'bluetoothEnabled'
| 'cellularEnabled'
type SubmenuView = Exclude<SettingsView, 'root' | 'notification-detail'>
type PasscodeFlow =
| 'set-new'
@@ -171,6 +184,18 @@ const serviceRows = [
},
]
const preferenceRows = [
{
key: 'connectivity',
view: 'connectivity' as const,
icon: Wifi,
iconColor: '#007aff',
},
{
key: 'focus',
view: 'focus' as const,
icon: Moon,
iconColor: '#5856d6',
},
{
key: 'security',
view: 'security' as const,
@@ -197,6 +222,27 @@ const preferenceRows = [
},
]
const connectivityRows = [
{
key: 'wifi',
preferenceKey: 'wifiEnabled' as const,
icon: Wifi,
iconColor: '#007aff',
},
{
key: 'bluetooth',
preferenceKey: 'bluetoothEnabled' as const,
icon: Bluetooth,
iconColor: '#007aff',
},
{
key: 'cellular',
preferenceKey: 'cellularEnabled' as const,
icon: Signal,
iconColor: '#34c759',
},
]
const normalizedQuery = computed(() => query.value.trim().toLowerCase())
const visibleToggleRows = computed(() =>
toggleRows.filter((row) => matchesSearch(row.key)),
@@ -233,7 +279,10 @@ const passcodeTitle = computed(() => {
if (passcodeFlow.value === 'set-confirm') {
return phone.t('Apps.settings.passcode.confirmNew')
}
if (passcodeFlow.value === 'change-current' || passcodeFlow.value === 'disable') {
if (
passcodeFlow.value === 'change-current' ||
passcodeFlow.value === 'disable'
) {
return phone.t('Apps.settings.passcode.enterCurrent')
}
if (passcodeFlow.value === 'change-confirm') {
@@ -402,7 +451,8 @@ function updateNumberPreference(
| 'notificationDurationSeconds'
| 'notificationVolume'
| 'phoneScale'
| 'ringtoneVolume',
| 'ringtoneVolume'
| 'screenBrightness',
event: Event,
): void {
phone.setPreference(
@@ -700,10 +750,11 @@ onBeforeUnmount(() => {
<component :is="row.icon" :size="17" :stroke-width="2.25" />
</span>
</template>
<template v-if="row.key === 'security'" #after>
<template v-if="row.key === 'security' || row.key === 'focus'" #after>
{{
phone.t(
phone.security.enabled
(row.key === 'security' && phone.security.enabled) ||
(row.key === 'focus' && phone.preferences.settings.focusMode)
? 'Apps.settings.on'
: 'Apps.settings.off',
)
@@ -714,7 +765,13 @@ onBeforeUnmount(() => {
</template>
<template v-else>
<k-navbar :title="activeTitle" class="top-0 sticky z-20">
<k-navbar
:title="activeTitle"
:class="[
'settings-detail-navbar sticky z-20',
{ 'settings-detail-navbar--dark': phone.isDarkMode },
]"
>
<template #left>
<k-navbar-back-link
component="button"
@@ -879,7 +936,9 @@ onBeforeUnmount(() => {
</k-block>
<template v-if="!phone.security.enabled">
<k-block-title>{{ phone.t('Apps.settings.passcode.codeLength') }}</k-block-title>
<k-block-title>{{
phone.t('Apps.settings.passcode.codeLength')
}}</k-block-title>
<k-block>
<k-segmented strong rounded>
<k-segmented-button
@@ -920,7 +979,9 @@ onBeforeUnmount(() => {
"
/>
</k-list>
<k-block-title>{{ phone.t('Apps.settings.passcode.codeLength') }}</k-block-title>
<k-block-title>{{
phone.t('Apps.settings.passcode.codeLength')
}}</k-block-title>
<k-block>
<k-segmented strong rounded>
<k-segmented-button
@@ -1132,6 +1193,80 @@ onBeforeUnmount(() => {
</k-list>
</template>
<template v-else-if="activeView === 'connectivity'">
<k-list strong inset>
<k-list-item :title="phone.t('Apps.settings.airplaneMode')">
<template #media>
<span class="settings-row-icon bg-[#ff9500]">
<Plane :size="17" :stroke-width="2.25" />
</span>
</template>
<template #after>
<k-toggle
:checked="phone.preferences.settings.airplaneMode"
:aria-label="phone.t('Apps.settings.toggle.airplaneMode')"
@change="toggleRootSetting('airplaneMode')"
/>
</template>
</k-list-item>
</k-list>
<k-block-title>{{
phone.t('Apps.settings.connections')
}}</k-block-title>
<k-list strong inset>
<k-list-item
v-for="row in connectivityRows"
:key="row.key"
:title="phone.t(`Apps.settings.${row.key}`)"
>
<template #media>
<span
class="settings-row-icon"
:style="{ backgroundColor: row.iconColor }"
>
<component :is="row.icon" :size="17" :stroke-width="2.25" />
</span>
</template>
<template #after>
<k-toggle
:checked="phone.preferences.settings[row.preferenceKey]"
:disabled="phone.preferences.settings.airplaneMode"
:aria-label="
phone.t(`Apps.settings.toggle.${row.preferenceKey}`)
"
@change="toggleRootSetting(row.preferenceKey)"
/>
</template>
</k-list-item>
</k-list>
<k-block class="text-sm leading-5 opacity-60">
{{ phone.t('Apps.settings.connectivityDescription') }}
</k-block>
</template>
<template v-else-if="activeView === 'focus'">
<k-list strong inset>
<k-list-item :title="phone.t('Apps.settings.focusMode')">
<template #media>
<span class="settings-row-icon bg-[#5856d6]">
<Moon :size="17" :stroke-width="2.25" />
</span>
</template>
<template #after>
<k-toggle
:checked="phone.preferences.settings.focusMode"
:aria-label="phone.t('Apps.settings.toggle.focusMode')"
@change="toggleRootSetting('focusMode')"
/>
</template>
</k-list-item>
</k-list>
<k-block class="text-sm leading-5 opacity-60">
{{ phone.t('Apps.settings.focusDescription') }}
</k-block>
</template>
<template v-else-if="activeView === 'general'">
<k-block-title>
{{ phone.t('Apps.settings.notificationDuration') }} ·
@@ -1243,6 +1378,48 @@ onBeforeUnmount(() => {
</k-list-item>
</k-list>
<k-block-title>
{{ phone.t('Apps.settings.screenBrightness') }} ·
{{ phone.preferences.settings.screenBrightness }}%
</k-block-title>
<k-list strong inset>
<k-list-item>
<template #inner>
<div class="flex w-full items-center gap-3">
<Sun :size="16" class="shrink-0 opacity-55" />
<k-range
class="w-full"
:value="phone.preferences.settings.screenBrightness"
:min="10"
:max="100"
:aria-label="phone.t('Apps.settings.screenBrightness')"
@input="updateNumberPreference('screenBrightness', $event)"
/>
<Sun :size="23" class="shrink-0" />
</div>
</template>
</k-list-item>
<k-list-item :title="phone.t('Apps.settings.rotationLock')">
<template #media>
<span class="settings-row-icon bg-[#ff9500]">
<RotateCw :size="17" :stroke-width="2.25" />
</span>
</template>
<template #after>
<k-toggle
:checked="phone.preferences.settings.rotationLocked"
:aria-label="phone.t('Apps.settings.toggle.rotationLocked')"
@change="
phone.setPreference(
'rotationLocked',
!phone.preferences.settings.rotationLocked,
)
"
/>
</template>
</k-list-item>
</k-list>
<k-block-title>
{{ phone.t('Apps.settings.phoneScale') }} ·
{{ phone.preferences.settings.phoneScale }}%
@@ -1456,3 +1633,44 @@ onBeforeUnmount(() => {
{{ accountToast }}
</k-toast>
</template>
<style scoped>
.settings-row-icon {
display: flex;
width: 28px;
height: 28px;
flex-shrink: 0;
align-items: center;
justify-content: center;
border-radius: 7px;
color: #fff;
box-shadow:
inset 0 1px 0 rgb(255 255 255 / 35%),
0 1px 2px rgb(0 0 0 / 25%);
}
.settings-detail-navbar {
top: 0 !important;
background: rgb(248 248 248 / 94%);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
}
.settings-detail-navbar::before {
position: absolute;
right: 0;
bottom: 100%;
left: 0;
height: 44px;
background: rgb(248 248 248);
content: '';
}
.settings-detail-navbar--dark {
background: rgb(0 0 0 / 94%);
}
.settings-detail-navbar--dark::before {
background: #000;
}
</style>
+7 -1
View File
@@ -609,10 +609,14 @@ Locales["en"] = {
accountStorage = "Cloud Storage", accountStorageValue = "On Device", accountPurchases = "Media & Purchases",
accountPurchasesValue = "Available", notifications = "Notifications", sounds = "Sounds & Haptics",
general = "General Settings", security = "Passcode & Security", appearance = "Appearance", allowNotifications = "Allow Notifications",
connectivity = "Connectivity", connections = "Connections", wifi = "Wi-Fi", bluetooth = "Bluetooth", cellular = "Cellular",
connectivityDescription = "Airplane Mode temporarily disables wireless connections. Wi-Fi, Bluetooth, and cellular settings are saved on this phone.",
focus = "Focus", focusMode = "Focus", focusDescription = "Focus silences non-critical notifications while keeping alarms and important alerts available.",
notificationSounds = "Sounds", notificationDuration = "Notification Duration", seconds = "{seconds} seconds",
ringtoneVolume = "Ringtone Volume", notificationVolume = "Notification Volume",
ringtone = "Ringtone", notificationSound = "Notification Sound", appearanceMode = "Appearance Mode",
automatic = "Automatic", light = "Light", dark = "Dark", phoneScale = "Phone Scale", phoneFrame = "Phone Frame",
screenBrightness = "Screen Brightness", rotationLock = "Rotation Lock",
about = "About", deviceName = "Device Name", deviceNameValue = "Sky Phone", softwareVersion = "Software Version",
language = "Language", languageValue = "English", localStorage = "Local Storage", localStorageValue = "On Device",
back = "Settings", wallpaperPicker = "Built-in Wallpapers", deviceInformation = "Device Information",
@@ -638,7 +642,9 @@ Locales["en"] = {
device_not_found = "That device is no longer linked.", default = "The account request failed.",
},
toggle = {
airplaneMode = "Toggle Airplane Mode", streamerMode = "Toggle Streamer Mode",
airplaneMode = "Toggle Airplane Mode", streamerMode = "Toggle Streamer Mode", focusMode = "Toggle Focus",
wifiEnabled = "Toggle Wi-Fi", bluetoothEnabled = "Toggle Bluetooth", cellularEnabled = "Toggle Cellular Data",
rotationLocked = "Toggle Rotation Lock",
notifications = "Toggle notifications for {app}", notificationSounds = "Toggle notification sounds for {app}",
},
frames = { black = "Black", blue = "Blue", green = "Green", lavender = "Lavender", white = "White" },