Skip to content

Commit da7e3ae

Browse files
Add device info (#9)
### Added device info menu for the expo project
1 parent f73d0c6 commit da7e3ae

File tree

8 files changed

+279
-0
lines changed

8 files changed

+279
-0
lines changed

.editorconfig

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# http://editorconfig.org
2+
# Properties: https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties
3+
4+
root = true
5+
6+
[*]
7+
charset = utf-8
8+
indent_style = space
9+
indent_size = 4
10+
insert_final_newline = true
11+
trim_trailing_whitespace = true
12+
end_of_line = lf
13+
14+
# Use 2 spaces for the HTML files
15+
[*.{html,svg}]
16+
indent_size = 2
17+
18+
[*.{js,jsx,ts,tsx}]
19+
indent_size = 4
20+
quote_type = single
21+
curly_bracket_next_line = false
22+
spaces_around_operators = true
23+
spaces_around_brackets = outside
24+
indent_brace_style = K&R
25+
26+
27+
# The JSON files contain newlines inconsistently
28+
[*.json]
29+
indent_style = space
30+
indent_size = 2
31+
insert_final_newline = false
32+
33+
# Minified JavaScript files shouldn't be changed
34+
[**.min.js]
35+
indent_style = ignore
36+
insert_final_newline = false
37+
38+
# Makefiles always use tabs for indentation
39+
[Makefile]
40+
indent_style = tab
41+
indent_size = 8
42+
43+
# Batch files use tabs for indentation
44+
[*.bat]
45+
indent_style = tab
46+
47+
[**.txt]
48+
max_line_length = 79
49+
50+
[*.md]
51+
trim_trailing_whitespace = false
52+
53+
[*.less]
54+
indent_size = 4
55+
56+
[*.{yml,yaml}]
57+
indent_size = 2
58+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
export interface DeviceInfo {
2+
brand: string | null;
3+
manufacturer: string | null;
4+
deviceName: string | null;
5+
modelId: string | null;
6+
modelName: string | null;
7+
osName: string | null;
8+
osVersion: string | null;
9+
osBuildId: string | null;
10+
osInternalBuildId: string | null;
11+
deviceType: string | null;
12+
deviceYearClass: number | null;
13+
isDevice: boolean | null;
14+
supportedCpuArchitectures: string[] | null;
15+
totalMemory: number | null;
16+
uptime: string | null;
17+
isJailBroken: boolean | null;
18+
}
19+
20+
export const DEVICE_INFO_FIELDS: {
21+
title: string;
22+
identifier: keyof DeviceInfo;
23+
}[] = [
24+
{ title: 'Brand', identifier: 'brand' },
25+
{ title: 'Manufacturer', identifier: 'manufacturer' },
26+
{ title: 'Device Name', identifier: 'deviceName' },
27+
{ title: 'Model ID', identifier: 'modelId' },
28+
{ title: 'Model Name', identifier: 'modelName' },
29+
{ title: 'OS Name', identifier: 'osName' },
30+
{ title: 'OS Version', identifier: 'osVersion' },
31+
{ title: 'OS Build ID', identifier: 'osBuildId' },
32+
{ title: 'OS Internal Build ID', identifier: 'osInternalBuildId' },
33+
{ title: 'Device Type', identifier: 'deviceType' },
34+
{ title: 'Device Year Class', identifier: 'deviceYearClass' },
35+
{ title: 'Physical Device', identifier: 'isDevice' },
36+
{
37+
title: 'Supported CPU Architectures',
38+
identifier: 'supportedCpuArchitectures',
39+
},
40+
{ title: 'Total Memory (Bytes)', identifier: 'totalMemory' },
41+
{ title: 'Uptime', identifier: 'uptime' },
42+
{ title: 'Jail Broken', identifier: 'isJailBroken' },
43+
];

features/expo/deviceInfo/enums.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export enum DeviceType {
2+
UNKNOWN = 0,
3+
PHONE = 1,
4+
TABLET = 2,
5+
DESKTOP = 3,
6+
TV = 4,
7+
}

features/expo/deviceInfo/hooks.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { useEffect, useState } from 'react';
2+
3+
import { enumToStr } from '../../../utils/enum';
4+
import * as Device from 'expo-device';
5+
import { DateTime } from 'luxon';
6+
7+
import { DeviceInfo } from './constants';
8+
import { DeviceType } from './enums';
9+
10+
export const useDeviceInfo = () => {
11+
const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>({
12+
brand: null,
13+
manufacturer: null,
14+
deviceName: null,
15+
modelId: null,
16+
modelName: null,
17+
osName: null,
18+
osVersion: null,
19+
osBuildId: null,
20+
osInternalBuildId: null,
21+
deviceType: null,
22+
deviceYearClass: null,
23+
isDevice: null,
24+
supportedCpuArchitectures: null,
25+
totalMemory: null,
26+
uptime: null,
27+
isJailBroken: null,
28+
});
29+
30+
useEffect(() => {
31+
const fetchDeviceInfo = () => {
32+
Device.getDeviceTypeAsync()
33+
.then((deviceType) => {
34+
if (deviceType) {
35+
setDeviceInfo((prev) => ({
36+
...prev,
37+
deviceType: enumToStr(DeviceType, deviceType),
38+
}));
39+
}
40+
})
41+
.catch((error) => {
42+
console.error('Failed to fetch device type:', error);
43+
});
44+
45+
Device.getUptimeAsync()
46+
.then((uptime) => {
47+
if (uptime) {
48+
setDeviceInfo((prev) => ({
49+
...prev,
50+
uptime: DateTime.fromMillis(uptime).toFormat(
51+
'hh:mm:ss'
52+
),
53+
}));
54+
}
55+
})
56+
.catch((error) => {
57+
console.error('Failed to fetch uptime:', error);
58+
});
59+
60+
Device.isRootedExperimentalAsync()
61+
.then((isJailBroken) => {
62+
if (isJailBroken !== null) {
63+
setDeviceInfo((prev) => ({ ...prev, isJailBroken }));
64+
}
65+
})
66+
.catch((error) => {
67+
console.error(
68+
'Failed to check if device is rooted:',
69+
error
70+
);
71+
});
72+
73+
setDeviceInfo((prev) => ({
74+
...prev,
75+
brand: Device.brand,
76+
manufacturer: Device.manufacturer,
77+
deviceName: Device.deviceName,
78+
modelId: Device.modelId,
79+
modelName: Device.modelName,
80+
osName: Device.osName,
81+
osVersion: Device.osVersion,
82+
osBuildId: Device.osBuildId,
83+
osInternalBuildId: Device.osInternalBuildId,
84+
deviceYearClass: Device.deviceYearClass,
85+
isDevice: Device.isDevice,
86+
supportedCpuArchitectures: Device.supportedCpuArchitectures,
87+
totalMemory: Device.totalMemory,
88+
}));
89+
};
90+
91+
fetchDeviceInfo();
92+
}, []);
93+
94+
return deviceInfo;
95+
};

features/expo/deviceInfo/index.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
3+
import { Card, Text, View } from 'react-native-ui-lib';
4+
5+
import { useDeviceInfo } from '../../../features/expo/deviceInfo/hooks';
6+
7+
import { Dividers } from '../../../utils/theme';
8+
9+
import { DEVICE_INFO_FIELDS } from './constants';
10+
11+
export function ExpoDeviceInfo() {
12+
const deviceInfo = useDeviceInfo();
13+
14+
return (
15+
<Card padding-s4 gap-s4 marginV-s4 marginH-s4>
16+
{DEVICE_INFO_FIELDS.map(({ title, identifier }, index) => (
17+
<View
18+
key={identifier}
19+
gap-s2
20+
paddingT-s2
21+
style={index !== 0 && Dividers.top1}
22+
>
23+
<Text text70>{title}</Text>
24+
<View>
25+
<Text>
26+
{deviceInfo[identifier] !== null
27+
? deviceInfo[identifier]?.toString()
28+
: 'N/A'}
29+
</Text>
30+
</View>
31+
</View>
32+
))}
33+
</Card>
34+
);
35+
}

utils/enum/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { snakeCaseToCapitalize } from '../string';
2+
3+
export function enumToStr(enumObj: any, val: number): string {
4+
let name = enumObj[val] as string;
5+
return snakeCaseToCapitalize(name);
6+
}

utils/string/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function capitalize(name: string): string {
2+
return `${name.charAt(0).toUpperCase()}${name.slice(1).toLowerCase()}`;
3+
}
4+
5+
export function snakeCaseToCapitalize(name: string): string {
6+
return name.split('_').map(capitalize).join(' ');
7+
}

utils/theme/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Colors } from 'react-native-ui-lib';
2+
3+
export const Dividers = {
4+
get right1() {
5+
return {
6+
borderRightWidth: 1,
7+
borderColor: Colors.$outlineDefault,
8+
};
9+
},
10+
get left1() {
11+
return {
12+
borderLeftWidth: 1,
13+
borderColor: Colors.$outlineDefault,
14+
};
15+
},
16+
get bottom1() {
17+
return {
18+
borderBottomWidth: 1,
19+
borderColor: Colors.$outlineDefault,
20+
};
21+
},
22+
get top1() {
23+
return {
24+
borderTopWidth: 1,
25+
borderColor: Colors.$outlineDefault,
26+
};
27+
},
28+
};

0 commit comments

Comments
 (0)