Images, unified action bars

This commit is contained in:
Niklas Korz 2024-01-02 23:34:17 +01:00
parent 6390d56470
commit 9187461ed4
11 changed files with 599 additions and 234 deletions

View file

@ -27,7 +27,7 @@ const linking = {
Task: "tasks/:taskId",
},
},
Notifications: "notifications",
History: "history",
Profile: "profile",
},
},

533
app/package-lock.json generated
View file

@ -13,6 +13,7 @@
"@expo/webpack-config": "^19.0.0",
"@react-native-masked-view/masked-view": "0.2.9",
"@react-navigation/drawer": "^6.6.6",
"@react-navigation/elements": "^1.3.21",
"@react-navigation/native": "^6.1.9",
"@react-navigation/stack": "^6.3.20",
"expo": "~49.0.15",
@ -40,7 +41,7 @@
"@types/react": "~18.2.14",
"patch-package": "^8.0.0",
"postinstall-postinstall": "^2.1.0",
"sharp-cli": "^4.2.0",
"sharp-cli": "^2.1.0",
"typescript": "^5.1.3"
}
},
@ -7182,12 +7183,6 @@
"node": ">= 4.0.0"
}
},
"node_modules/b4a": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
"integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==",
"dev": true
},
"node_modules/babel-core": {
"version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@ -8193,6 +8188,15 @@
"node": ">=6"
}
},
"node_modules/code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
@ -10286,12 +10290,6 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
"dev": true
},
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@ -11361,6 +11359,15 @@
"loose-envify": "^1.0.0"
}
},
"node_modules/invert-kv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/ip": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
@ -12559,6 +12566,18 @@
"shell-quote": "^1.8.1"
}
},
"node_modules/lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
"integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
"dev": true,
"dependencies": {
"invert-kv": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -12807,12 +12826,6 @@
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
},
"node_modules/lodash.pick": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
"integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==",
"dev": true
},
"node_modules/lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
@ -13060,6 +13073,18 @@
"tmpl": "1.0.5"
}
},
"node_modules/map-age-cleaner": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
"dev": true,
"dependencies": {
"p-defer": "^1.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/matchmediaquery": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz",
@ -13110,6 +13135,29 @@
"node": ">= 0.6"
}
},
"node_modules/mem": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
"integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
"dev": true,
"dependencies": {
"map-age-cleaner": "^0.1.1",
"mimic-fn": "^2.0.0",
"p-is-promise": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/mem/node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/memfs": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
@ -14084,6 +14132,35 @@
"multicast-dns": "cli.js"
}
},
"node_modules/multiyargs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/multiyargs/-/multiyargs-1.0.0.tgz",
"integrity": "sha512-rKXtn3hjueIQzyqyPRk8roPjc23uLUA1QQmljIrpaKC3N1rtGDkZXsprBbRNUPMtw+Vi0RLO9KLp1yq7xvhT5Q==",
"dev": true,
"dependencies": {
"debug": "2.6.x",
"promise-do-whilst": "1.0.x"
},
"engines": {
"node": ">=6.x",
"yargs": ">=7.0.x"
}
},
"node_modules/multiyargs/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/multiyargs/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"node_modules/mv": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
@ -14259,9 +14336,9 @@
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ=="
},
"node_modules/node-addon-api": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
"dev": true
},
"node_modules/node-dir": {
@ -14398,6 +14475,15 @@
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
"integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="
},
"node_modules/number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ob1": {
"version": "0.76.8",
"resolved": "https://registry.npmjs.org/ob1/-/ob1-0.76.8.tgz",
@ -14514,6 +14600,20 @@
"node": ">=0.10.0"
}
},
"node_modules/os-locale": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
"integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
"dev": true,
"dependencies": {
"execa": "^1.0.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@ -14531,6 +14631,15 @@
"os-tmpdir": "^1.0.0"
}
},
"node_modules/p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
"integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
@ -14539,6 +14648,15 @@
"node": ">=4"
}
},
"node_modules/p-is-promise": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
"integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@ -15786,12 +15904,6 @@
"node": ">=10"
}
},
"node_modules/prebuild-install/node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true
},
"node_modules/prebuild-install/node_modules/detect-libc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
@ -15801,48 +15913,6 @@
"node": ">=8"
}
},
"node_modules/prebuild-install/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/prebuild-install/node_modules/tar-fs": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"dev": true,
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
}
},
"node_modules/prebuild-install/node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true,
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
@ -15928,6 +15998,12 @@
"asap": "~2.0.3"
}
},
"node_modules/promise-do-whilst": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-do-whilst/-/promise-do-whilst-1.0.1.tgz",
"integrity": "sha512-ibWrC+x8v5K9V4UC8ISxxo/zvk4gVuiOPibgkS+pRa2fYKkbEZfu5OY8paq29QM0qKM9/+iaLmp1mBvPnTgzcQ==",
"dev": true
},
"node_modules/promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@ -16060,12 +16136,6 @@
}
]
},
"node_modules/queue-tick": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
"integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
"dev": true
},
"node_modules/ramda": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
@ -17082,46 +17152,55 @@
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
},
"node_modules/sharp": {
"version": "0.32.6",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz",
"integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==",
"version": "0.30.6",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.6.tgz",
"integrity": "sha512-lSdVxFxcndzcXggDrak6ozdGJgmIgES9YVZWtAFrwi+a/H5vModaf51TghBtMPw+71sLxUsTy2j+aB7qLIODQg==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.2",
"node-addon-api": "^6.1.0",
"prebuild-install": "^7.1.1",
"semver": "^7.5.4",
"detect-libc": "^2.0.1",
"node-addon-api": "^5.0.0",
"prebuild-install": "^7.1.0",
"semver": "^7.3.7",
"simple-get": "^4.0.1",
"tar-fs": "^3.0.4",
"tar-fs": "^2.1.1",
"tunnel-agent": "^0.6.0"
},
"engines": {
"node": ">=14.15.0"
"node": ">=12.13.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/sharp-cli": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/sharp-cli/-/sharp-cli-4.2.0.tgz",
"integrity": "sha512-rLu31/2k0JCrDw0BaM4sWU0yf9652GtzH0PksxFaw++YLRj8Hj/pDwhbdKxV/QEb5qkDOX/+0HyBQf6l5aYtqw==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/sharp-cli/-/sharp-cli-2.1.1.tgz",
"integrity": "sha512-nn/VK4I5UhU5gdQp7sw81qyV/ymyZS9yhdWh+wcE0ML9ietbrQaFZXtVc7MeYAHLF6l5oQPPG0eQQz0ObO0M6A==",
"dev": true,
"dependencies": {
"bubble-stream-error": "1.0.x",
"glob": "8.0.x",
"is-directory": "0.3.x",
"lodash.pick": "^4.4.0",
"sharp": "0.32.6",
"yargs": "^17.6.2"
"multiyargs": "1.0.x",
"sharp": "0.30.6",
"yargs": "12.0.x"
},
"bin": {
"sharp": "bin/cli.js"
},
"engines": {
"node": ">=14.15"
"node": ">=12.22"
}
},
"node_modules/sharp-cli/node_modules/ansi-regex": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/sharp-cli/node_modules/brace-expansion": {
@ -17133,6 +17212,44 @@
"balanced-match": "^1.0.0"
}
},
"node_modules/sharp-cli/node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/sharp-cli/node_modules/cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
"integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
"dev": true,
"dependencies": {
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0",
"wrap-ansi": "^2.0.0"
}
},
"node_modules/sharp-cli/node_modules/find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"dependencies": {
"locate-path": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/sharp-cli/node_modules/get-caller-file": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true
},
"node_modules/sharp-cli/node_modules/glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
@ -17152,6 +17269,19 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/sharp-cli/node_modules/locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"dependencies": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/sharp-cli/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
@ -17164,6 +17294,169 @@
"node": ">=10"
}
},
"node_modules/sharp-cli/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sharp-cli/node_modules/p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"dependencies": {
"p-limit": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/sharp-cli/node_modules/path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/sharp-cli/node_modules/require-main-filename": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
"integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==",
"dev": true
},
"node_modules/sharp-cli/node_modules/string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"dependencies": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/sharp-cli/node_modules/strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
"dev": true,
"dependencies": {
"ansi-regex": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/sharp-cli/node_modules/wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
"dev": true,
"dependencies": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sharp-cli/node_modules/wrap-ansi/node_modules/ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sharp-cli/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
"dev": true,
"dependencies": {
"number-is-nan": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sharp-cli/node_modules/wrap-ansi/node_modules/string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
"dev": true,
"dependencies": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sharp-cli/node_modules/wrap-ansi/node_modules/strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
"dev": true,
"dependencies": {
"ansi-regex": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sharp-cli/node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true
},
"node_modules/sharp-cli/node_modules/yargs": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
"dev": true,
"dependencies": {
"cliui": "^4.0.0",
"decamelize": "^1.2.0",
"find-up": "^3.0.0",
"get-caller-file": "^1.0.1",
"os-locale": "^3.0.0",
"require-directory": "^2.1.1",
"require-main-filename": "^1.0.1",
"set-blocking": "^2.0.0",
"string-width": "^2.0.0",
"which-module": "^2.0.0",
"y18n": "^3.2.1 || ^4.0.0",
"yargs-parser": "^11.1.1"
}
},
"node_modules/sharp-cli/node_modules/yargs-parser": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
"dev": true,
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
},
"node_modules/sharp/node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
@ -17629,16 +17922,6 @@
"node": ">= 0.10.0"
}
},
"node_modules/streamx": {
"version": "2.15.6",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz",
"integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==",
"dev": true,
"dependencies": {
"fast-fifo": "^1.1.0",
"queue-tick": "^1.0.1"
}
},
"node_modules/strict-uri-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
@ -18029,25 +18312,51 @@
}
},
"node_modules/tar-fs": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
"integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"dev": true,
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^3.1.5"
"tar-stream": "^2.1.4"
}
},
"node_modules/tar-fs/node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true
},
"node_modules/tar-stream": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
"integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true,
"dependencies": {
"b4a": "^1.6.4",
"fast-fifo": "^1.2.0",
"streamx": "^2.15.0"
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/tar-stream/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/tar/node_modules/minipass": {

View file

@ -14,6 +14,7 @@
"@expo/webpack-config": "^19.0.0",
"@react-native-masked-view/masked-view": "0.2.9",
"@react-navigation/drawer": "^6.6.6",
"@react-navigation/elements": "^1.3.21",
"@react-navigation/native": "^6.1.9",
"@react-navigation/stack": "^6.3.20",
"expo": "~49.0.15",
@ -41,7 +42,7 @@
"@types/react": "~18.2.14",
"patch-package": "^8.0.0",
"postinstall-postinstall": "^2.1.0",
"sharp-cli": "^4.2.0",
"sharp-cli": "^2.1.0",
"typescript": "^5.1.3"
},
"private": true

