feat(release): prepare 1.1.0 candidate
This commit is contained in:
parent
5a34f66981
commit
5205dcdfa9
736 changed files with 115667 additions and 12203 deletions
|
|
@ -1,15 +1,31 @@
|
|||
// src/navigation/TabNavigator.tsx — Bottom tabs: DASH / HIST / REC / TALK / SET
|
||||
import { View, StyleSheet, Pressable, Platform } from 'react-native'
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
|
||||
import { d3roNativePalette } from '@d3ro/ui-native'
|
||||
// src/navigation/TabNavigator.tsx — Bottom tabs: DASH / WORKS / REC / TALK / SET
|
||||
import { View, StyleSheet } from 'react-native'
|
||||
import {
|
||||
BottomTabBar,
|
||||
createBottomTabNavigator,
|
||||
type BottomTabBarProps,
|
||||
} from '@react-navigation/bottom-tabs'
|
||||
import DashScreen from '../screens/DashScreen'
|
||||
import HistoryScreen from '../screens/HistoryScreen'
|
||||
import WorksHubScreen from '../screens/WorksHubScreen'
|
||||
import RecordScreen from '../screens/RecordScreen'
|
||||
import TalkScreen from '../screens/TalkScreen'
|
||||
import SettingsScreen from '../screens/SettingsScreen'
|
||||
import FreeTierBanner from '../components/FreeTierBanner'
|
||||
import { useMobilePreferences } from '../lib/preferences-context'
|
||||
export type MainTabParamList = {
|
||||
Dash: undefined
|
||||
Works: undefined
|
||||
Record: {
|
||||
meetingId?: string;
|
||||
meetingTitle?: string;
|
||||
meetingLanguage?: string;
|
||||
incomingMediaId?: string;
|
||||
} | undefined
|
||||
Talk: undefined
|
||||
Settings: undefined
|
||||
}
|
||||
|
||||
const MONO = Platform.OS === 'ios' ? 'Menlo' : 'monospace'
|
||||
const Tab = createBottomTabNavigator()
|
||||
const Tab = createBottomTabNavigator<MainTabParamList>()
|
||||
|
||||
function TabIcon({ type, color }: { type: string; color: string }): React.ReactElement {
|
||||
if (type === 'dash') {
|
||||
|
|
@ -21,10 +37,12 @@ function TabIcon({ type, color }: { type: string; color: string }): React.ReactE
|
|||
</View>
|
||||
)
|
||||
}
|
||||
if (type === 'hist') {
|
||||
if (type === 'works') {
|
||||
return (
|
||||
<View style={[iconStyles.circle, { borderColor: color }]}>
|
||||
<View style={[iconStyles.hand, { backgroundColor: color }]} />
|
||||
<View style={[iconStyles.rows, { borderColor: color }]}>
|
||||
{[0, 1, 2].map((i) => (
|
||||
<View key={i} style={[iconStyles.rowsLine, { backgroundColor: color }]} />
|
||||
))}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
|
@ -38,35 +56,56 @@ function TabIcon({ type, color }: { type: string; color: string }): React.ReactE
|
|||
}
|
||||
|
||||
function RecordFAB(): React.ReactElement {
|
||||
const { palette } = useMobilePreferences()
|
||||
return (
|
||||
<View style={fabStyles.fab}>
|
||||
<View
|
||||
style={[
|
||||
fabStyles.fab,
|
||||
{
|
||||
backgroundColor: palette.accent.main,
|
||||
borderColor: palette.bg.app,
|
||||
shadowColor: palette.accent.main,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<View style={fabStyles.micIcon}>
|
||||
<View style={fabStyles.micBody} />
|
||||
<View style={fabStyles.micBase} />
|
||||
<View style={[fabStyles.micBody, { backgroundColor: palette.bg.app }]} />
|
||||
<View style={[fabStyles.micBase, { backgroundColor: palette.bg.app }]} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
function FreeTierTabBar(props: BottomTabBarProps): React.ReactElement {
|
||||
const { palette } = useMobilePreferences()
|
||||
return (
|
||||
<View style={{ backgroundColor: palette.bg.sidebar }}>
|
||||
<FreeTierBanner />
|
||||
<BottomTabBar {...props} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default function TabNavigator(): React.ReactElement {
|
||||
const { palette } = useMobilePreferences()
|
||||
return (
|
||||
<Tab.Navigator
|
||||
tabBar={(props) => <FreeTierTabBar {...props} />}
|
||||
screenOptions={{
|
||||
// 높이/패딩은 react-navigation 기본값(세이프에어리어 자동 반영,
|
||||
// 콘텐츠 수직 균형 포함)을 쓴다 — 커스텀 height 지정은 폴드 등
|
||||
// 큰 인셋 기기에서 콘텐츠가 상단에 몰리는 회귀를 일으켰다.
|
||||
tabBarStyle: {
|
||||
backgroundColor: 'rgba(25, 25, 27, 0.95)',
|
||||
borderTopColor: d3roNativePalette.border.default,
|
||||
backgroundColor: palette.bg.sidebar,
|
||||
borderTopColor: palette.border.default,
|
||||
borderTopWidth: 1,
|
||||
height: 80,
|
||||
paddingBottom: 20,
|
||||
paddingTop: 8,
|
||||
},
|
||||
tabBarActiveTintColor: d3roNativePalette.accent.main,
|
||||
tabBarInactiveTintColor: d3roNativePalette.text.muted,
|
||||
tabBarActiveTintColor: palette.accent.main,
|
||||
tabBarInactiveTintColor: palette.text.muted,
|
||||
tabBarLabelStyle: {
|
||||
fontFamily: MONO,
|
||||
fontSize: 9,
|
||||
fontSize: 11,
|
||||
fontWeight: '500',
|
||||
letterSpacing: 0.5,
|
||||
letterSpacing: 0.2,
|
||||
},
|
||||
headerShown: false,
|
||||
}}
|
||||
|
|
@ -76,15 +115,17 @@ export default function TabNavigator(): React.ReactElement {
|
|||
component={DashScreen}
|
||||
options={{
|
||||
title: 'DASH',
|
||||
tabBarButtonTestID: 'tab-dash',
|
||||
tabBarIcon: ({ color }) => <TabIcon type="dash" color={color} />,
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="History"
|
||||
component={HistoryScreen}
|
||||
name="Works"
|
||||
component={WorksHubScreen}
|
||||
options={{
|
||||
title: 'HIST',
|
||||
tabBarIcon: ({ color }) => <TabIcon type="hist" color={color} />,
|
||||
title: 'WORKS',
|
||||
tabBarButtonTestID: 'tab-works',
|
||||
tabBarIcon: ({ color }) => <TabIcon type="works" color={color} />,
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
|
|
@ -92,6 +133,7 @@ export default function TabNavigator(): React.ReactElement {
|
|||
component={RecordScreen}
|
||||
options={{
|
||||
title: '',
|
||||
tabBarButtonTestID: 'tab-record',
|
||||
tabBarIcon: () => <RecordFAB />,
|
||||
tabBarLabel: () => null,
|
||||
}}
|
||||
|
|
@ -101,6 +143,7 @@ export default function TabNavigator(): React.ReactElement {
|
|||
component={TalkScreen}
|
||||
options={{
|
||||
title: 'TALK',
|
||||
tabBarButtonTestID: 'tab-talk',
|
||||
tabBarIcon: ({ color }) => <TabIcon type="talk" color={color} />,
|
||||
}}
|
||||
/>
|
||||
|
|
@ -109,6 +152,7 @@ export default function TabNavigator(): React.ReactElement {
|
|||
component={SettingsScreen}
|
||||
options={{
|
||||
title: 'SET',
|
||||
tabBarButtonTestID: 'tab-settings',
|
||||
tabBarIcon: ({ color }) => <TabIcon type="set" color={color} />,
|
||||
}}
|
||||
/>
|
||||
|
|
@ -119,8 +163,11 @@ export default function TabNavigator(): React.ReactElement {
|
|||
const iconStyles = StyleSheet.create({
|
||||
grid: { width: 22, height: 22, flexDirection: 'row', flexWrap: 'wrap', gap: 2 },
|
||||
gridCell: { width: 9, height: 9, borderWidth: 1.5, borderRadius: 2 },
|
||||
circle: { width: 22, height: 22, borderRadius: 11, borderWidth: 1.5, justifyContent: 'center', alignItems: 'center' },
|
||||
hand: { width: 1.5, height: 7, position: 'absolute', top: 3 },
|
||||
rows: {
|
||||
width: 22, height: 22, borderWidth: 1.5, borderRadius: 5,
|
||||
alignItems: 'center', justifyContent: 'center', gap: 2.5,
|
||||
},
|
||||
rowsLine: { width: 11, height: 1.5, borderRadius: 1 },
|
||||
chat: { width: 22, height: 18, borderWidth: 1.5, borderRadius: 4 },
|
||||
gear: { width: 22, height: 22, borderWidth: 1.5, borderRadius: 11 },
|
||||
})
|
||||
|
|
@ -132,18 +179,15 @@ const fabStyles = StyleSheet.create({
|
|||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 28,
|
||||
backgroundColor: d3roNativePalette.accent.main,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
shadowColor: d3roNativePalette.accent.main,
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0.4,
|
||||
shadowRadius: 10,
|
||||
elevation: 8,
|
||||
borderWidth: 4,
|
||||
borderColor: d3roNativePalette.bg.app,
|
||||
},
|
||||
micIcon: { alignItems: 'center' },
|
||||
micBody: { width: 8, height: 14, borderRadius: 4, backgroundColor: d3roNativePalette.bg.app, marginBottom: 2 },
|
||||
micBase: { width: 14, height: 2, borderRadius: 1, backgroundColor: d3roNativePalette.bg.app },
|
||||
micBody: { width: 8, height: 14, borderRadius: 4, marginBottom: 2 },
|
||||
micBase: { width: 14, height: 2, borderRadius: 1 },
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue