Add tag datatable
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -23,11 +23,9 @@ import {
|
||||
setFilter,
|
||||
} from '../state';
|
||||
import { MEME_TYPE, memeTypePlural } from '../database';
|
||||
import { useDimensions } from '../contexts';
|
||||
|
||||
const Home = () => {
|
||||
const theme = useTheme();
|
||||
const dimensions = useDimensions();
|
||||
const sort = useSelector((state: RootState) => state.home.sort);
|
||||
const sortDirection = useSelector(
|
||||
(state: RootState) => state.home.sortDirection,
|
||||
@@ -65,9 +63,13 @@ const Home = () => {
|
||||
|
||||
return (
|
||||
<RootScrollView padded>
|
||||
<Searchbar placeholder="Search" value={search} onChangeText={setSearch} />
|
||||
<View style={[styles.flexRowSpaceBetween, styles.centeredVertical]}>
|
||||
<View style={[styles.flexRow, styles.centeredVertical]}>
|
||||
<Searchbar
|
||||
placeholder="Search Memes"
|
||||
value={search}
|
||||
onChangeText={setSearch}
|
||||
/>
|
||||
<View style={[styles.flexRowSpaceBetween, styles.alignCenter]}>
|
||||
<View style={[styles.flexRow, styles.alignCenter]}>
|
||||
<Menu
|
||||
visible={sortMenuVisible}
|
||||
onDismiss={() => setSortMenuVisible(false)}
|
||||
@@ -97,13 +99,13 @@ const Home = () => {
|
||||
<IconButton
|
||||
icon={getViewIcon(view)}
|
||||
iconColor={theme.colors.primary}
|
||||
size={dimensions.static.verticalScale(16)}
|
||||
size={18}
|
||||
onPress={() => dispatch(cycleView())}
|
||||
/>
|
||||
<IconButton
|
||||
icon={favoritesOnly ? 'heart' : 'heart-outline'}
|
||||
iconColor={theme.colors.primary}
|
||||
size={dimensions.static.verticalScale(16)}
|
||||
size={18}
|
||||
onPress={() => dispatch(toggleFavoritesOnly())}
|
||||
/>
|
||||
<Menu
|
||||
@@ -114,7 +116,7 @@ const Home = () => {
|
||||
onPress={() => setFilterMenuVisible(true)}
|
||||
icon={filter ? 'filter' : 'filter-outline'}
|
||||
iconColor={theme.colors.primary}
|
||||
size={dimensions.static.verticalScale(16)}
|
||||
size={18}
|
||||
/>
|
||||
}>
|
||||
<Menu.Item
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import {
|
||||
Button,
|
||||
List,
|
||||
@@ -12,18 +12,20 @@ import { openDocumentTree } from 'react-native-scoped-storage';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { RootScrollView } from '../components';
|
||||
import styles from '../styles';
|
||||
import {
|
||||
RootState,
|
||||
updateNoMedia,
|
||||
updateStorageUri,
|
||||
} from '../state';
|
||||
import { RootState, updateNoMedia, updateStorageUri } from '../state';
|
||||
import type {} from 'redux-thunk/extend-redux';
|
||||
import { useDimensions } from '../contexts';
|
||||
|
||||
const settingsScreenStyles = StyleSheet.create({
|
||||
snackbar: {
|
||||
marginBottom: 90,
|
||||
},
|
||||
});
|
||||
|
||||
const SettingsScreen = () => {
|
||||
const noMedia = useSelector((state: RootState) => state.settings.noMedia);
|
||||
const dispatch = useDispatch();
|
||||
const dimensions = useDimensions();
|
||||
const { responsive } = useDimensions();
|
||||
|
||||
const [optimizingDatabase, setOptimizingDatabase] = useState(false);
|
||||
const [snackbarVisible, setSnackbarVisible] = useState(false);
|
||||
@@ -46,7 +48,7 @@ const SettingsScreen = () => {
|
||||
<Button
|
||||
mode="elevated"
|
||||
style={{
|
||||
marginBottom: dimensions.responsive.verticalScale(15),
|
||||
marginBottom: responsive.verticalScale(15),
|
||||
}}
|
||||
loading={optimizingDatabase}
|
||||
onPress={optimizeDatabase}>
|
||||
@@ -58,7 +60,7 @@ const SettingsScreen = () => {
|
||||
<Button
|
||||
mode="elevated"
|
||||
style={{
|
||||
marginBottom: dimensions.responsive.verticalScale(15),
|
||||
marginBottom: responsive.verticalScale(15),
|
||||
}}
|
||||
onPress={async () => {
|
||||
const { uri } = await openDocumentTree(true);
|
||||
@@ -71,7 +73,7 @@ const SettingsScreen = () => {
|
||||
styles.flexRowSpaceBetween,
|
||||
styles.smallPaddingHorizontal,
|
||||
{
|
||||
marginBottom: dimensions.responsive.verticalScale(15),
|
||||
marginBottom: responsive.verticalScale(15),
|
||||
},
|
||||
]}>
|
||||
<Text>Hide media from gallery</Text>
|
||||
@@ -89,7 +91,7 @@ const SettingsScreen = () => {
|
||||
<Snackbar
|
||||
visible={snackbarVisible}
|
||||
onDismiss={() => setSnackbarVisible(false)}
|
||||
style={{ marginBottom: dimensions.static.verticalScale(75) }}
|
||||
style={settingsScreenStyles.snackbar}
|
||||
action={{
|
||||
label: 'Dismiss',
|
||||
onPress: () => setSnackbarVisible(false),
|
||||
|
@@ -1,22 +1,55 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Button, Text } from 'react-native-paper';
|
||||
import { RootScrollView } from '../components';
|
||||
import React, { useState } from 'react';
|
||||
import { DataTable, HelperText, Searchbar } from 'react-native-paper';
|
||||
import { useQuery, useRealm } from '@realm/react';
|
||||
import { Tag, deleteAllTags } from '../database';
|
||||
import { RootScrollView, TagChip } from '../components';
|
||||
import { Tag, deleteTag } from '../database';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import styles from '../styles';
|
||||
|
||||
const tagStyles = StyleSheet.create({
|
||||
helperText: {
|
||||
marginVertical: 10,
|
||||
},
|
||||
view: {
|
||||
justifyContent: 'center',
|
||||
maxWidth: '75%',
|
||||
},
|
||||
});
|
||||
|
||||
const Tags = () => {
|
||||
const realm = useRealm();
|
||||
const tags = useQuery<Tag>('Tag');
|
||||
|
||||
const [search, setSearch] = useState('');
|
||||
const tags = useQuery<Tag>('Tag').filtered(`name CONTAINS[c] "${search}"`);
|
||||
|
||||
return (
|
||||
<RootScrollView centered padded>
|
||||
{tags.map(tag => (
|
||||
<Text key={tag.id.toHexString()} style={{ color: tag.color }}>
|
||||
{tag.name}
|
||||
</Text>
|
||||
))}
|
||||
<Button onPress={() => deleteAllTags(realm)}>Delete All Tags</Button>
|
||||
<RootScrollView padded style={styles.alignCenter}>
|
||||
<Searchbar
|
||||
placeholder="Search Tags"
|
||||
value={search}
|
||||
onChangeText={setSearch}
|
||||
/>
|
||||
<DataTable>
|
||||
<DataTable.Header>
|
||||
<DataTable.Title>Tag</DataTable.Title>
|
||||
<DataTable.Title numeric>Items</DataTable.Title>
|
||||
</DataTable.Header>
|
||||
{tags.map(tag => (
|
||||
<DataTable.Row
|
||||
key={tag.id.toHexString()}
|
||||
onPress={() => deleteTag(realm, tag)}>
|
||||
<View style={tagStyles.view}>
|
||||
<TagChip tag={tag} />
|
||||
</View>
|
||||
<DataTable.Cell numeric>{tag.memes.length}</DataTable.Cell>
|
||||
</DataTable.Row>
|
||||
))}
|
||||
</DataTable>
|
||||
{tags.length === 0 && (
|
||||
<HelperText type={'info'} style={tagStyles.helperText}>
|
||||
No tags found
|
||||
</HelperText>
|
||||
)}
|
||||
</RootScrollView>
|
||||
);
|
||||
};
|
||||
|
@@ -10,7 +10,7 @@ import { useDimensions } from '../contexts';
|
||||
|
||||
const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dimensions = useDimensions();
|
||||
const { responsive } = useDimensions();
|
||||
|
||||
const selectStorageLocation = async () => {
|
||||
const uri = await openDocumentTree(true).catch(noOp);
|
||||
@@ -25,7 +25,7 @@ const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
||||
variant="displayMedium"
|
||||
style={[
|
||||
{
|
||||
marginBottom: dimensions.responsive.verticalScale(30),
|
||||
marginBottom: responsive.verticalScale(30),
|
||||
},
|
||||
styles.centerText,
|
||||
]}>
|
||||
@@ -35,7 +35,7 @@ const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
||||
mode="contained"
|
||||
onPress={selectStorageLocation}
|
||||
style={{
|
||||
marginBottom: dimensions.responsive.verticalScale(100),
|
||||
marginBottom: responsive.verticalScale(100),
|
||||
}}>
|
||||
Select Storage Location
|
||||
</Button>
|
||||
|
Reference in New Issue
Block a user