From 585c831aaba27410ed8db02d90daf626f374e604 Mon Sep 17 00:00:00 2001 From: sedataskan Date: Fri, 14 Mar 2025 00:45:56 +0300 Subject: [PATCH] Add react-native-paper and implement progress bar in CurrentlyReadingBook component #60 #61 --- package-lock.json | 177 ++++++++++++++++++++++++ package.json | 1 + src/components/CurrentlyReadingBook.tsx | 11 ++ src/screens/BookPreviewScreen.tsx | 19 +-- 4 files changed, 200 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe3ac23..4f29c88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "react-native-gesture-handler": "^2.24.0", "react-native-keyboard-avoiding-scroll-view": "^1.0.1", "react-native-material-menu": "^2.0.0", + "react-native-paper": "^5.13.1", "react-native-ratings": "^8.1.0", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "^5.3.0", @@ -2220,6 +2221,28 @@ "dev": true, "license": "MIT" }, + "node_modules/@callstack/react-theme-provider": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@callstack/react-theme-provider/-/react-theme-provider-3.0.9.tgz", + "integrity": "sha512-tTQ0uDSCL0ypeMa8T/E9wAZRGKWj8kXP7+6RYgPTfOPs9N07C9xM8P02GJ3feETap4Ux5S69D9nteq9mEj86NA==", + "license": "MIT", + "dependencies": { + "deepmerge": "^3.2.0", + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/@callstack/react-theme-provider/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@egjs/hammerjs": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", @@ -13357,6 +13380,57 @@ "react-native": "*" } }, + "node_modules/react-native-paper": { + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.13.1.tgz", + "integrity": "sha512-8frKVKJ5JBd8WL1G3tpcYzOgK40kxkD/U+yLHGKNeLnD6v1Qc9W6DxWTHWN7lsX/DPYnhgvw1aKkYaPTmDj5pg==", + "license": "MIT", + "dependencies": { + "@callstack/react-theme-provider": "^3.0.9", + "color": "^3.1.2", + "use-latest-callback": "^0.1.5" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-safe-area-context": "*", + "react-native-vector-icons": "*" + } + }, + "node_modules/react-native-paper/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/react-native-paper/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/react-native-paper/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/react-native-paper/node_modules/use-latest-callback": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.11.tgz", + "integrity": "sha512-8nhb73STSD/z3GTHklvNjL8F9wMOo0bj0AFnulpIYuFTm6aQlT3ZcNbXF2YurKImIY8+kpSFSDHZZyQmurGrhw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8" + } + }, "node_modules/react-native-ratings": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-8.1.0.tgz", @@ -13418,6 +13492,109 @@ "react-native": "*" } }, + "node_modules/react-native-vector-icons": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.2.0.tgz", + "integrity": "sha512-n5HGcxUuVaTf9QJPs/W22xQpC2Z9u0nb0KgLPnVltP8vdUvOp6+R26gF55kilP/fV4eL4vsAHUqUjewppJMBOQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "prop-types": "^15.7.2", + "yargs": "^16.1.1" + }, + "bin": { + "fa-upgrade.sh": "bin/fa-upgrade.sh", + "fa5-upgrade": "bin/fa5-upgrade.sh", + "fa6-upgrade": "bin/fa6-upgrade.sh", + "generate-icon": "bin/generate-icon.js" + } + }, + "node_modules/react-native-vector-icons/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/react-native-vector-icons/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT", + "peer": true + }, + "node_modules/react-native-vector-icons/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-native-vector-icons/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-native-vector-icons/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-native-vector-icons/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "peer": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native-vector-icons/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=10" + } + }, "node_modules/react-native/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", diff --git a/package.json b/package.json index aefdd0d..ce58eac 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "react-native-gesture-handler": "^2.24.0", "react-native-keyboard-avoiding-scroll-view": "^1.0.1", "react-native-material-menu": "^2.0.0", + "react-native-paper": "^5.13.1", "react-native-ratings": "^8.1.0", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "^5.3.0", diff --git a/src/components/CurrentlyReadingBook.tsx b/src/components/CurrentlyReadingBook.tsx index 5d5ff84..5256d4d 100644 --- a/src/components/CurrentlyReadingBook.tsx +++ b/src/components/CurrentlyReadingBook.tsx @@ -6,6 +6,7 @@ import { Ionicons } from "@expo/vector-icons"; import { useNavigation } from "@react-navigation/native"; import { StackNavigationProp } from "@react-navigation/stack"; import { useTranslation } from "react-i18next"; +import { ProgressBar } from "react-native-paper"; type RootStackParamList = { BookPreview: { @@ -109,6 +110,11 @@ export const CurrentlyReadingBook = ({ {t("current_page")}: {currentPage} + @@ -172,4 +178,9 @@ const styles = StyleSheet.create({ opacity: 0.9, marginLeft: 4, }, + progressBar: { + height: 6, + borderRadius: 3, + marginTop: 10, + }, }); diff --git a/src/screens/BookPreviewScreen.tsx b/src/screens/BookPreviewScreen.tsx index cc408ba..9d3f203 100644 --- a/src/screens/BookPreviewScreen.tsx +++ b/src/screens/BookPreviewScreen.tsx @@ -49,6 +49,13 @@ export default function BookPreviewScreen() { const [bookStatus, setBookStatus] = useState(book.status); const [open, setOpen] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false); + const [parsedBook, setParsedBook] = useState({ + ...book, + saveDate: new Date(book.saveDate), + status: book.status ? book.status : t("to_read"), + favPage: book.favPage ? book.favPage : 0, + currentPage: Number(book.currentPage) || 0, + }); const getSecureImageUrl = (url: string | undefined) => { if (!url) return "https://via.placeholder.com/128x192?text=No+Cover"; @@ -78,14 +85,6 @@ export default function BookPreviewScreen() { ); } - const parsedBook = { - ...book, - saveDate: new Date(book.saveDate), - status: book.status ? book.status : t("to_read"), - favPage: book.favPage ? book.favPage : 0, - currentPage: Number(book.currentPage) || 0, - }; - const handleEdit = () => { setMenuVisible(false); navigation.navigate("AddBook", { @@ -124,6 +123,10 @@ export default function BookPreviewScreen() { const handleStatusChange = async (newStatusKey: string) => { setBookStatus(newStatusKey); + setParsedBook((prevBook) => ({ + ...prevBook, + status: newStatusKey, + })); try { const existingBooks = await AsyncStorage.getItem("books"); const books = existingBooks ? JSON.parse(existingBooks) : [];