From cda67d23f699c02cddebffe465d586a0a20c81d6 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Sat, 24 Oct 2020 02:47:57 +0200 Subject: [PATCH] Setup of single store works for multiple timeline --- App.jsx | 4 +- package-lock.json | 305 +++++++++++-------------- package.json | 2 +- src/{Main.jsx => Index.jsx} | 14 +- src/api/client.js | 16 +- src/app/store.js | 16 -- src/stacks/Main.jsx | 14 ++ src/stacks/Main/Following.jsx | 7 + src/stacks/MainTimeline.jsx | 18 -- src/stacks/Public.jsx | 14 ++ src/stacks/Public/CurrentPublic.jsx | 7 + src/stacks/PublicTimeline.jsx | 20 -- src/stacks/common/Timeline.jsx | 36 ++- src/stacks/common/instanceInfoSlice.js | 24 ++ src/stacks/common/store.js | 30 +++ src/stacks/common/timelineSlice.js | 137 +++++------ 16 files changed, 334 insertions(+), 330 deletions(-) rename src/{Main.jsx => Index.jsx} (70%) delete mode 100644 src/app/store.js create mode 100644 src/stacks/Main.jsx create mode 100644 src/stacks/Main/Following.jsx delete mode 100644 src/stacks/MainTimeline.jsx create mode 100644 src/stacks/Public.jsx create mode 100644 src/stacks/Public/CurrentPublic.jsx delete mode 100644 src/stacks/PublicTimeline.jsx create mode 100644 src/stacks/common/instanceInfoSlice.js create mode 100644 src/stacks/common/store.js diff --git a/App.jsx b/App.jsx index fdd93fb5..c502efb9 100644 --- a/App.jsx +++ b/App.jsx @@ -1,6 +1,6 @@ import React from 'react' -import Main from './src/Main' +import Index from './src/Index' -const App = () =>
+const App = () => export default App diff --git a/package-lock.json b/package-lock.json index f637934a..7f46f00d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1707,13 +1707,6 @@ "query-string": "^6.13.5", "react-is": "^16.13.0", "use-subscription": "^1.4.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - } } }, "@react-navigation/native": { @@ -1751,13 +1744,6 @@ "redux": "^4.0.0", "redux-thunk": "^2.3.0", "reselect": "^4.0.0" - }, - "dependencies": { - "reselect": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", - "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" - } } }, "@types/hammerjs": { @@ -2048,6 +2034,60 @@ "pkg-up": "^3.1.0", "reselect": "^4.0.0", "resolve": "^1.13.1" + }, + "dependencies": { + "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, + "requires": { + "locate-path": "^3.0.0" + } + }, + "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, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "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, + "requires": { + "p-try": "^2.0.0" + } + }, + "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, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } } }, "babel-plugin-react-native-web": { @@ -2084,52 +2124,6 @@ "resolve": "^1.4.0" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "requires": { - "find-up": "^2.1.0" - } - }, "reselect": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", @@ -2420,9 +2414,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001148", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001148.tgz", - "integrity": "sha512-E66qcd0KMKZHNJQt9hiLZGE3J4zuTqE1OnU53miEVtylFbwOEmeA5OsRu90noZful+XGSQOni1aT2tiqu/9yYw==" + "version": "1.0.30001150", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001150.tgz", + "integrity": "sha512-kiNKvihW0m36UhAFnl7bOAv0i1K1f6wpfVtTF5O5O82XzgtBnb05V0XeV3oZ968vfg2sRNChsHw8ASH2hDfoYQ==" }, "capture-exit": { "version": "2.0.0", @@ -2440,6 +2434,13 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } } }, "chardet": { @@ -2756,9 +2757,9 @@ } }, "dayjs": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.9.3.tgz", - "integrity": "sha512-V+1SyIvkS+HmNbN1G7A9+ERbFTV9KTXu6Oor98v2xHmzzpp52OIJhQuJSTywWuBY5pyAEmlwbCi1Me87n/SLOw==" + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.9.4.tgz", + "integrity": "sha512-ABSF3alrldf7nM9sQ2U+Ln67NRwmzlLOqG7kK03kck0mw3wlSSEKv/XhKGGxUjQcS57QeiCyNdrFgtj9nWlrng==" }, "debug": { "version": "4.2.0", @@ -2929,9 +2930,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.582", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.582.tgz", - "integrity": "sha512-0nCJ7cSqnkMC+kUuPs0YgklFHraWGl/xHqtZWWtOeVtyi+YqkoAOMGuZQad43DscXCQI/yizcTa3u6B5r+BLww==" + "version": "1.3.583", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.583.tgz", + "integrity": "sha512-L9BwLwJohjZW9mQESI79HRzhicPk1DFgM+8hOCfGgGCFEcA3Otpv7QK6SGtYoZvfQfE3wKLh0Hd5ptqUFv3gvQ==" }, "emoji-regex": { "version": "8.0.0", @@ -3067,9 +3068,9 @@ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "esprima": { "version": "4.0.1", @@ -3549,6 +3550,13 @@ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "requires": { "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } } }, "file-uri-to-path": { @@ -3627,12 +3635,11 @@ } }, "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, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "^3.0.0" + "locate-path": "^2.0.0" } }, "fontfaceobserver": { @@ -4586,12 +4593,11 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, "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, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "^3.0.0", + "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, @@ -4832,6 +4838,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -5114,6 +5125,11 @@ "source-map": "^0.5.0" } }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "json5": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", @@ -5649,9 +5665,9 @@ "optional": true }, "nanoid": { - "version": "3.1.13", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.13.tgz", - "integrity": "sha512-oYL7jWZUdScASxYOrcwE8EvISFGzO3/1g+t56vCyR0s2nrpmBcOc7hTAFJaVf6HMyEPJrnNelnjRnMN6KZnCPA==" + "version": "3.1.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.15.tgz", + "integrity": "sha512-n8rXUZ8UU3lV6+43atPrSizqzh25n1/f00Wx1sCiE7R1sSHytZLTTiQl8DjC4IDLOnEZDlgJhy0yO4VsIpMxow==" }, "nanomatch": { "version": "1.2.13", @@ -5891,28 +5907,25 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "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, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "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, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "^2.0.0" + "p-limit": "^1.1.0" } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" }, "parse-json": { "version": "4.0.0", @@ -6025,12 +6038,11 @@ } }, "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "requires": { - "find-up": "^3.0.0" + "find-up": "^2.1.0" } }, "plist": { @@ -6728,13 +6740,6 @@ "requires": { "loose-envify": "^1.4.0", "symbol-observable": "^1.2.0" - }, - "dependencies": { - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - } } }, "redux-thunk": { @@ -6872,8 +6877,7 @@ "reselect": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", - "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==", - "dev": true + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" }, "resolve": { "version": "1.18.1", @@ -6945,6 +6949,13 @@ "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", "requires": { "symbol-observable": "1.0.1" + }, + "dependencies": { + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" + } } }, "safe-buffer": { @@ -7419,61 +7430,21 @@ } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-abstract": "^1.18.0-next.1" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-abstract": "^1.18.0-next.1" } }, "string_decoder": { @@ -7511,9 +7482,9 @@ } }, "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "temp": { "version": "0.8.3", @@ -7823,9 +7794,9 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "use-subscription": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.4.1.tgz", - "integrity": "sha512-7+IIwDG/4JICrWHL/Q/ZPK5yozEnvRm6vHImu0LKwQlmWGKeiF7mbAenLlK/cTNXrTtXHU/SFASQHzB6+oSJMQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.0.tgz", + "integrity": "sha512-/FVRiB2I7NDjzWoNBYPt6YkkvleMm/lFtxj1hH6nX2TVrJ/5UTbovw9OE1efv2Zl0HoAYuTjM7zHd9OsABn5sg==", "requires": { "object-assign": "^4.1.1" } diff --git a/package.json b/package.json index 83bc88a3..6604e8ea 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "react-native-render-html": "^4.2.4", "react-native-safe-area-context": "3.1.4", "react-native-screens": "~2.10.1", - "react-native-web": "~0.13.12", + "react-native-web": "~0.13.7", "react-native-webview": "10.7.0", "react-redux": "^7.2.1" }, diff --git a/src/Main.jsx b/src/Index.jsx similarity index 70% rename from src/Main.jsx rename to src/Index.jsx index 0fba7890..8c1a6649 100644 --- a/src/Main.jsx +++ b/src/Index.jsx @@ -5,31 +5,29 @@ import { enableScreens } from 'react-native-screens' enableScreens() import React from 'react' -import store from './app/store' +import store from 'src/stacks/common/store' import { Provider } from 'react-redux' import { StatusBar } from 'expo-status-bar' -import MainTimeline from 'src/stacks/MainTimeline' -import PublicTimeline from 'src/stacks/PublicTimeline' +import Main from 'src/stacks/Main' +import Public from 'src/stacks/Public' import Notifications from 'src/stacks/Notifications' import Me from 'src/stacks/Me' const Tab = createBottomTabNavigator() -export default function Main () { +export default function Index () { return ( - <> - - + + {/* */} - ) } diff --git a/src/api/client.js b/src/api/client.js index bd744518..37538b32 100644 --- a/src/api/client.js +++ b/src/api/client.js @@ -1,12 +1,6 @@ -export async function client ( - instance, - endpoint, - query, - { body, ...customConfig } = {} -) { - if (!instance || !endpoint) { - console.error('Missing instance or endpoint.') - return Promise.reject('Missing instance or endpoint.') +export async function client (url, query, { body, ...customConfig } = {}) { + if (!url) { + return Promise.reject('Missing URL.') } const headers = { 'Content-Type': 'application/json' } @@ -25,8 +19,8 @@ export async function client ( let data try { const response = await fetch( - `https://${instance}/api/v1/${endpoint}${ - query + `https://${url}${ + Object.keys(query).length ? `?${Object.keys(query) .map(key => `${key}=${query[key]}`) .join('&')}` diff --git a/src/app/store.js b/src/app/store.js deleted file mode 100644 index c5335808..00000000 --- a/src/app/store.js +++ /dev/null @@ -1,16 +0,0 @@ -import { configureStore } from '@reduxjs/toolkit' - -import genericTimelineSlice from 'src/stacks/common/timelineSlice' - -export default configureStore({ - reducer: { - 'social.xmflsct.com': genericTimelineSlice('social.xmflsct.com').slice - .reducer, - 'm.cmx.im': genericTimelineSlice('m.cmx.im').slice.reducer - }, - middleware: getDefaultMiddleware => - getDefaultMiddleware({ - immutableCheck: false, - serializableCheck: false - }) -}) diff --git a/src/stacks/Main.jsx b/src/stacks/Main.jsx new file mode 100644 index 00000000..32250622 --- /dev/null +++ b/src/stacks/Main.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { createNativeStackNavigator } from 'react-native-screens/native-stack' + +import Following from 'src/stacks/Main/Following' + +const MainStack = createNativeStackNavigator() + +export default function Main () { + return ( + + + + ) +} diff --git a/src/stacks/Main/Following.jsx b/src/stacks/Main/Following.jsx new file mode 100644 index 00000000..d6e6a08e --- /dev/null +++ b/src/stacks/Main/Following.jsx @@ -0,0 +1,7 @@ +import React from 'react' + +import Timeline from 'src/stacks/common/Timeline' + +export default function Following () { + return +} diff --git a/src/stacks/MainTimeline.jsx b/src/stacks/MainTimeline.jsx deleted file mode 100644 index f35015a6..00000000 --- a/src/stacks/MainTimeline.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react' -import { createNativeStackNavigator } from 'react-native-screens/native-stack' - -import Timeline from 'src/stacks/common/Timeline' - -const MainTimelineStack = createNativeStackNavigator() - -function Base () { - return -} - -export default function MainTimeline () { - return ( - - - - ) -} diff --git a/src/stacks/Public.jsx b/src/stacks/Public.jsx new file mode 100644 index 00000000..01da675e --- /dev/null +++ b/src/stacks/Public.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { createNativeStackNavigator } from 'react-native-screens/native-stack' + +import CurrentPublic from 'src/stacks/Public/CurrentPublic' + +const PublicStack = createNativeStackNavigator() + +export default function PublicTimeline () { + return ( + + + + ) +} diff --git a/src/stacks/Public/CurrentPublic.jsx b/src/stacks/Public/CurrentPublic.jsx new file mode 100644 index 00000000..d4e829a0 --- /dev/null +++ b/src/stacks/Public/CurrentPublic.jsx @@ -0,0 +1,7 @@ +import React from 'react' + +import Timeline from 'src/stacks/common/Timeline' + +export default function CurrentPublic () { + return +} diff --git a/src/stacks/PublicTimeline.jsx b/src/stacks/PublicTimeline.jsx deleted file mode 100644 index 38b3e463..00000000 --- a/src/stacks/PublicTimeline.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' -import { createNativeStackNavigator } from 'react-native-screens/native-stack' - -import Timeline from 'src/stacks/common/Timeline' - -const PublicTimelineStack = createNativeStackNavigator() - -function Base () { - return -} - -export default function PublicTimeline () { - return ( - - - - ) -} - -// store by page maybe diff --git a/src/stacks/common/Timeline.jsx b/src/stacks/common/Timeline.jsx index 2b4675c9..8d6c192b 100644 --- a/src/stacks/common/Timeline.jsx +++ b/src/stacks/common/Timeline.jsx @@ -1,23 +1,25 @@ import PropTypes from 'prop-types' import React, { useEffect } from 'react' import { ActivityIndicator, FlatList, View } from 'react-native' -import { useSelector, useDispatch } from 'react-redux' +import { connect, useSelector, useDispatch } from 'react-redux' import TootTimeline from 'src/components/TootTimeline' +import { fetch, getToots, getStatus } from './timelineSlice' -import genericTimelineSlice from './timelineSlice' - -export default function Timeline ({ instance, endpoint, local }) { +export default function Timeline ({ remote, endpoint, local }) { const dispatch = useDispatch() - const toots = useSelector(genericTimelineSlice(instance).getToots) - const status = useSelector(genericTimelineSlice(instance).getStatus) + const toots = useSelector(state => + getToots(state)({ remote, endpoint, local }) + ) + const status = useSelector(state => + getStatus(state)({ remote, endpoint, local }) + ) useEffect(() => { if (status === 'idle') { - dispatch(genericTimelineSlice(instance).fetch({ endpoint, local })) + dispatch(fetch({ remote, endpoint, local })) } }, [status, dispatch]) - let content if (status === 'error') { @@ -31,22 +33,13 @@ export default function Timeline ({ instance, endpoint, local }) { renderItem={TootTimeline} onRefresh={() => dispatch( - genericTimelineSlice(instance).fetch({ - endpoint, - local, - id: toots[0].id, - newer: true - }) + fetch({ remote, endpoint, local, id: toots[0].id, newer: true }) ) } refreshing={status === 'loading'} onEndReached={() => dispatch( - genericTimelineSlice(instance).fetch({ - endpoint, - local, - id: toots[toots.length - 1].id - }) + fetch({ remote, endpoint, local, id: toots[toots.length - 1].id }) ) } onEndReachedThreshold={0.5} @@ -61,6 +54,7 @@ export default function Timeline ({ instance, endpoint, local }) { } Timeline.propTypes = { - instance: PropTypes.string.isRequired, - public: PropTypes.bool + remote: PropTypes.bool, + endpoint: PropTypes.string.isRequired, + local: PropTypes.bool } diff --git a/src/stacks/common/instanceInfoSlice.js b/src/stacks/common/instanceInfoSlice.js new file mode 100644 index 00000000..7a368f1e --- /dev/null +++ b/src/stacks/common/instanceInfoSlice.js @@ -0,0 +1,24 @@ +import { createSlice } from '@reduxjs/toolkit' + +const instanceInfoSlice = createSlice({ + name: 'instanceInfo', + initialState: {}, + reducers: { + // increment (state) { + // state.value++ + // }, + // decrement (state) { + // state.value-- + // }, + // incrementByAmount (state, action) { + // state.value += action.payload + // } + } +}) + +export const getCurrent = state => state.current +export const getCurrentToken = state => state.currentToken +export const getRemote = state => state.remote + +// export const { increment, decrement, incrementByAmount } = counterSlice.actions +export default instanceInfoSlice.reducer diff --git a/src/stacks/common/store.js b/src/stacks/common/store.js new file mode 100644 index 00000000..c06a13aa --- /dev/null +++ b/src/stacks/common/store.js @@ -0,0 +1,30 @@ +import { configureStore } from '@reduxjs/toolkit' + +import instanceInfoSlice from 'src/stacks/common/instanceInfoSlice' +import timelineSlice from 'src/stacks/common/timelineSlice' + +// get site information from local storage and pass to reducers +const preloadedState = { + instanceInfo: { + current: 'social.xmflsct.com', + currentToken: 'qjzJ0IjvZ1apsn0_wBkGcdjKgX7Dao9KEPhGwggPwAo', + remote: 'm.cmx.im' + } +} + +const reducer = { + instanceInfo: instanceInfoSlice, + timelines: timelineSlice +} + +// const middleware = getDefaultMiddleware => +// getDefaultMiddleware({ +// immutableCheck: false, +// serializableCheck: false +// }) + +export default configureStore({ + preloadedState, + reducer, + // middleware +}) diff --git a/src/stacks/common/timelineSlice.js b/src/stacks/common/timelineSlice.js index 506ae9fa..269dc192 100644 --- a/src/stacks/common/timelineSlice.js +++ b/src/stacks/common/timelineSlice.js @@ -1,77 +1,82 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit' import { client } from 'src/api/client' -import * as localStorage from 'src/utils/localStorage' -export default function genericTimelineSlice (instance) { - const fetch = createAsyncThunk( - 'timeline/fetch', - async ({ endpoint, local, id, newer }) => { - if (!instance || !endpoint) console.error('Missing instance or endpoint.') +// Naming convention +// Following: home +// Local: home/local +// CurrentPublic: public/local +// RemotePublic: remote - let query = {} - if (local) query.local = 'true' - if (newer) { - query.since_id = id - } else { - if (id) { - query.max_id = id +const checkInstance = ({ remote, endpoint, local }) => + remote ? 'remote' : `${endpoint}${local ? '/local' : ''}` + +export const fetch = createAsyncThunk( + 'timeline/fetch', + async ({ remote, endpoint, local, id, newer }, { getState }) => { + if (!endpoint) console.error('Missing endpoint') + + const instance = remote + ? `${getState().instanceInfo.remote}/api/v1/timelines/public` + : `${getState().instanceInfo.current}/api/v1/timelines/${endpoint}` + + const query = { + ...(local && { local: 'true' }), + ...(newer ? { since_id: id } : id && { max_id: id }) + } + + const header = { + ...(getState().instanceInfo.currentToken && { + headers: { + Authorization: `Bearer ${getState().instanceInfo.currentToken}` } - } - - let header - const instanceToken = await localStorage.getItem() - if (instanceToken) { - header = { headers: { Authorization: `Bearer ${instanceToken}` } } - } - - return { - data: await client.get( - instance, - `timelines/${endpoint}`, - query, - header - ), - newer: newer - } + }) } - ) - const slice = createSlice({ - name: instance, - initialState: { - toots: [], - status: 'idle', - error: null - }, - extraReducers: { - [fetch.pending]: state => { - state.status = 'loading' - }, - [fetch.fulfilled]: (state, action) => { - state.status = 'succeeded' - action.payload.newer - ? state.toots.unshift(...action.payload.data) - : state.toots.push(...action.payload.data) - }, - [fetch.rejected]: (state, action) => { - state.status = 'failed' - state.error = action.payload - } - } - }) - - getToots = state => state[instance].toots - getStatus = state => state[instance].status - - return { - fetch, - slice, - getToots, - getStatus + return await client.get(instance, query, header) } -} +) -// export const timelineSlice = genericTimelineSlice(data) +export const timelineSlice = createSlice({ + name: 'timeline', + initialState: { + home: { + toots: [], + status: 'idle' + }, + 'home/local': { + toots: [], + status: 'idle' + }, + 'public/local': { + toots: [], + status: 'idle' + }, + remote: { + toots: [], + status: 'idle' + } + }, + extraReducers: { + [fetch.pending]: (state, action) => { + state[checkInstance(action.meta.arg)].status = 'loading' + }, + [fetch.fulfilled]: (state, action) => { + state[checkInstance(action.meta.arg)].status = 'succeeded' + action.meta.arg.newer + ? state[checkInstance(action.meta.arg)].toots.unshift(...action.payload) + : state[checkInstance(action.meta.arg)].toots.push(...action.payload) + }, + [fetch.rejected]: (state, action) => { + console.error(action.error.message) + state[checkInstance(action.meta.arg)].status = 'failed' + } + } +}) -// export default timelineSlice.reducer +export const getToots = state => instance => + state.timelines[checkInstance(instance)].toots +export const getStatus = state => instance => + state.timelines[checkInstance(instance)].status + +export default timelineSlice.reducer