From 0daf4f79ab3220378d83df365cfa18de36b48d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Berente?= <30603208+berenteb@users.noreply.github.com> Date: Sun, 28 Jan 2024 18:49:46 +0100 Subject: [PATCH 1/6] feat: added notification icon and settings --- app.json | 6 +++++- assets/notification-icon.png | Bin 0 -> 7168 bytes 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 assets/notification-icon.png diff --git a/app.json b/app.json index 4460a3e..bf14dad 100644 --- a/app.json +++ b/app.json @@ -31,6 +31,10 @@ } }, "owner": "kir-dev", - "plugins": ["expo-router"] + "plugins": ["expo-router"], + "notification": { + "icon": "./assets/notification-icon.png", + "color": "#000000" + } } } diff --git a/assets/notification-icon.png b/assets/notification-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..07e2c814a3961f5c59196272eee48e833a91e284 GIT binary patch literal 7168 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 Date: Sun, 28 Jan 2024 18:50:02 +0100 Subject: [PATCH 2/6] feat: added expo-notifications and expo-device --- package.json | 6 +- yarn.lock | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 180 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d1caa45..76d7353 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "main": "expo-router/entry", "scripts": { "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo run:android", + "ios": "expo run:ios", "lint": "eslint \"./**/*.ts?(x)\" --fix", "lint:check": "eslint \"./**/*.ts?(x)\"", "prettier": "prettier --write \"**/*.(ts|tsx)\"", @@ -21,7 +21,9 @@ "date-fns": "^3.2.0", "expo": "~49.0.21", "expo-constants": "~14.4.2", + "expo-device": "~5.4.0", "expo-linking": "~5.0.2", + "expo-notifications": "~0.20.1", "expo-router": "^2.0.0", "expo-splash-screen": "~0.20.5", "expo-status-bar": "~1.6.0", diff --git a/yarn.lock b/yarn.lock index ac0bda9..7aca782 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1447,6 +1447,23 @@ semver "7.3.2" tempy "0.3.0" +"@expo/image-utils@^0.3.18": + version "0.3.23" + resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.3.23.tgz#f14fd7e1f5ff6f8e4911a41e27dd274470665c3f" + integrity sha512-nhUVvW0TrRE4jtWzHQl8TR4ox7kcmrc2I0itaeJGjxF5A54uk7avgA0wRt7jP1rdvqQo1Ke1lXyLYREdhN9tPw== + dependencies: + "@expo/spawn-async" "1.5.0" + chalk "^4.0.0" + fs-extra "9.0.0" + getenv "^1.0.0" + jimp-compact "0.16.1" + mime "^2.4.4" + node-fetch "^2.6.0" + parse-png "^2.1.0" + resolve-from "^5.0.0" + semver "7.3.2" + tempy "0.3.0" + "@expo/json-file@^8.2.37", "@expo/json-file@~8.2.37": version "8.2.37" resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.37.tgz#9c02d3b42134907c69cc0a027b18671b69344049" @@ -1620,6 +1637,11 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== +"@ide/backoff@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@ide/backoff/-/backoff-1.0.0.tgz#466842c25bd4a4833e0642fab41ccff064010176" + integrity sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -2553,6 +2575,17 @@ asap@~2.0.3, asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +assert@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== + dependencies: + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" + ast-types@0.15.2: version "0.15.2" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.15.2.tgz#39ae4809393c4b16df751ee563411423e85fb49d" @@ -2585,6 +2618,11 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + babel-core@^7.0.0-bridge.0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" @@ -2689,6 +2727,11 @@ babel-preset-fbjs@^3.4.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" +badgin@^1.1.5: + version "1.2.3" + resolved "https://registry.yarnpkg.com/badgin/-/badgin-1.2.3.tgz#994b5f519827d7d5422224825b2c8faea2bc43ad" + integrity sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -2897,7 +2940,7 @@ cacache@^15.3.0: tar "^6.0.2" unique-filename "^1.1.1" -call-bind@^1.0.0: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== @@ -3426,7 +3469,7 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-data-property@^1.1.1: +define-data-property@^1.0.1, define-data-property@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== @@ -3445,6 +3488,15 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== +define-properties@^1.1.3, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + del@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" @@ -3858,6 +3910,13 @@ expo-constants@~14.4.2: "@expo/config" "~8.1.0" uuid "^3.3.2" +expo-device@~5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-5.4.0.tgz#4dc4db4b2265d1f5c9d7c2be6548c375882be437" + integrity sha512-TQxSVPrC6njCbzZ9Cqpc1lGLIjPmO1zBIbqW7CTqBPD1dOIMrgQvt7lZZhkHh3pWzoZznH283sSYqCvy3XcURw== + dependencies: + ua-parser-js "^0.7.33" + expo-file-system@~15.4.0, expo-file-system@~15.4.5: version "15.4.5" resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-15.4.5.tgz#3ef68583027ff0e2fb9eca7a22b3caff6cfc550d" @@ -3915,6 +3974,21 @@ expo-modules-core@1.5.12: compare-versions "^3.4.0" invariant "^2.2.4" +expo-notifications@~0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.20.1.tgz#55479e3bbde31ab5ccf6f6fd3ed288c6c91101d2" + integrity sha512-Y4Y8IWYj/cSWCP/P167z3GRg//5ZlsznfMXi4ABdWOOpF0RGNpd5N17TxioNivtt7tMhZ/o1vmzFxulhy0nBWg== + dependencies: + "@expo/image-utils" "^0.3.18" + "@ide/backoff" "^1.0.0" + abort-controller "^3.0.0" + assert "^2.0.0" + badgin "^1.1.5" + expo-application "~5.3.0" + expo-constants "~14.4.2" + fs-extra "^9.1.0" + uuid "^3.4.0" + expo-router@^2.0.0: version "2.0.14" resolved "https://registry.yarnpkg.com/expo-router/-/expo-router-2.0.14.tgz#6c05fc9620d3d3e94dfffdd013ad5dace1bc69e0" @@ -4171,6 +4245,13 @@ fontfaceobserver@^2.1.0: resolved "https://registry.yarnpkg.com/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz#5fb392116e75d5024b7ec8e4f2ce92106d1488c8" integrity sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" @@ -4437,11 +4518,18 @@ has-proto@^1.0.1: resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== -has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + hasown@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" @@ -4614,6 +4702,14 @@ ipaddr.js@^1.9.0: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4636,6 +4732,11 @@ is-buffer@~1.1.1, is-buffer@~1.1.6: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-core-module@^2.13.0: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" @@ -4678,6 +4779,13 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -4711,6 +4819,14 @@ is-invalid-path@^0.1.0: dependencies: is-glob "^2.0.0" +is-nan@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -4753,6 +4869,13 @@ is-stream@^3.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== +is-typed-array@^1.1.3: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -5919,6 +6042,29 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -7634,6 +7780,11 @@ typescript@^5.1.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +ua-parser-js@^0.7.33: + version "0.7.37" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz#e464e66dac2d33a7a1251d7d7a99d6157ec27832" + integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA== + ua-parser-js@^1.0.35: version "1.0.37" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.37.tgz#b5dc7b163a5c1f0c510b08446aed4da92c46373f" @@ -7779,6 +7930,17 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -7863,6 +8025,17 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== +which-typed-array@^1.1.11, which-typed-array@^1.1.2: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" From 38062499580129d4bbe43d3540fadf07503ccb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Berente?= <30603208+berenteb@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:24:50 +0100 Subject: [PATCH 3/6] feat: added local push notifications --- app/(tabs)/_layout.tsx | 2 + components/schedule/favorite-button.tsx | 12 +++-- components/schedule/schedule-details-page.tsx | 2 +- components/schedule/schedule-item.tsx | 2 +- contexts/favorite-events.context.tsx | 14 +++-- hooks/use-notification-observer.ts | 35 ++++++++++++ package.json | 2 +- services/favorite-event.service.ts | 4 +- services/notification.service.ts | 53 +++++++++++++++++++ types/favorite-event.type.ts | 1 + yarn.lock | 2 +- 11 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 hooks/use-notification-observer.ts create mode 100644 services/notification.service.ts diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 5ef9ce7..5933916 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -4,9 +4,11 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { TabbarBackground } from '../../components/tabbar/tabbar-background'; import { TabbarIcon } from '../../components/tabbar/tabbar-icon'; import { TabbarLabel } from '../../components/tabbar/tabbar-label'; +import { useNotificationObserver } from '../../hooks/use-notification-observer'; import { colors } from '../../theme/colors'; export default function TabsLayout() { + useNotificationObserver(); const { top, bottom, left, right } = useSafeAreaInsets(); return ( isFavoriteEvent(eventId), [eventId, isFavoriteEvent]); + const isFavorite = useMemo(() => isFavoriteEvent(event.id), [event, isFavoriteEvent]); const onPress = () => { if (isFavorite) { - removeFavoriteEvent(eventId); + removeFavoriteEvent(event.id); } else { - addFavoriteEvent(eventId); + addFavoriteEvent(event); } }; diff --git a/components/schedule/schedule-details-page.tsx b/components/schedule/schedule-details-page.tsx index 3cf6865..1e2fd8d 100644 --- a/components/schedule/schedule-details-page.tsx +++ b/components/schedule/schedule-details-page.tsx @@ -26,7 +26,7 @@ export function ScheduleDetailsPage({ id }: ScheduleDetailsPageProps) { {data?.description} - + ); } diff --git a/components/schedule/schedule-item.tsx b/components/schedule/schedule-item.tsx index e3284aa..fec9ec0 100644 --- a/components/schedule/schedule-item.tsx +++ b/components/schedule/schedule-item.tsx @@ -1,5 +1,5 @@ import { format } from 'date-fns'; -import { useNavigation } from 'expo-router'; +import { router, useNavigation, useRouter } from 'expo-router'; import { useState } from 'react'; import { Image, Pressable, View } from 'react-native'; import { NativeStackNavigationProp } from 'react-native-screens/native-stack'; diff --git a/contexts/favorite-events.context.tsx b/contexts/favorite-events.context.tsx index 6761ffa..b67b84e 100644 --- a/contexts/favorite-events.context.tsx +++ b/contexts/favorite-events.context.tsx @@ -1,12 +1,14 @@ import { createContext, PropsWithChildren, useContext, useEffect, useState } from 'react'; import { FavoriteEventStorageService } from '../services/favorite-event.service'; +import { NotificationService } from '../services/notification.service'; import { FavoriteEvent } from '../types/favorite-event.type'; +import { ScheduleEvent } from '../types/schedule-event.type'; type FavoriteEventsContextType = | { favoriteEvents: FavoriteEvent[]; - addFavoriteEvent: (eventId: string) => void; + addFavoriteEvent: (event: ScheduleEvent) => void; removeFavoriteEvent: (eventId: string) => void; isFavoriteEvent: (eventId: string) => boolean; } @@ -17,14 +19,18 @@ const FavoriteEventsContext = createContext(undefined export function FavoriteEventsProvider({ children }: PropsWithChildren) { const [favoriteEvents, setFavoriteEvents] = useState([]); - function addFavoriteEvent(eventId: string) { - setFavoriteEvents((prev) => [...prev, { eventId }]); - FavoriteEventStorageService.addFavoriteEvent(eventId); + async function addFavoriteEvent(event: ScheduleEvent) { + const notificationId = await NotificationService.scheduleEventNotification(event); + const favoriteEvent = { eventId: event.id, notificationId }; + setFavoriteEvents((prev) => [...prev, favoriteEvent]); + FavoriteEventStorageService.addFavoriteEvent(favoriteEvent); } function removeFavoriteEvent(eventId: string) { + const favoriteEvent = favoriteEvents.find((item) => item.eventId === eventId); setFavoriteEvents((prev) => prev.filter((item) => item.eventId !== eventId)); FavoriteEventStorageService.removeFavoriteEvent(eventId); + NotificationService.removeScheduledNotification(favoriteEvent?.notificationId); } function isFavoriteEvent(eventId: string) { diff --git a/hooks/use-notification-observer.ts b/hooks/use-notification-observer.ts new file mode 100644 index 0000000..315a8bd --- /dev/null +++ b/hooks/use-notification-observer.ts @@ -0,0 +1,35 @@ +import * as Notifications from 'expo-notifications'; +import { useRouter } from 'expo-router'; +import { useEffect } from 'react'; + +//From: https://docs.expo.dev/versions/latest/sdk/notifications/#handle-push-notifications-with-navigation +export function useNotificationObserver() { + const router = useRouter(); + useEffect(() => { + let isMounted = true; + + function redirect(notification: Notifications.Notification) { + const tab = notification.request.content.data?.tab; + const screen = notification.request.content.data?.screen; + const id = notification.request.content.data?.id; + if (tab) router.push({ pathname: tab }); + if (screen) router.push({ pathname: `${tab}/${screen}`, params: { id } }); + } + + Notifications.getLastNotificationResponseAsync().then((response) => { + if (!isMounted || !response?.notification) { + return; + } + redirect(response?.notification); + }); + + const subscription = Notifications.addNotificationResponseReceivedListener((response) => { + redirect(response.notification); + }); + + return () => { + isMounted = false; + subscription.remove(); + }; + }, []); +} diff --git a/package.json b/package.json index 76d7353..653d1cc 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "expo-device": "~5.4.0", "expo-linking": "~5.0.2", "expo-notifications": "~0.20.1", - "expo-router": "^2.0.0", + "expo-router": "^2.0.14", "expo-splash-screen": "~0.20.5", "expo-status-bar": "~1.6.0", "nativewind": "^2.0.11", diff --git a/services/favorite-event.service.ts b/services/favorite-event.service.ts index f821afc..dbbca5a 100644 --- a/services/favorite-event.service.ts +++ b/services/favorite-event.service.ts @@ -17,10 +17,10 @@ export class FavoriteEventStorageService { } } - static async addFavoriteEvent(eventId: string): Promise { + static async addFavoriteEvent(favorite: FavoriteEvent): Promise { try { const favoriteEvents = await this.listFavoriteEvents(); - const newFavoriteEvents = [...favoriteEvents, { eventId }]; + const newFavoriteEvents = [...favoriteEvents, favorite]; await this.saveFavoriteEvents(newFavoriteEvents); } catch (error) { console.log(error); diff --git a/services/notification.service.ts b/services/notification.service.ts new file mode 100644 index 0000000..6327227 --- /dev/null +++ b/services/notification.service.ts @@ -0,0 +1,53 @@ +import { isBefore } from 'date-fns'; +import * as Notifications from 'expo-notifications'; +import { Platform } from 'react-native'; + +import { ScheduleEvent } from '../types/schedule-event.type'; + +export class NotificationService { + static notificationEnabled = false; + + private static async registerForPushNotifications() { + if (Platform.OS === 'android') { + await Notifications.setNotificationChannelAsync('default', { + name: 'default', + importance: Notifications.AndroidImportance.HIGH, + }); + } + + const { status: existingStatus } = await Notifications.getPermissionsAsync(); + this.notificationEnabled = existingStatus === 'granted'; + if (existingStatus !== 'granted') { + const { status } = await Notifications.requestPermissionsAsync(); + this.notificationEnabled = status === 'granted'; + } + } + + static async scheduleEventNotification(event: ScheduleEvent) { + await this.registerForPushNotifications(); + if (!this.notificationEnabled) { + console.log('Notification permission not granted, not scheduling notification'); + return; + } + if (isBefore(new Date(event.start), new Date())) { + console.log('Event is in the past, not scheduling notification'); + return; + } + + const triggerDate = new Date(event.start); + + return await Notifications.scheduleNotificationAsync({ + content: { + title: event.title, + body: `Hamarosan kezdődik a(z) ${event.location} teremben!`, + data: { tab: 'schedule', screen: 'schedule-details', id: event.id }, + }, + trigger: triggerDate, + }); + } + + static async removeScheduledNotification(notificationId: string | undefined): Promise { + if (!notificationId) return; + await Notifications.cancelScheduledNotificationAsync(notificationId); + } +} diff --git a/types/favorite-event.type.ts b/types/favorite-event.type.ts index bad6f88..8d94897 100644 --- a/types/favorite-event.type.ts +++ b/types/favorite-event.type.ts @@ -1,3 +1,4 @@ export type FavoriteEvent = { eventId: string; + notificationId: string | undefined; }; diff --git a/yarn.lock b/yarn.lock index 7aca782..54f400f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3989,7 +3989,7 @@ expo-notifications@~0.20.1: fs-extra "^9.1.0" uuid "^3.4.0" -expo-router@^2.0.0: +expo-router@^2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/expo-router/-/expo-router-2.0.14.tgz#6c05fc9620d3d3e94dfffdd013ad5dace1bc69e0" integrity sha512-F5dP4WMe+zQLzlGSbC+NT9/67FGgwmUCJuPGD4BkK0eRt0uga+y53vQ59m5MCOebqE0N9Ukr/Jz8Num16iGqZA== From 975d32a0d4997d40b9641f3275f9c81b980f1394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Berente?= <30603208+berenteb@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:26:51 +0100 Subject: [PATCH 4/6] chore: unused imports removed --- components/schedule/favorite-button.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/schedule/favorite-button.tsx b/components/schedule/favorite-button.tsx index 4b0dcfb..096c206 100644 --- a/components/schedule/favorite-button.tsx +++ b/components/schedule/favorite-button.tsx @@ -1,5 +1,4 @@ import { AntDesign } from '@expo/vector-icons'; -import { addMinutes, addSeconds } from 'date-fns'; import { useMemo } from 'react'; import { Pressable } from 'react-native'; From 1828455c8d78ac44360ecb05421eff7208bfb398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Berente?= <30603208+berenteb@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:28:17 +0100 Subject: [PATCH 5/6] chore: unused imports removed --- components/schedule/schedule-item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/schedule/schedule-item.tsx b/components/schedule/schedule-item.tsx index fec9ec0..e3284aa 100644 --- a/components/schedule/schedule-item.tsx +++ b/components/schedule/schedule-item.tsx @@ -1,5 +1,5 @@ import { format } from 'date-fns'; -import { router, useNavigation, useRouter } from 'expo-router'; +import { useNavigation } from 'expo-router'; import { useState } from 'react'; import { Image, Pressable, View } from 'react-native'; import { NativeStackNavigationProp } from 'react-native-screens/native-stack'; From 29acf0c7c156a4a58d626d155976a22074647587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Berente?= <30603208+berenteb@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:09:15 +0100 Subject: [PATCH 6/6] fix: wrote back start commands --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 653d1cc..c67aa52 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "main": "expo-router/entry", "scripts": { "start": "expo start", - "android": "expo run:android", - "ios": "expo run:ios", + "android": "expo start --android", + "ios": "expo start --ios", "lint": "eslint \"./**/*.ts?(x)\" --fix", "lint:check": "eslint \"./**/*.ts?(x)\"", "prettier": "prettier --write \"**/*.(ts|tsx)\"",