fix(mobile): list desktop and web devices instead of failing the screen
normalizeRegisteredDevice accepted only android/ios, so one desktop row made the whole Devices screen fail. Accept the server platform list and show the platform on each card.
This commit is contained in:
parent
0a4f5aee64
commit
53fcdf6305
3 changed files with 20 additions and 3 deletions
|
|
@ -27,6 +27,12 @@ describe('device response contract', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('accepts desktop and web devices registered to the same account', () => {
|
||||||
|
for (const platform of ['windows', 'macos', 'web', 'ios'] as const) {
|
||||||
|
expect(normalizeRegisteredDevice({ ...row, platform }).platform).toBe(platform)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
it('rejects missing timestamps and unsupported platforms', () => {
|
it('rejects missing timestamps and unsupported platforms', () => {
|
||||||
expect(() => normalizeRegisteredDevice({ ...row, last_seen_at: 'bad' }))
|
expect(() => normalizeRegisteredDevice({ ...row, last_seen_at: 'bad' }))
|
||||||
.toThrow(DeviceServiceError)
|
.toThrow(DeviceServiceError)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,19 @@
|
||||||
import type { MobileRuntimeConfig } from '../../lib/native-config'
|
import type { MobileRuntimeConfig } from '../../lib/native-config'
|
||||||
import { supabase } from '../../lib/supabase'
|
import { supabase } from '../../lib/supabase'
|
||||||
|
|
||||||
|
/** 서버 devices.platform CHECK 목록과 같다. 데스크톱(windows/macos)도 같은 계정의 기기로 등록된다. */
|
||||||
|
export const DEVICE_PLATFORMS = ['android', 'ios', 'web', 'windows', 'macos'] as const
|
||||||
|
export type DevicePlatform = (typeof DEVICE_PLATFORMS)[number]
|
||||||
|
|
||||||
|
function isDevicePlatform(value: unknown): value is DevicePlatform {
|
||||||
|
return typeof value === 'string' && (DEVICE_PLATFORMS as readonly string[]).includes(value)
|
||||||
|
}
|
||||||
|
|
||||||
export interface RegisteredDevice {
|
export interface RegisteredDevice {
|
||||||
id: string
|
id: string
|
||||||
userId: string
|
userId: string
|
||||||
installationId: string
|
installationId: string
|
||||||
platform: 'android' | 'ios'
|
platform: DevicePlatform
|
||||||
deviceName: string
|
deviceName: string
|
||||||
appVersion: string
|
appVersion: string
|
||||||
osVersion: string | null
|
osVersion: string | null
|
||||||
|
|
@ -43,7 +51,7 @@ export function normalizeRegisteredDevice(value: unknown): RegisteredDevice {
|
||||||
typeof value.id !== 'string'
|
typeof value.id !== 'string'
|
||||||
|| typeof value.user_id !== 'string'
|
|| typeof value.user_id !== 'string'
|
||||||
|| typeof value.installation_id !== 'string'
|
|| typeof value.installation_id !== 'string'
|
||||||
|| (value.platform !== 'android' && value.platform !== 'ios')
|
|| !isDevicePlatform(value.platform)
|
||||||
|| typeof value.device_name !== 'string'
|
|| typeof value.device_name !== 'string'
|
||||||
|| typeof value.app_version !== 'string'
|
|| typeof value.app_version !== 'string'
|
||||||
|| (value.os_version !== null && typeof value.os_version !== 'string')
|
|| (value.os_version !== null && typeof value.os_version !== 'string')
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,10 @@ export default function DevicesScreen(): React.ReactElement {
|
||||||
: t('mobile.devices.active')}
|
: t('mobile.devices.active')}
|
||||||
</ThemeText>
|
</ThemeText>
|
||||||
</View>
|
</View>
|
||||||
<ThemeText variant="small" color="muted">{device.osVersion ?? '—'}</ThemeText>
|
<ThemeText variant="small" color="muted">
|
||||||
|
{t(`mobile.devices.platform.${device.platform}`)}
|
||||||
|
{device.osVersion ? ` · ${device.osVersion}` : ''}
|
||||||
|
</ThemeText>
|
||||||
<ThemeText variant="small" color="muted">
|
<ThemeText variant="small" color="muted">
|
||||||
{t('mobile.devices.version', { version: device.appVersion })}
|
{t('mobile.devices.version', { version: device.appVersion })}
|
||||||
</ThemeText>
|
</ThemeText>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue