diff --git a/index.js b/index.js index d689463b..6d720428 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,11 @@ import 'react-native-gesture-handler'; import { registerRootComponent } from 'expo'; +import { I18nManager } from 'react-native'; +import { i18n } from './strings/translations'; + +const isRTL = i18n.locale.startsWith('ar') || i18n.locale.startsWith('he'); +I18nManager.allowRTL(isRTL); +I18nManager.forceRTL(isRTL); import App from './App'; diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx index 800c3143..4cd5acac 100644 --- a/src/components/Checkbox/Checkbox.tsx +++ b/src/components/Checkbox/Checkbox.tsx @@ -42,8 +42,8 @@ export const Checkbox: React.FC = ({ status === 'indeterminate' ? 'indeterminate' : status - ? 'checked' - : 'unchecked' + ? 'checked' + : 'unchecked' } onPress={onPress} color={theme.primary} @@ -85,11 +85,11 @@ export const SortItem = ({ label, status, onPress, theme }: SortItemProps) => ( const styles = StyleSheet.create({ defaultLabel: { - marginLeft: 12, + marginStart: 12, }, icon: { alignSelf: 'center', - left: 24, + start: 24, position: 'absolute', }, pressable: { @@ -98,5 +98,5 @@ const styles = StyleSheet.create({ paddingHorizontal: 16, paddingVertical: 6, }, - sortItem: { paddingVertical: 16, paddingLeft: 64 }, + sortItem: { paddingVertical: 16, paddingStart: 64 }, }); diff --git a/src/components/Chip/Chip.tsx b/src/components/Chip/Chip.tsx index ac061951..e412d530 100644 --- a/src/components/Chip/Chip.tsx +++ b/src/components/Chip/Chip.tsx @@ -44,7 +44,7 @@ const styles = StyleSheet.create({ chipContainer: { borderRadius: 8, height: 32, - marginRight: 8, + marginEnd: 8, overflow: 'hidden', }, label: { diff --git a/src/components/ColorPreferenceItem/ColorPreferenceItem.tsx b/src/components/ColorPreferenceItem/ColorPreferenceItem.tsx index d30bee12..a5d8e452 100644 --- a/src/components/ColorPreferenceItem/ColorPreferenceItem.tsx +++ b/src/components/ColorPreferenceItem/ColorPreferenceItem.tsx @@ -37,7 +37,7 @@ const styles = StyleSheet.create({ colorPreview: { borderRadius: 50, height: 24, - marginRight: 16, + marginEnd: 16, width: 24, }, container: { diff --git a/src/components/List/List.tsx b/src/components/List/List.tsx index 119e8a30..160bcea8 100644 --- a/src/components/List/List.tsx +++ b/src/components/List/List.tsx @@ -171,7 +171,7 @@ const styles = StyleSheet.create({ height: 24, width: 24, borderRadius: 50, - marginRight: 16, + marginEnd: 16, }, description: { fontSize: 12, @@ -182,7 +182,7 @@ const styles = StyleSheet.create({ opacity: 0.5, }, iconCtn: { - paddingLeft: 16, + paddingStart: 16, }, infoCtn: { paddingHorizontal: 16, diff --git a/src/components/ListView.tsx b/src/components/ListView.tsx index f60b6727..0dddeebf 100644 --- a/src/components/ListView.tsx +++ b/src/components/ListView.tsx @@ -88,7 +88,7 @@ const styles = StyleSheet.create({ flex: 1, flexWrap: 'wrap', fontSize: 15, - marginLeft: 16, - paddingRight: 8, + marginStart: 16, + paddingEnd: 8, }, }); diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx index cc1e89c5..c748bfc6 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -107,11 +107,7 @@ const Menu: React.FC & { Item: React.FC } = ({ = ({ const styles = StyleSheet.create({ icon: { alignSelf: 'center', - left: 24, + start: 24, position: 'absolute', }, label: { - marginLeft: 12, + marginStart: 12, }, pressable: { alignItems: 'center', diff --git a/src/components/SafeAreaView/SafeAreaView.tsx b/src/components/SafeAreaView/SafeAreaView.tsx index 085d209b..878693e5 100644 --- a/src/components/SafeAreaView/SafeAreaView.tsx +++ b/src/components/SafeAreaView/SafeAreaView.tsx @@ -22,8 +22,8 @@ const SafeAreaView: React.FC = ({ }, padding: { paddingBottom: excludeBottom ? 0 : bottom, - paddingLeft: left, - paddingRight: right, + paddingStart: left, + paddingEnd: right, paddingTop: excludeTop ? 0 : top, }, }); diff --git a/src/components/SearchbarV2/SearchbarV2.tsx b/src/components/SearchbarV2/SearchbarV2.tsx index ca4da104..1e3e2c6a 100644 --- a/src/components/SearchbarV2/SearchbarV2.tsx +++ b/src/components/SearchbarV2/SearchbarV2.tsx @@ -49,8 +49,6 @@ const Searchbar: React.FC = ({ const [extraMenu, showExtraMenu] = useState(false); const marginTop = 8; - const marginRight = 16; - const marginLeft = 16; return ( = ({ styles.searchbarContainer, { marginTop, - marginRight, - marginLeft, backgroundColor: theme.surface2, }, ]} diff --git a/src/components/Switch/SwitchItem.tsx b/src/components/Switch/SwitchItem.tsx index 07273291..da63d180 100644 --- a/src/components/Switch/SwitchItem.tsx +++ b/src/components/Switch/SwitchItem.tsx @@ -72,6 +72,6 @@ const styles = StyleSheet.create({ justifyContent: 'center', }, switch: { - marginLeft: 8, + marginStart: 8, }, }); diff --git a/src/components/ThemePicker/ThemePicker.tsx b/src/components/ThemePicker/ThemePicker.tsx index 35d21d8c..82cfaf89 100644 --- a/src/components/ThemePicker/ThemePicker.tsx +++ b/src/components/ThemePicker/ThemePicker.tsx @@ -151,7 +151,7 @@ const styles = StyleSheet.create({ checkIcon: { position: 'absolute', top: 5, - right: 5, + end: 5, borderRadius: 50, padding: 1.6, zIndex: 1, @@ -164,7 +164,7 @@ const styles = StyleSheet.create({ topBarAccent: { width: 44, height: 10, - marginLeft: 8, + marginStart: 8, borderRadius: 50, }, content: { @@ -186,7 +186,7 @@ const styles = StyleSheet.create({ rowAccentSmall: { height: 10, width: 16, - marginLeft: 4, + marginStart: 4, borderRadius: 50, }, rowAccentShort: { @@ -221,5 +221,5 @@ const styles = StyleSheet.create({ fontSize: 12, paddingVertical: 4, }, - marginLeft: { marginLeft: 4 }, + marginLeft: { marginStart: 4 }, }); diff --git a/src/hooks/common/useGithubUpdateChecker.ts b/src/hooks/common/useGithubUpdateChecker.ts index 5fa22804..99483fcb 100644 --- a/src/hooks/common/useGithubUpdateChecker.ts +++ b/src/hooks/common/useGithubUpdateChecker.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { version } from '../../../package.json'; import { newer } from '@utils/compareVersion'; import { MMKVStorage } from '@utils/mmkv/mmkv'; @@ -30,7 +30,7 @@ export const useGithubUpdateChecker = (): GithubUpdate => { return timeSinceLastCheck >= ONE_DAY_MS; }; - const checkForRelease = async () => { + const checkForRelease = useCallback(async () => { if (!shouldCheckForUpdate()) { setChecking(false); return; @@ -65,11 +65,11 @@ export const useGithubUpdateChecker = (): GithubUpdate => { // Silently fail in offline mode or on network errors setChecking(false); } - }; + }, []); const isNewVersion = (versionTag: string) => { const currentVersion = `${version}`; - const regex = /[^\\d.]/; + const regex = /[^\d.]/; const newVersion = versionTag.replace(regex, ''); @@ -78,7 +78,7 @@ export const useGithubUpdateChecker = (): GithubUpdate => { useEffect(() => { checkForRelease(); - }, []); + }, [checkForRelease]); if (!checking && latestRelease?.tag_name) { return { diff --git a/src/navigators/BottomNavigator.tsx b/src/navigators/BottomNavigator.tsx index 5867c4e1..b31a10a1 100644 --- a/src/navigators/BottomNavigator.tsx +++ b/src/navigators/BottomNavigator.tsx @@ -59,6 +59,18 @@ const BottomNavigator = () => { [], ); + const renderTabBar = useCallback( + (props: any) => ( + + ), + [theme, showLabelsInNav, renderIcon], + ); + return ( ({ @@ -70,14 +82,7 @@ const BottomNavigator = () => { color: theme.onError, }, })} - tabBar={props => ( - - )} + tabBar={renderTabBar} > { { backgroundColor: theme.primary, marginBottom: bottom + 16, - marginRight: right + 16, + marginEnd: right + 16, }, ]} label={getString('common.filter')} @@ -196,6 +196,6 @@ const styles = StyleSheet.create({ bottom: 0, margin: 16, position: 'absolute', - right: 0, + end: 0, }, }); diff --git a/src/screens/BrowseSourceScreen/components/FilterBottomSheet.tsx b/src/screens/BrowseSourceScreen/components/FilterBottomSheet.tsx index 99b093d0..6697656b 100644 --- a/src/screens/BrowseSourceScreen/components/FilterBottomSheet.tsx +++ b/src/screens/BrowseSourceScreen/components/FilterBottomSheet.tsx @@ -175,24 +175,24 @@ const FilterItem: React.FC = ({ {isVisible ? filter.options.map(val => { - return ( - - setSelectedFilters(prevFilters => ({ - ...prevFilters, - [filterKey]: { - type: FilterTypes.CheckboxGroup, - value: insertOrRemoveIntoArray(value, val.value), - }, - })) - } - /> - ); - }) + return ( + + setSelectedFilters(prevFilters => ({ + ...prevFilters, + [filterKey]: { + type: FilterTypes.CheckboxGroup, + value: insertOrRemoveIntoArray(value, val.value), + }, + })) + } + /> + ); + }) : null} ); @@ -255,71 +255,71 @@ const FilterItem: React.FC = ({ {isVisible ? filter.options.map(val => { - return ( - { + if (value.exclude?.includes(val.value)) { + setSelectedFilters(prev => { + return { + ...prev, + [filterKey]: { + type: FilterTypes.ExcludableCheckboxGroup, + value: { + include: [...(value.include || [])], + exclude: [ + ...(value.exclude?.filter( + f => f !== val.value, + ) || []), + ], + }, + }, + }; + }); + } else if (value.include?.includes(val.value)) { + setSelectedFilters(prev => { + return { + ...prev, + [filterKey]: { + type: FilterTypes.ExcludableCheckboxGroup, + value: { + include: [ + ...(value.include?.filter( + f => f !== val.value, + ) || []), + ], + exclude: [...(value.exclude || []), val.value], + }, + }, + }; + }); + } else { + setSelectedFilters(prev => { + return { + ...prev, + [filterKey]: { + type: FilterTypes.ExcludableCheckboxGroup, + value: { + include: [...(value.include || []), val.value], + exclude: value.exclude, + }, + }, + }; + }); } - onPress={() => { - if (value.exclude?.includes(val.value)) { - setSelectedFilters(prev => { - return { - ...prev, - [filterKey]: { - type: FilterTypes.ExcludableCheckboxGroup, - value: { - include: [...(value.include || [])], - exclude: [ - ...(value.exclude?.filter( - f => f !== val.value, - ) || []), - ], - }, - }, - }; - }); - } else if (value.include?.includes(val.value)) { - setSelectedFilters(prev => { - return { - ...prev, - [filterKey]: { - type: FilterTypes.ExcludableCheckboxGroup, - value: { - include: [ - ...(value.include?.filter( - f => f !== val.value, - ) || []), - ], - exclude: [...(value.exclude || []), val.value], - }, - }, - }; - }); - } else { - setSelectedFilters(prev => { - return { - ...prev, - [filterKey]: { - type: FilterTypes.ExcludableCheckboxGroup, - value: { - include: [...(value.include || []), val.value], - exclude: value.exclude, - }, - }, - }; - }); - } - }} - /> - ); - }) + }} + /> + ); + }) : null} ); @@ -350,45 +350,48 @@ const FilterBottomSheet: React.FC = ({ bottomSheetRef={filterSheetRef} snapPoints={[400, 600]} bottomInset={bottom} - backgroundStyle={styles.transparent} - style={[styles.container, { backgroundColor: overlay(2, theme.surface) }]} - handleComponent={() => ( - -