Compare commits
13 Commits
v1.0-alpha
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
f4fb7ebe2b | |
|
|
c49a0150c9 | |
|
|
6967ffa346 | |
|
|
3ad28fad8b | |
|
|
1c9f1b9ce2 | |
|
|
502a5305c2 | |
|
|
955b14ee61 | |
|
|
8333d9a591 | |
|
|
112e4127c1 | |
|
|
13d995edd2 | |
|
|
7918b3d9f9 | |
|
|
318a17b9be | |
|
|
3baba5b4eb |
30
App.tsx
30
App.tsx
|
|
@ -15,7 +15,16 @@ import TitleBar from './components/TitleBar';
|
||||||
import db from './lib/client';
|
import db from './lib/client';
|
||||||
|
|
||||||
const findTheme = async () => {
|
const findTheme = async () => {
|
||||||
const theme = await AsyncStorage.getItem('theme');
|
const res = await db.from("settings").select().eq({id: 'theme'})
|
||||||
|
let theme = 'auto'
|
||||||
|
if (!res.error){
|
||||||
|
if (res.data.length > 0){
|
||||||
|
theme = res.data[0].value
|
||||||
|
}else{
|
||||||
|
const res = await db.from('settings').insert({id: 'theme', value: 'auto'})
|
||||||
|
console.log(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
if(theme === 'dark') {
|
if(theme === 'dark') {
|
||||||
return dark;
|
return dark;
|
||||||
} else if(theme === 'light') {
|
} else if(theme === 'light') {
|
||||||
|
|
@ -35,7 +44,13 @@ const findTheme = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const findThemeMode = async () => {
|
const findThemeMode = async () => {
|
||||||
const theme = await AsyncStorage.getItem('theme');
|
const res = await db.from("settings").select().eq({id:'theme'})
|
||||||
|
let theme = 'auto'
|
||||||
|
if (!res.error){
|
||||||
|
if (res.data.length > 0){
|
||||||
|
theme = res.data[0].value
|
||||||
|
}
|
||||||
|
}
|
||||||
if (theme){
|
if (theme){
|
||||||
return theme;
|
return theme;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -55,7 +70,6 @@ export default function App() {
|
||||||
const [others, setOthers] = useState([]);
|
const [others, setOthers] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const theme = await findTheme();
|
const theme = await findTheme();
|
||||||
|
|
@ -97,22 +111,22 @@ export default function App() {
|
||||||
case 'dark':
|
case 'dark':
|
||||||
setThemeMode('dark');
|
setThemeMode('dark');
|
||||||
setTheme(dark);
|
setTheme(dark);
|
||||||
await AsyncStorage.setItem('theme', 'dark');
|
await db.from("settings").update({value: 'dark'}).eq({id: 'theme'})
|
||||||
break;
|
break;
|
||||||
case 'light':
|
case 'light':
|
||||||
setThemeMode('light');
|
setThemeMode('light');
|
||||||
setTheme(light);
|
setTheme(light);
|
||||||
await AsyncStorage.setItem('theme', 'light');
|
await db.from('settings').update({value: 'light'}).eq({id: 'theme'})
|
||||||
break;
|
break;
|
||||||
case 'solorizedDark':
|
case 'solorizedDark':
|
||||||
setThemeMode('solorizedDark');
|
setThemeMode('solorizedDark');
|
||||||
setTheme(solorizedDark);
|
setTheme(solorizedDark);
|
||||||
await AsyncStorage.setItem('theme', 'solorizedDark');
|
await db.from('settings').update({value: 'solorizedDark'}).eq({id: 'theme'})
|
||||||
break;
|
break;
|
||||||
case 'oled':
|
case 'oled':
|
||||||
setThemeMode('oled');
|
setThemeMode('oled');
|
||||||
setTheme(oled);
|
setTheme(oled);
|
||||||
await AsyncStorage.setItem('theme', 'oled');
|
await db.from('settings').update({value: 'oled'}).eq({id: 'theme'})
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setThemeMode('auto');
|
setThemeMode('auto');
|
||||||
|
|
@ -122,7 +136,7 @@ export default function App() {
|
||||||
} else {
|
} else {
|
||||||
setTheme(light);
|
setTheme(light);
|
||||||
}
|
}
|
||||||
await AsyncStorage.setItem('theme', "auto");
|
await db.from('settings').update({id: 'theme', value: 'auto'}).eq({id: 'theme'})
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
# Tali
|
# Tali
|
||||||
|
|
||||||
React Native app to keep track of movies, tv shows and other interesting stuff you want to watch or do. Gone are the days of using an unorganized note app to keep track of what you want to or already have watched.
|
React Native app to keep track of movies, tv shows and other interesting stuff you want to watch or do. Gone are the days of using an unorganized note app to keep track of what you want to or already have watched.
|
||||||
|
|
||||||
|

|
||||||
|
|
|
||||||
2
app.json
2
app.json
|
|
@ -9,7 +9,7 @@
|
||||||
"splash": {
|
"splash": {
|
||||||
"image": "./assets/splash.png",
|
"image": "./assets/splash.png",
|
||||||
"resizeMode": "contain",
|
"resizeMode": "contain",
|
||||||
"backgroundColor": "#ffffff"
|
"backgroundColor": "#000000"
|
||||||
},
|
},
|
||||||
"assetBundlePatterns": [
|
"assetBundlePatterns": [
|
||||||
"**/*"
|
"**/*"
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 6.0 KiB |
BIN
assets/icon.png
BIN
assets/icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -1,5 +1,5 @@
|
||||||
import nasa from './nasa';
|
import nasa from './nasa';
|
||||||
import { MovieSchema, ShowSchema, TestTableShema, OtherSchema, CategorySchema} from './schemas';
|
import { MovieSchema, ShowSchema, TestTableShema, OtherSchema, CategorySchema, SettingSchema} from './schemas';
|
||||||
|
|
||||||
|
|
||||||
const tableSchemas = {
|
const tableSchemas = {
|
||||||
|
|
@ -7,7 +7,7 @@ const tableSchemas = {
|
||||||
shows: ShowSchema,
|
shows: ShowSchema,
|
||||||
others: OtherSchema,
|
others: OtherSchema,
|
||||||
categories: CategorySchema,
|
categories: CategorySchema,
|
||||||
test: TestTableShema,
|
settings: SettingSchema ,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
28
lib/nasa.ts
28
lib/nasa.ts
|
|
@ -55,13 +55,23 @@ export default class nasa{
|
||||||
let table:any = await AsyncStorage.getItem(this.#tableName);
|
let table:any = await AsyncStorage.getItem(this.#tableName);
|
||||||
if(table){
|
if(table){
|
||||||
table = JSON.parse(table);
|
table = JSON.parse(table);
|
||||||
let maxId = 0;
|
console.log(newData)
|
||||||
table.forEach((s:any)=>{
|
if ('id' in newData){
|
||||||
if(s.id > maxId){
|
table.forEach((s:any)=>{
|
||||||
maxId = s.id;
|
if(s.id === newData.id){
|
||||||
}
|
this.error = 'Id already exists';
|
||||||
});
|
return this
|
||||||
newData.id = maxId + 1;
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
let maxId = 0;
|
||||||
|
table.forEach((s:any)=>{
|
||||||
|
if(s.id > maxId){
|
||||||
|
maxId = s.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
newData.id = maxId + 1;
|
||||||
|
}
|
||||||
const {data, error} = await this.#tableSchemas[this.#tableName].safeParse(newData);
|
const {data, error} = await this.#tableSchemas[this.#tableName].safeParse(newData);
|
||||||
if(error){
|
if(error){
|
||||||
this.error = error.message;
|
this.error = error.message;
|
||||||
|
|
@ -72,7 +82,9 @@ export default class nasa{
|
||||||
this.data = data
|
this.data = data
|
||||||
return this;
|
return this;
|
||||||
}else{
|
}else{
|
||||||
newData.id = 1;
|
if (!('id' in newData)){
|
||||||
|
newData.id = 1;
|
||||||
|
}
|
||||||
const {data, error} = await this.#tableSchemas[this.#tableName].safeParse(newData);
|
const {data, error} = await this.#tableSchemas[this.#tableName].safeParse(newData);
|
||||||
if(error){
|
if(error){
|
||||||
this.error = error.message;
|
this.error = error.message;
|
||||||
|
|
|
||||||
|
|
@ -89,3 +89,9 @@ export const TestTableShema = z.object({
|
||||||
test: z.string(),
|
test: z.string(),
|
||||||
}).strict();
|
}).strict();
|
||||||
export type TestTable = z.infer<typeof TestTableShema>;
|
export type TestTable = z.infer<typeof TestTableShema>;
|
||||||
|
|
||||||
|
export const SettingSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
value: z.string().or(z.boolean().or(z.number()))
|
||||||
|
})
|
||||||
|
export type SettingsTable = z.infer<typeof SettingSchema>
|
||||||
|
|
@ -244,6 +244,12 @@ const style = (theme:any) => {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
|
delete: {
|
||||||
|
color: 'red',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -457,8 +463,8 @@ function EditMovieModal({editMovie, setEdditMovie, update, theme, remove}:any){
|
||||||
value={editMovie.notes}
|
value={editMovie.notes}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{...st.row, width: '90%', marginLeft: 20, justifyContent: "flex-start"}}>
|
<View style={{...st.row, width: '90%', marginLeft: 20, justifyContent: "center"}}>
|
||||||
<Button title="delete" onPress={()=>remove(editMovie.id)} theme={theme} style={{backgroundColor: theme.danger, paddingHorizontal: 25, margin: 0}}/>
|
<Text style={st.delete} onLongPress={()=>remove(editMovie.id)}>long press to delete</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,11 @@ const style = (theme:any) => {
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
},
|
},
|
||||||
|
delete: {
|
||||||
|
color: 'red',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -520,8 +525,8 @@ function EditshowModal({editOther, setEditOther, update, theme, remove, selCat}:
|
||||||
value={editOther.notes}
|
value={editOther.notes}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{...st.row, width: '90%', marginLeft: 20, justifyContent: "flex-start"}}>
|
<View style={{...st.row, width: '90%', marginLeft: 20, justifyContent: "center"}}>
|
||||||
<Button title="delete" onPress={()=>remove(editOther.id)} theme={theme} style={{backgroundColor: theme.danger, paddingHorizontal: 25, margin: 0,}}/>
|
<Text style={st.delete} onLongPress={()=>remove(editor.id)}>long press to delete</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,11 @@ export default function OtherCat({theme, otherCategories, setOtherCategories, se
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
const res = await db.from('categories').delete().eq({id: newCat.id});
|
let res = await db.from('categories').delete().eq({id: newCat.id});
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
setOtherCategories([...otherCategories.filter((c:any) => c.id !== newCat.id)])
|
setOtherCategories([...otherCategories.filter((c:any) => c.id !== newCat.id)])
|
||||||
}
|
}
|
||||||
|
res = await db.from('others').delete().eq({category: newCat.id})
|
||||||
setModalVisible(false);
|
setModalVisible(false);
|
||||||
setNewCat({title: '', showEpisodes: false});
|
setNewCat({title: '', showEpisodes: false});
|
||||||
setEditPop(false);
|
setEditPop(false);
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,10 @@ export default function Settings({theme, changeTheme, themeMode, clearAll, resyn
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
const dataToExport = await db.fileExport()
|
const dataToExport = await db.fileExport()
|
||||||
const data = JSON.stringify(dataToExport);
|
const data = JSON.stringify(dataToExport);
|
||||||
// export dataToExport in json format to a file using react-native-fs
|
|
||||||
if (Platform.OS === 'android') {
|
if (Platform.OS === 'android') {
|
||||||
const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
|
const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
|
||||||
if (permissions.granted) {
|
if (permissions.granted) {
|
||||||
// Gets SAF URI from response
|
|
||||||
const uri = permissions.directoryUri;
|
const uri = permissions.directoryUri;
|
||||||
// Writes file to SAF URI
|
|
||||||
await StorageAccessFramework.createFileAsync(uri, 'tali', 'application/json').then(async (fileUri) => {
|
await StorageAccessFramework.createFileAsync(uri, 'tali', 'application/json').then(async (fileUri) => {
|
||||||
await StorageAccessFramework.writeAsStringAsync(fileUri, data, { encoding: FileSystem.EncodingType.UTF8 }).catch((err) => console.log(err))
|
await StorageAccessFramework.writeAsStringAsync(fileUri, data, { encoding: FileSystem.EncodingType.UTF8 }).catch((err) => console.log(err))
|
||||||
})
|
})
|
||||||
|
|
@ -104,8 +101,8 @@ export default function Settings({theme, changeTheme, themeMode, clearAll, resyn
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{...st.row, zIndex:0}}>
|
<View style={{...st.row, zIndex:0}}>
|
||||||
<Button theme={theme} title="Export Data" onPress={handleExport} style={{padding:30, flex:1}}/>
|
<Button theme={theme} title="Export" onPress={handleExport} style={{padding:30, flex:1}}/>
|
||||||
<Button theme={theme} title="Import Data" onPress={handleImport} style={{padding:30, flex:1}}/>
|
<Button theme={theme} title="Import" onPress={handleImport} style={{padding:30, flex:1}}/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{...st.row, zIndex:0}}>
|
<View style={{...st.row, zIndex:0}}>
|
||||||
<Button theme={theme} title="Delete All Data" onPress={() => setDeleteAllModal(true)} style={{width:'100%'}}/>
|
<Button theme={theme} title="Delete All Data" onPress={() => setDeleteAllModal(true)} style={{width:'100%'}}/>
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,11 @@ const style = (theme:any) => {
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
},
|
},
|
||||||
|
delete: {
|
||||||
|
color: 'red',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -517,8 +522,8 @@ function EditshowModal({editShow, setEditShow, update, theme, remove}:any){
|
||||||
value={editShow.notes}
|
value={editShow.notes}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={{...st.row, width: '90%', marginLeft: 20, justifyContent: "flex-start"}}>
|
<View style={{...st.row, width: '90%', marginLeft: 20, justifyContent: "center"}}>
|
||||||
<Button title="delete" onPress={()=>remove(editShow.id)} theme={theme} style={{backgroundColor: theme.danger, paddingHorizontal: 25, margin: 0,}}/>
|
<Text style={st.delete} onLongPress={()=>remove(editShow.id)}>long press to delete</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue