From 9bc39731c9268d1e1a66c2c6908687156d5103fc Mon Sep 17 00:00:00 2001 From: Joseph Hale Date: Sun, 22 May 2022 01:52:27 -0700 Subject: [PATCH] Hide BinaryDots that will never be active For example, the dot worth 32 on the portrait screen will never be used in the hours column, so it should be hidden. --- .gitignore | 4 + .vscode/launch.json | 28 +++++ .vscode/settings.json | 18 ++-- package.json | 3 +- src/components/BinaryClock.tsx | 75 ++++++++++---- src/components/BinaryDigit.tsx | 131 +++++++----------------- src/components/BinaryDot.tsx | 23 ++++- src/pages/BinaryClockSettingsScreen.tsx | 37 ++++--- 8 files changed, 179 insertions(+), 140 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.gitignore b/.gitignore index 81570d9..aed7dac 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ # .DS_Store +# VS Code +# +.vscode/.react + # Xcode # build/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2f4bb1a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to packager", + "request": "attach", + "type": "reactnative", + "cwd": "${workspaceFolder}" + }, + { + "name": "Debug iOS", + "request": "launch", + "type": "reactnative", + "cwd": "${workspaceFolder}", + "platform": "ios" + }, + { + "name": "Debug Android", + "request": "launch", + "type": "reactnative", + "cwd": "${workspaceFolder}", + "platform": "android" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 31a9662..144f23b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,12 @@ { - "cSpell.words": [ - "Pressable" - ], - "licenser.author": "Joseph Hale", - "licenser.license": "MPLv2", - "licenser.projectName": "Binary Clock" -} \ No newline at end of file + "cSpell.words": ["Pressable"], + "licenser.author": "Joseph Hale", + "licenser.license": "MPLv2", + "licenser.projectName": "Binary Clock", + "[typescript]": { + "editor.tabSize": 2 + }, + "[typescriptreact]": { + "editor.tabSize": 2 + } +} diff --git a/package.json b/package.json index 7b32920..e5bb67b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "start": "react-native start", "test": "jest", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", - "icons": "react-native-svg-app-icon" + "icons": "react-native-svg-app-icon", + "android-menu": "adb shell input keyevent 82" }, "dependencies": { "@react-native-community/slider": "^4.2.2", diff --git a/src/components/BinaryClock.tsx b/src/components/BinaryClock.tsx index 259b126..b10fdaf 100644 --- a/src/components/BinaryClock.tsx +++ b/src/components/BinaryClock.tsx @@ -10,10 +10,20 @@ import {StyleSheet, View} from 'react-native'; import BinaryDigit from './BinaryDigit'; import Orientation from '../utils/orientation'; -const BinaryClock: React.FC<{ - orientation: Orientation; +interface BinaryClockProps { + orientation?: Orientation; brightness?: number; -}> = ({orientation, brightness = 0.5}) => { + showHints?: boolean; +} + +const BinaryClock: React.FC = args => { + const defaults = { + orientation: Orientation.Landscape, + brightness: 0.5, + showHints: false, + }; + const props = {...defaults, ...args}; + const [time, setTime] = useState(new Date()); useEffect(() => { const toggle = setInterval(() => { @@ -21,33 +31,62 @@ const BinaryClock: React.FC<{ }, 50); return () => clearInterval(toggle); }); + + let digits = []; + let hours = time.getHours(); + let minutes = time.getMinutes(); + let seconds = time.getSeconds(); + switch (props.orientation) { + case Orientation.Portrait: + digits = [ + {key: 'h', value: hours, maxVisible: 23}, + {key: 'm', value: minutes, maxVisible: 59}, + {key: 's', value: seconds, maxVisible: 59}, + ]; + break; + case Orientation.Landscape: + digits = [ + {key: 'h10', value: firstDigit(hours), maxVisible: 2}, + {key: 'h1', value: secondDigit(hours), maxVisible: 9}, + {key: 'm10', value: firstDigit(minutes), maxVisible: 5}, + {key: 'm1', value: secondDigit(minutes), maxVisible: 9}, + {key: 's10', value: firstDigit(seconds), maxVisible: 5}, + {key: 's1', value: secondDigit(seconds), maxVisible: 9}, + ]; + break; + } + let maxValue = Math.max(...digits.map(digit => digit.maxVisible)); + return ( - - - + {digits.map(digit => ( + + ))} ); }; +function firstDigit(value: number) { + return Math.floor(value / 10); +} +function secondDigit(value: number) { + return value % 10; +} + const styles = StyleSheet.create({ binaryClock: { flexDirection: 'row', paddingHorizontal: '5%', height: '100%', backgroundColor: 'black', + alignItems: 'center', }, }); diff --git a/src/components/BinaryDigit.tsx b/src/components/BinaryDigit.tsx index d8d7b23..54c0c72 100644 --- a/src/components/BinaryDigit.tsx +++ b/src/components/BinaryDigit.tsx @@ -8,104 +8,47 @@ import React from 'react'; import {StyleSheet, View} from 'react-native'; import BinaryDot from './BinaryDot'; -import Orientation from '../utils/orientation'; -/* eslint no-bitwise: ["error", { "allow": ["&"] }] */ -const BinaryDigit: React.FC<{ +interface BinaryDigitProps { value: number; - orientation: Orientation; brightness?: number; -}> = ({value, orientation, brightness = 0.5}) => { - switch (orientation) { - case Orientation.Portrait: - return ( - - - 0} - value={32} - brightness={brightness} - /> - 0} - value={16} - brightness={brightness} - /> - 0} - value={8} - brightness={brightness} - /> - 0} - value={4} - brightness={brightness} - /> - 0} - value={2} - brightness={brightness} - /> - 0} - value={1} - brightness={brightness} - /> - - - ); - case Orientation.Landscape: - const firstDigit = Math.floor(value / 10); - const secondDigit = value % 10; - return ( - - - 0} - value={8} - brightness={brightness} - /> - 0} - value={4} - brightness={brightness} - /> - 0} - value={2} - brightness={brightness} - /> - 0} - value={1} - brightness={brightness} - /> - - - 0} - value={8} - brightness={brightness} - /> - 0} - value={4} - brightness={brightness} - /> - 0} - value={2} - brightness={brightness} - /> - 0} - value={1} - brightness={brightness} - /> - - - ); + maxVisible?: number; + maxValue?: number; + showHints?: boolean; +} + +/* eslint no-bitwise: ["error", { "allow": ["&"] }] */ +const BinaryDigit: React.FC = args => { + const defaults = { + brightness: 0.5, + maxVisible: 15, + maxValue: 15, + showHints: false, + }; + const props = {...defaults, ...args}; + + let dotCount = 0; + if (props.maxValue > 0) { + dotCount = Math.floor(Math.log2(props.maxValue)) + 1; } + let dotValues = Array.from(Array(dotCount), (_, i) => 2 ** i); + + return ( + + + {dotValues.reverse().map(value => ( + 0} + visible={props.maxVisible >= value} + value={value} + brightness={props.brightness} + showHints={props.showHints} + /> + ))} + + + ); }; const styles = StyleSheet.create({ diff --git a/src/components/BinaryDot.tsx b/src/components/BinaryDot.tsx index 2511a06..c13d3bf 100644 --- a/src/components/BinaryDot.tsx +++ b/src/components/BinaryDot.tsx @@ -7,17 +7,30 @@ import React from 'react'; import {StyleSheet, View, Text} from 'react-native'; -const BinaryDot: React.FC<{ +interface BinaryDotProps { active: boolean; + visible?: boolean; value?: number; brightness?: number; showHints?: boolean; -}> = ({active, value, brightness = 0.5, showHints = false}) => { +} + +const BinaryDot: React.FC = args => { + const defaults = { + visible: true, + value: 1, + brightness: 1, + showHints: false, + }; + const props = {...defaults, ...args}; + let active_modifier = props.active ? 1 : 0.25; + let visible_modifier = props.visible ? 1 : 0; + let opacity = props.brightness * active_modifier * visible_modifier; return ( - - {showHints && value && ( + + {props.showHints && props.value && ( - {value} + {props.value} )} diff --git a/src/pages/BinaryClockSettingsScreen.tsx b/src/pages/BinaryClockSettingsScreen.tsx index 956ad67..8852629 100644 --- a/src/pages/BinaryClockSettingsScreen.tsx +++ b/src/pages/BinaryClockSettingsScreen.tsx @@ -8,6 +8,7 @@ import Slider from '@react-native-community/slider'; import React from 'react'; import { Button, + SafeAreaView, StyleSheet, Text, useWindowDimensions, @@ -43,22 +44,28 @@ const BinaryClockSettingScreen: React.FC = () => { }); } return ( - width ? 'column' : 'row'}, - ]}> - - + + width ? 'column' : 'row'}, + ]}> + + + + + Brightness + {brightnessString} + +