Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add settings screen #2

Merged
merged 8 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions app/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,16 @@ export default function HackerNewsPageDetail() {
<SafeAreaView style={[styles.container, { backgroundColor: backgroundColor }]}>
<StatusBar barStyle={isDarkMode ? "light-content" : "dark-content"} />
<Header
isMainPage={false}
title={undefined}
showLoginIcon={false}
showOptionsIcon={false}
showBackIcon={true}
details={{
url: searchParamAsString(url),
story: searchParamAsString(story),
title: searchParamAsString(title)}} />
title: searchParamAsString(title),
}}
/>
<View style={styles.webViewContainer}>
{ searchParamAsString(url) &&
<WebView
Expand Down
7 changes: 6 additions & 1 deletion app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ export default function Index() {
return (
<SafeAreaView style={[styles.container, { backgroundColor: theme.background }]}>
<StatusBar barStyle={scheme === 'dark' ? "light-content" : "dark-content"} />
<Header isMainPage={true} details={undefined} />
<Header
title='HN-10'
showLoginIcon={true}
showOptionsIcon={true}
showBackIcon={false}
details={undefined} />
<View style={styles.content}>
<HackerNewsPage numberOfStories={10} onDataFetched={() => {}} onStorySelected={handleStorySelected} client={client} />
</View>
Expand Down
122 changes: 122 additions & 0 deletions app/settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { useState } from 'react';
import { View, Text, StyleSheet, Switch, TouchableOpacity, Alert, SafeAreaView, StatusBar, Appearance } from 'react-native';
import { useColorScheme } from 'react-native';
import { useThemeColor } from "@/utils/Colors";
import { Feather } from '@expo/vector-icons';
import Header from '@/components/Header';

export default function SettingsPage() {
const colorScheme = useColorScheme();
const [isDarkMode, setIsDarkMode] = useState(colorScheme === 'dark');
const [selectedBrowser, setSelectedBrowser] = useState('in-app');

const backgroundColor = useThemeColor(colorScheme, 'background');
const textColor = useThemeColor(colorScheme, 'text');
const cardColor = useThemeColor(colorScheme, 'card');
const tintColor = useThemeColor(colorScheme, 'tint');

const toggleDarkMode = () => {
const newMode = !isDarkMode;
setIsDarkMode(newMode);
Appearance.setColorScheme(newMode ? 'dark' : 'light');
};

const changeBrowser = (browser) => {
setSelectedBrowser(browser);
// Implement logic to change default browser
};

const handleTip = () => {
Alert.alert(
"Support the Developer",
"Thank you for considering a tip! This will open the in-app purchase flow.",
[
{ text: "Cancel", style: "cancel" },
{ text: "Proceed", onPress: () => {
// Implement in-app purchase logic here
console.log("Initiate in-app purchase");
}}
]
);
};

return (
<SafeAreaView style={[styles.container, { backgroundColor: backgroundColor }]}>
<StatusBar barStyle={isDarkMode ? "light-content" : "dark-content"} />
<Header
title='Settings'
showLoginIcon={false}
showOptionsIcon={false}
showBackIcon={true}
details={undefined} />
<View style={[styles.container, { backgroundColor }]}>
<View style={[styles.section, { backgroundColor: cardColor }]}>
<Text style={[styles.sectionTitle, { color: textColor }]}>Appearance</Text>
<View style={styles.setting}>
<Text style={[styles.settingText, { color: textColor }]}>Dark Mode</Text>
<Switch value={isDarkMode} onValueChange={toggleDarkMode} />
</View>
</View>

<View style={[styles.section, { backgroundColor: cardColor }]}>
<Text style={[styles.sectionTitle, { color: textColor }]}>Browser</Text>
{['in-app', 'google', 'safari'].map((browser) => (
<TouchableOpacity
key={browser}
style={styles.setting}
onPress={() => changeBrowser(browser)}
>
<Text style={[styles.settingText, { color: textColor }]}>{browser}</Text>
{selectedBrowser === browser && <Feather name="check" size={24} color={tintColor} />}
</TouchableOpacity>
))}
</View>

<TouchableOpacity style={[styles.tipButton, { backgroundColor: tintColor }]} onPress={handleTip}>
<Text style={styles.tipButtonText}>Buy Me a Coffee</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 16,
},
section: {
marginBottom: 24,
borderRadius: 8,
padding: 16,
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
setting: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 8,
},
settingText: {
fontSize: 16,
},
tipButton: {
padding: 16,
borderRadius: 8,
alignItems: 'center',
},
tipButtonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
});
63 changes: 34 additions & 29 deletions components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import { LoginContext } from "./LoginProvider";
import LoginModal from "./LoginModal";

type Props = {
isMainPage: boolean
title: string | undefined
showBackIcon: boolean
showLoginIcon: boolean
showOptionsIcon: boolean
details: {
url: string | undefined;
story: string | undefined;
Expand All @@ -40,14 +43,14 @@ const Header: React.FC<Props> = (props) => {
}, [navigation]);

const renderBackButton = () =>
props.isMainPage ? null : (
props.showBackIcon ? (
<TouchableOpacity
onPress={() => navigation.goBack()}
style={styles.backButton}
>
<Feather name="arrow-left" size={24} color={tintColor} />
</TouchableOpacity>
);
) : null;

const renderStoryNumber = () => {
if (props.details && props.details.story && props.details.story.trim()) {
Expand All @@ -62,18 +65,20 @@ const Header: React.FC<Props> = (props) => {
}

const renderTitle = () => {
const titleText = (text: string) =>
<Text
style={[styles.headerTitle, { color: textColor }]}
numberOfLines={1}
>
{text}
</Text>
if (props.title && props.title.trim()) {
return titleText(props.title.trim());
}
if (props.details && props.details.title && props.details.title.trim()) {
return (
<Text
style={[styles.headerTitle, { color: textColor }]}
numberOfLines={1}
>
{props.details.title}
</Text>
)
} else {
return (null);
return titleText(props.details.title.trim());
}
return (null);
}

const renderSubtitle = () => {
Expand All @@ -91,25 +96,25 @@ const Header: React.FC<Props> = (props) => {
}
}

const renderHeaderText = () =>
props.isMainPage ? (
const renderHeaderText = () => {
if (props.title && props.title.trim()) {
return (
<View style={styles.headerTextContainer}>
<Text
style={[styles.headerTitle, { color: textColor }]}
numberOfLines={1}
>
HN-10
</Text>
</View>
) : (
<View style={styles.headerTextContainer}>
{renderStoryNumber()}
<View>
{renderTitle()}
{renderSubtitle()}
</View>
</View>
);
)
} else {
return (
<View style={styles.headerTextContainer}>
{renderStoryNumber()}
<View>
{renderTitle()}
{renderSubtitle()}
</View>
</View>
)
}
};

return (
<View>
Expand Down
Loading