FIX - harden phone stability and app controls (#28)

This commit is contained in:
DerEchteAlec
2026-08-22 19:48:30 +02:00
committed by GitHub
parent 2059e19e1c
commit cb6c94a7d8
36 changed files with 651 additions and 181 deletions
@@ -81,6 +81,7 @@ describe('AppStoreApp Sky navigation contract', () => {
expect(source).toContain('@click="profileOpened = true"')
expect(source).toContain('const installedApps = computed')
expect(source).toContain('return !appStore.isInstalled(app.id)')
expect(source).toContain('if (!appStore.isAvailable(app.id)) return false')
expect(source).toContain(
'class="store-account__apps phone-effect--expensive-shadow"',
)
+5 -1
View File
@@ -122,6 +122,7 @@ const catalog = computed(() =>
if (!isLaunchablePhoneApp(app) || app.id === 'app-store' || app.adminOnly) {
return false
}
if (!appStore.isAvailable(app.id)) return false
return !appStore.isInstalled(app.id)
}).sort((a, b) => a.gridOrder - b.gridOrder),
@@ -129,7 +130,9 @@ const catalog = computed(() =>
const installedApps = computed(() =>
PHONE_APPS.filter(
(app): app is LaunchablePhoneAppDefinition =>
isLaunchablePhoneApp(app) && appStore.isInstalled(app.id),
isLaunchablePhoneApp(app) &&
appStore.isAvailable(app.id) &&
appStore.isInstalled(app.id),
).sort((a, b) => a.gridOrder - b.gridOrder),
)
const installedGameCount = computed(
@@ -143,6 +146,7 @@ const dailyCandidates = computed(() =>
!app.adminOnly &&
!isExternalPhoneApp(app) &&
app.id !== 'app-store' &&
appStore.isAvailable(app.id) &&
!DEFAULT_INSTALLED_PHONE_APP_IDS.has(app.id) &&
!appStore.isInstalled(app.id),
),
@@ -369,6 +369,22 @@ describe('VaultX crypto app contracts', () => {
expect(testServer).toContain('function advanceCryptoCycle(')
})
it('does not keep market and settlement workers active while disabled', () => {
expect(server).toContain('local function start_crypto_schedulers()')
expect(server).toMatch(
/start_crypto_schedulers\(\)[\s\S]*?if Config\.Crypto\.Enabled ~= true then\s+return/,
)
expect(server).toContain(
'while scheduler_generation == generation and Config.Crypto.Enabled == true do',
)
expect(server).toContain(
'AddEventHandler("sky_phone:configurator:serverUpdated", refresh_crypto_runtime)',
)
expect(server).not.toMatch(
/CreateThread\(function\(\)\s+while true do\s+Wait\(5 \* 60 \* 1000\)/,
)
})
it('stores cash in price-scale minor units throughout the ledger', () => {
expect(server).toContain(
'local ledger_amount = amount * Config.Crypto.PriceScale',
@@ -6,6 +6,14 @@ const source = readFileSync(
new URL('./DarkChatApp.vue', import.meta.url),
'utf8',
)
const server = readFileSync(
new URL('../../../../sky_phone/source/server/darkchat.lua', import.meta.url),
'utf8',
)
const config = readFileSync(
new URL('../../../../sky_phone/config/config.lua', import.meta.url),
'utf8',
)
describe('DarkChatApp Sky UI contract', () => {
it('uses first-party Sky UI without direct Konsta markup', () => {
@@ -130,4 +138,13 @@ describe('DarkChatApp Sky UI contract', () => {
/\.dc-inbox-navbar :deep\(\.sky-navbar__title-container > div\)\s*\{[^}]*translateY\(-14px\)/s,
)
})
it('cleans expired messages in bounded indexed batches', () => {
expect(config).toContain('CleanupBatchSize = 250')
expect(server).toContain('Config.DarkChat.CleanupBatchSize')
expect(server).toMatch(
/DELETE FROM `sky_phone_darkchat_messages`[\s\S]*?ORDER BY `expires_at`, `id`[\s\S]*?LIMIT \?/,
)
expect(server).toContain(']], { batch_size })')
})
})
@@ -16,6 +16,12 @@ describe('PhoneApp EasyShare contract', () => {
it('uses the shared full-width Sky tab bar for phone sections', () => {
expect(source).toContain('<sky-tab-bar')
expect(source).toContain('<sky-tab-button')
expect(source).toContain(
'calc(var(--sky-tabbar-height) + var(--sky-safe-area-bottom) + 16px);',
)
expect(source).not.toMatch(
/\.phone-contacts\s*\{[^}]*padding-bottom:\s*20px;/s,
)
})
it('uses shared interactive liquid glass surfaces for phone controls', () => {
-1
View File
@@ -2250,7 +2250,6 @@ onBeforeUnmount(() => {
position: relative;
padding-top: 6px;
padding-right: 24px;
padding-bottom: 20px;
}
.phone-contacts-header {