diff --git a/src/components/AutoOrientingClock.tsx b/src/components/AutoOrientingClock.tsx
new file mode 100644
--- /dev/null
+++ b/src/components/AutoOrientingClock.tsx
@@ -0,0 +1,55 @@
+// Copyright (c) 2025 Joseph Hale
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import { useState } from "react";
+import { useSettings } from "../settings/useSettings";
+import Orientation from "../utils/orientation";
+import { StyleSheet, View } from "react-native";
+import BinaryClock from "./BinaryClock";
+
+
+export default function AutoOrientingClock({ lastAspectUpdate }: { lastAspectUpdate: Date }) {
+ const [settings] = useSettings('AutoOrientingClock');
+ const [layout, setLayout] = useState({
+ height: 0,
+ width: 0,
+ date: new Date(0),
+ });
+ const showClock =
+ layout.height > 0 &&
+ layout.width > 0 &&
+ layout.date.getTime() > lastAspectUpdate.getTime();
+ const orientation =
+ layout.height > layout.width ? Orientation.Portrait : Orientation.Landscape;
+ return (
+ {
+ setLayout({
+ height: nativeEvent.layout.height,
+ width: nativeEvent.layout.width,
+ date: new Date(),
+ });
+ }}>
+ {!showClock ? (
+
+ ) : (
+
+ )}
+
+ );
+}
+
+const styles = StyleSheet.create({
+ blankClock: {
+ height: '100%',
+ backgroundColor: 'black',
+ }
+})
\ No newline at end of file
diff --git a/src/pages/BinaryClockScreen.tsx b/src/pages/BinaryClockScreen.tsx
--- a/src/pages/BinaryClockScreen.tsx
+++ b/src/pages/BinaryClockScreen.tsx
@@ -1,154 +1,59 @@
-// Copyright (c) 2022 Joseph Hale
+// Copyright (c) 2022 - 2025 Joseph Hale
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
import {
Pressable,
SafeAreaView,
- ScrollView,
StyleSheet,
View,
- useWindowDimensions,
+ useWindowDimensions
} from 'react-native';
-import React, {useCallback, useState} from 'react';
+import React, { useCallback, useState } from 'react';
-import BinaryClock from '../components/BinaryClock';
-import Orientation from '../utils/orientation';
-import SettingBoolean from '../components/settings/SettingBoolean';
-import SettingRange from '../components/settings/SettingRange';
-import { useSettings } from '../settings/useSettings';
+import AutoOrientingClock from '../components/AutoOrientingClock';
+import SettingsScrollView from '../components/settings/SettingsScrollView';
-const BinaryClockScreen: React.FC = () => {
- const [showSettings, setShowSettings] = useState<{
- value: boolean;
- updated: Date;
- }>({value: false, updated: new Date()});
- const toggleSettings = useCallback(
- () => setShowSettings({value: !showSettings.value, updated: new Date()}),
- [showSettings],
- );
- const {height, width} = useWindowDimensions();
- const [settings, updateSetting] = useSettings('BinaryClockScreen');
- const brightnessString = `${Math.round(settings.brightness * 100)}%`;
- const roundnessString = `${Math.round(settings.roundness * 100)}%`;
+function BinaryClockScreen() {
+ const [settingsVisibility, toggleSettingsVisibility] = useSettingsVisibility();
+
+ const { height, width } = useWindowDimensions();
+ const flexStyle = { flexDirection: height > width ? 'column' : 'row' } as const
+
return (
- width ? 'column' : 'row'},
- ]}>
-
-
+
+
+
- {showSettings.value && (
-
- updateSetting({brightness: value})}
- caption={brightnessString}
- />
- updateSetting({roundness: value})}
- caption={roundnessString}
- />
- updateSetting({showHints: value})}
- initialValue={settings.showHints}
- />
-
+ {settingsVisibility.value && (
+
+
+
)}
);
};
-function Clock({
- brightness,
- roundness,
- showHints,
- lastAspectUpdate,
-}: {
- brightness: number;
- roundness: number;
- showHints: boolean;
- lastAspectUpdate: Date;
-}) {
- const [layout, setLayout] = useState({
- height: 0,
- width: 0,
- date: new Date(0),
- });
- const showClock =
- layout.height > 0 &&
- layout.width > 0 &&
- layout.date.getTime() > lastAspectUpdate.getTime();
- const orientation =
- layout.height > layout.width ? Orientation.Portrait : Orientation.Landscape;
- return (
- {
- setLayout({
- height: nativeEvent.layout.height,
- width: nativeEvent.layout.width,
- date: new Date(),
- });
- }}>
- {!showClock ? (
-
- ) : (
-
- )}
-
+function useSettingsVisibility() {
+ const [visibility, setVisibility] = useState<{
+ value: boolean;
+ updated: Date;
+ }>({ value: false, updated: new Date() });
+ const toggleVisibility = useCallback(
+ () => setVisibility({ value: !visibility.value, updated: new Date() }),
+ [visibility],
);
+ return [visibility, toggleVisibility] as const;
}
const styles = StyleSheet.create({
- container: {
- height: '100%',
- },
- clockPreview: {
- flex: 2,
- },
- blankClock: {
- height: '100%',
- backgroundColor: 'black',
- },
- settingsContainer: {
- flex: 3,
- },
- settingsContentContainer: {
- padding: 20,
- justifyContent: 'flex-start',
- },
- label: {
- fontSize: 20,
- fontWeight: 'bold',
- marginBottom: 10,
- },
- description: {
- marginBottom: 10,
- },
+ container: { height: '100%' },
+ clock: { flex: 5 },
+ settings: { flex: 2 },
});
export default BinaryClockScreen;
diff --git a/src/components/settings/SettingsScrollView.tsx b/src/components/settings/SettingsScrollView.tsx
new file mode 100644
--- /dev/null
+++ b/src/components/settings/SettingsScrollView.tsx
@@ -0,0 +1,46 @@
+// Copyright (c) 2025 Joseph Hale
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import { ScrollView, StyleSheet } from "react-native";
+import { useSettings } from "../../settings/useSettings";
+import SettingRange from "./SettingRange";
+import SettingBoolean from "./SettingBoolean";
+
+
+export default function SettingsScrollView() {
+ const [settings, updateSetting] = useSettings('SettingsScrollView');
+ const brightnessString = `${Math.round(settings.brightness * 100)}%`;
+ const roundnessString = `${Math.round(settings.roundness * 100)}%`;
+ return (
+
+ updateSetting({ brightness: value })}
+ caption={brightnessString}
+ />
+ updateSetting({ roundness: value })}
+ caption={roundnessString}
+ />
+ updateSetting({ showHints: value })}
+ initialValue={settings.showHints}
+ />
+
+ )
+}
+
+const styles = StyleSheet.create({
+ contentContainer: {
+ padding: 20,
+ justifyContent: 'flex-start',
+ },
+})
\ No newline at end of file