Add .noMedia setting

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2023-07-11 12:18:33 +03:00
parent 20641666ff
commit 55e22efb66
4 changed files with 54 additions and 5 deletions

View File

@@ -9,11 +9,13 @@ import { Settings } from '../types';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import { LoadingView } from '../components'; import { LoadingView } from '../components';
import WelcomeScreen from '../screens/welcome'; import WelcomeScreen from '../screens/welcome';
import { FileSystem } from 'react-native-file-access'; import { AndroidScoped, FileSystem } from 'react-native-file-access';
import { import {
getPersistedUriPermissions, getPersistedUriPermissions,
openDocumentTree, openDocumentTree,
releasePersistableUriPermission, releasePersistableUriPermission,
createFile,
deleteFile,
} from 'react-native-scoped-storage'; } from 'react-native-scoped-storage';
interface SettingsContextType { interface SettingsContextType {
@@ -28,6 +30,7 @@ const SettingsContext = createContext<SettingsContextType | undefined>(
function SettingsProvider({ children }: { children: ReactNode }) { function SettingsProvider({ children }: { children: ReactNode }) {
const [settings, setSettings] = useState<Settings>({ const [settings, setSettings] = useState<Settings>({
storageUri: '', storageUri: '',
noMedia: false,
}); });
const [hasLoaded, setHasLoaded] = useState(false); const [hasLoaded, setHasLoaded] = useState(false);
@@ -44,13 +47,32 @@ function SettingsProvider({ children }: { children: ReactNode }) {
void AsyncStorage.setItem('storageUri', updatedSettings.storageUri); void AsyncStorage.setItem('storageUri', updatedSettings.storageUri);
void FileSystem.exists(
AndroidScoped.appendPath(updatedSettings.storageUri, '.nomedia'),
).then(noMediaExists => {
if (updatedSettings.noMedia && !noMediaExists) {
void createFile(
updatedSettings.storageUri,
'.nomedia',
'text/x-unknown',
);
} else if (!updatedSettings.noMedia && noMediaExists) {
void deleteFile(
AndroidScoped.appendPath(updatedSettings.storageUri, '.nomedia'),
);
}
});
setSettings(updatedSettings); setSettings(updatedSettings);
}; };
useEffect(() => { useEffect(() => {
const loadSettings = async () => { const loadSettings = async () => {
const storageUriValue = await AsyncStorage.getItem('storageUri'); const storageUriValue = await AsyncStorage.getItem('storageUri');
const noMediaValue = await AsyncStorage.getItem('noMedia');
let storageUri = storageUriValue ?? ''; let storageUri = storageUriValue ?? '';
let noMedia = noMediaValue === 'true';
if (storageUri !== '') { if (storageUri !== '') {
const permissions = await getPersistedUriPermissions(); const permissions = await getPersistedUriPermissions();
@@ -75,10 +97,15 @@ function SettingsProvider({ children }: { children: ReactNode }) {
} catch { } catch {
storageUri = ''; storageUri = '';
} }
noMedia = await FileSystem.exists(
AndroidScoped.appendPath(storageUri, '.nomedia'),
);
} }
setSettings({ setSettings({
storageUri, storageUri,
noMedia,
}); });
setHasLoaded(true); setHasLoaded(true);

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { Button, List, Snackbar } from 'react-native-paper'; import { Button, List, Snackbar, Switch, Text } from 'react-native-paper';
import { useRealm } from '@realm/react'; import { useRealm } from '@realm/react';
import { openDocumentTree } from 'react-native-scoped-storage'; import { openDocumentTree } from 'react-native-scoped-storage';
import { PaddedView } from '../components'; import { PaddedView } from '../components';
@@ -14,7 +14,7 @@ const SettingsScreen = () => {
const [snackbarVisible, setSnackbarVisible] = useState(false); const [snackbarVisible, setSnackbarVisible] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState(''); const [snackbarMessage, setSnackbarMessage] = useState('');
const { setSettings } = useSettings(); const { settings, setSettings } = useSettings();
const realm = useRealm(); const realm = useRealm();
@@ -66,6 +66,20 @@ const SettingsScreen = () => {
}}> }}>
Change External Storage Path Change External Storage Path
</Button> </Button>
<View
style={[
styles.flexRowSpaceBetween,
styles.smallPaddingHorizontal,
styles.marginBottom,
]}>
<Text>Hide media from gallery</Text>
<Switch
value={settings.noMedia}
onValueChange={value => {
setSettings({ noMedia: value });
}}
/>
</View>
</List.Section> </List.Section>
</View> </View>
</PaddedView> </PaddedView>

View File

@@ -12,10 +12,10 @@ const moderateScale = (size: number, factor = 0.5) =>
const styles = StyleSheet.create({ const styles = StyleSheet.create({
marginBottom: { marginBottom: {
marginBottom: verticalScale(5), marginBottom: verticalScale(15),
}, },
bigMarginBottom: { bigMarginBottom: {
marginBottom: verticalScale(25), marginBottom: verticalScale(30),
}, },
extremeMarginBottom: { extremeMarginBottom: {
marginBottom: verticalScale(100), marginBottom: verticalScale(100),
@@ -23,6 +23,9 @@ const styles = StyleSheet.create({
padding: { padding: {
padding: '5%', padding: '5%',
}, },
smallPaddingHorizontal: {
paddingHorizontal: '2.5%',
},
centered: { centered: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
@@ -31,6 +34,10 @@ const styles = StyleSheet.create({
centerText: { centerText: {
textAlign: 'center', textAlign: 'center',
}, },
flexRowSpaceBetween: {
flexDirection: 'row',
justifyContent: 'space-between',
},
}); });
export { horizontalScale, verticalScale, moderateScale, styles as default }; export { horizontalScale, verticalScale, moderateScale, styles as default };

View File

@@ -1,5 +1,6 @@
interface Settings { interface Settings {
storageUri: string; storageUri: string;
noMedia: boolean;
} }
export default Settings; export default Settings;