View file

@ -1,6 +1,6 @@
import { createMaterialBottomTabNavigator } from "react-native-paper/react-navigation";
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import { ScreenList, Notifications, Profile } from "./screens";
import { ScreenList, History, Profile } from "./screens";
const Tab = createMaterialBottomTabNavigator();
@ -18,8 +18,8 @@ export function BottomNavigation() {
}}
/>
<Tab.Screen
name="Notifications"
component={Notifications}
name="History"
component={History}
options={{
tabBarLabel: "History",
tabBarIcon: ({ color }) => (

View file

@ -1,6 +1,6 @@
import * as React from "react";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { ScreenList, Notifications, Profile } from "./screens";
import { ScreenList, History, Profile } from "./screens";
const Drawer = createDrawerNavigator();
@ -13,7 +13,7 @@ export function DrawerNavigation() {
}}
>
<Drawer.Screen name="Feed" component={ScreenList} />
<Drawer.Screen name="Notifications" component={Notifications} />
<Drawer.Screen name="Notifications" component={History} />
<Drawer.Screen name="Profile" component={Profile} />
</Drawer.Navigator>
);

View file

@ -0,0 +1,24 @@
import { StyleSheet, View } from "react-native";
import { Text } from "react-native-paper";
import { Appbar } from "react-native-paper";
export function History() {
return (
<>
<Appbar.Header elevated>
<Appbar.Content title="History" />
</Appbar.Header>
<View style={styles.container}>
<Text variant="headlineMedium">History!</Text>
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
});

View file

@ -3,21 +3,19 @@ import {
ScrollView,
View,
useWindowDimensions,
Image,
} from "react-native";
import { Appbar, Text, Avatar, Card, List, useTheme } from "react-native-paper";
import {
Appbar,
Text,
Avatar,
IconButton,
Card,
List,
useTheme,
} from "react-native-paper";
import { createStackNavigator } from "@react-navigation/stack";
StackHeaderProps,
createStackNavigator,
} from "@react-navigation/stack";
import RenderHtml from "react-native-render-html";
import { HomeScreenNavigationProp } from "./types";
import useSWR from "swr";
import { pb } from "../api";
import { getHeaderTitle } from "@react-navigation/elements";
import { useEffect, useLayoutEffect } from "react";
function ListItem(props: { name: string; onPress(): void }) {
return (
@ -97,9 +95,20 @@ async function listFetcher(id: string): Promise<ListResponse> {
function ListContent({ route, navigation }: HomeScreenNavigationProp<"List">) {
const theme = useTheme();
const { listId } = route.params ?? {};
const { listId, listName } = route.params ?? {};
const { isLoading, data, error } = useSWR(listId || "all", listFetcher);
useEffect(() => {
let title = "";
if (isLoading) {
title = listName || "Loading...";
} else if (data) {
title = data.name;
} else if (error) {
title = "Error";
}
navigation.setOptions({ title });
}, [isLoading, data?.name, error, navigation]);
if (isLoading) {
return (
<View
@ -122,45 +131,29 @@ function ListContent({ route, navigation }: HomeScreenNavigationProp<"List">) {
const { name, parentId, lists, tasks } = data;
return (
<>
<Appbar.Header elevated>
{Boolean(listId) && (
<Appbar.BackAction
onPress={() =>
navigation.canGoBack()
? navigation.pop()
: navigation.replace("List", { listId: parentId })
}
/>
)}
<Appbar.Content title={name} />
<Appbar.Action icon="dice-multiple-outline" onPress={() => {}} />
<Appbar.Action icon="magnify" onPress={() => {}} />
</Appbar.Header>
<ScrollView
style={[styles.container, { backgroundColor: theme.colors.background }]}
>
{lists.map((l) => (
<ListItem
key={l.id}
name={l.name}
onPress={() => navigation.push("List", { listId: l.id })}
/>
))}
{tasks.length > 0 && (
<List.Section>
<List.Subheader>Tasks</List.Subheader>
{tasks.map((t) => (
<TaskItem
key={t.id}
name={t.name}
onPress={() => navigation.push("Task", { taskId: t.id })}
/>
))}
</List.Section>
)}
</ScrollView>
</>
<ScrollView
style={[styles.container, { backgroundColor: theme.colors.background }]}
>
{lists.map((l) => (
<ListItem
key={l.id}
name={l.name}
onPress={() => navigation.push("List", { listId: l.id, listName: l.name })}
/>
))}
{tasks.length > 0 && (
<List.Section>
<List.Subheader>Tasks</List.Subheader>
{tasks.map((t) => (
<TaskItem
key={t.id}
name={t.name}
onPress={() => navigation.push("Task", { taskId: t.id, taskName: t.name })}
/>
))}
</List.Section>
)}
</ScrollView>
);
}
@ -169,24 +162,41 @@ interface TaskResponse {
name: string;
description: string;
listId: string;
imageSource: string;
}
async function taskFetcher(id: string): Promise<TaskResponse> {
const task = await pb.collection("tasks").getOne(id);
const icon = await pb.collection("icons").getOne(task.icon);
const imageSource = pb.getFileUrl(icon, icon.image, {
thumb: "300x300",
});
return {
id,
name: task.name,
description: task.description,
listId: task.list,
imageSource,
};
}
function TaskContent({ route, navigation }: HomeScreenNavigationProp<"Task">) {
const dimensions = useWindowDimensions();
const theme = useTheme();
const { taskId } = route.params;
const { taskId, taskName } = route.params;
const { isLoading, data, error } = useSWR(taskId, taskFetcher);
useEffect(() => {
let title = "";
if (isLoading) {
title = taskName || "Loading...";
} else if (data) {
title = data.name;
} else if (error) {
title = "Error";
}
navigation.setOptions({ title });
}, [isLoading, data?.name, error, navigation]);
if (isLoading) {
return (
<View
@ -206,33 +216,64 @@ function TaskContent({ route, navigation }: HomeScreenNavigationProp<"Task">) {
);
}
const { name, description, listId } = data;
const { name, description, imageSource } = data;
return (
<>
<Appbar.Header elevated>
<Appbar.BackAction
onPress={() =>
navigation.canGoBack()
? navigation.pop()
: navigation.replace("List", { listId })
}
/>
<Appbar.Content title={name} />
</Appbar.Header>
<View
style={[styles.padded, { backgroundColor: theme.colors.background }]}
>
<RenderHtml
contentWidth={dimensions.width}
source={{ html: description }}
baseStyle={{
color: theme.colors.onBackground,
fontSize: "1.1em",
}}
/>
</View>
</>
<View
style={[
styles.padded,
styles.centered,
{ backgroundColor: theme.colors.background },
]}
>
<Image style={styles.image} source={{ uri: imageSource }} />
<RenderHtml
contentWidth={dimensions.width}
source={{ html: description }}
baseStyle={{
color: theme.colors.onBackground,
fontSize: "1.1em",
}}
/>
</View>
);
}
function ListNavigationBar({
navigation,
route,
options,
back,
}: StackHeaderProps) {
const title = getHeaderTitle(options, (route.params as any)?.listName || route.name);
return (
<Appbar.Header elevated>
{back ? <Appbar.BackAction onPress={() => navigation.pop()} /> : null}
<Appbar.Content title={title} />
<Appbar.Action icon="dice-multiple-outline" onPress={() => {}} />
<Appbar.Action icon="magnify" onPress={() => {}} />
</Appbar.Header>
);
}
function TaskNavigationBar({
navigation,
route,
options,
back,
}: StackHeaderProps) {
const title = getHeaderTitle(options, (route.params as any)?.taskName || route.name);
return (
<Appbar.Header elevated>
<Appbar.BackAction
onPress={() => (back ? navigation.pop() : navigation.replace("List"))}
/>
<Appbar.Content title={title} />
<Appbar.Action icon="run-fast" onPress={() => {}} />
<Appbar.Action icon="square-edit-outline" onPress={() => {}} />
</Appbar.Header>
);
}
@ -242,10 +283,21 @@ export function ScreenList() {
return (
<Stack.Navigator
initialRouteName="List"
screenOptions={{ headerShown: false }}
>
<Stack.Screen name="List" component={ListContent as any} />
<Stack.Screen name="Task" component={TaskContent as any} />
<Stack.Screen
name="List"
component={ListContent as any}
options={{
header: (props) => <ListNavigationBar {...props} />,
}}
/>
<Stack.Screen
name="Task"
component={TaskContent as any}
options={{
header: (props) => <TaskNavigationBar {...props} />,
}}
/>
</Stack.Navigator>
);
}
@ -262,4 +314,12 @@ const styles = StyleSheet.create({
padding: 16,
flex: 1,
},
centered: {
alignItems: "center",
},
image: {
width: 300,
height: 300,
borderRadius: 15,
},
});

View file

@ -1,20 +0,0 @@
import { StyleSheet, View } from "react-native";
import { Text } from "react-native-paper";
export function Notifications() {
return (
<View style={styles.container}>
<Text variant="headlineMedium">Updates!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});

View file

@ -1,18 +1,12 @@
import { StyleSheet, View } from "react-native";
import { useNavigation } from "@react-navigation/native";
import { Text } from "react-native-paper";
import { Appbar } from "react-native-paper";
export function Profile() {
const navigation = useNavigation();
return (
<>
<Appbar.Header>
{navigation.canGoBack() && <Appbar.BackAction onPress={() => navigation.goBack()} />}
<Appbar.Content title="Title" />
<Appbar.Action icon="calendar" onPress={() => navigation.navigate("Profile")} />
<Appbar.Action icon="magnify" onPress={() => {}} />
<Appbar.Header elevated>
<Appbar.Content title="Profile" />
</Appbar.Header>
<View style={styles.container}>
<Text variant="headlineMedium">Profile!</Text>
@ -23,10 +17,8 @@ export function Profile() {
const styles = StyleSheet.create({
container: {
/*flex: 1,
backgroundColor: "#fff",
flex: 1,
alignItems: "center",
justifyContent: "center",*/
justifyContent: "center",
},
});

View file

@ -1,3 +1,3 @@
export * from "./List";
export * from "./Notifications";
export * from "./History";
export * from "./Profile";

View file

@ -6,14 +6,13 @@ import type { StackScreenProps } from "@react-navigation/stack";
export interface RootBottomParamList extends ParamListBase {
Home: NavigatorScreenParams<HomeStackParamList>;
Notifications: undefined;
History: undefined;
Profile: undefined;
Task: { id: string };
}
interface HomeStackParamList extends ParamListBase {
List: { listId: string | null };
Task: { taskId: string | null };
List: { listId: string | null, listName?: string };
Task: { taskId: string | null, taskName?: string };
}
export type HomeScreenNavigationProp<