Add .noMedia setting
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -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);
|
||||||
|
@@ -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>
|
||||||
|
@@ -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 };
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
interface Settings {
|
interface Settings {
|
||||||
storageUri: string;
|
storageUri: string;
|
||||||
|
noMedia: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
Reference in New Issue
Block a user