From a656b409ac0d64877a1737616057d4dd8355bcf4 Mon Sep 17 00:00:00 2001 From: Imbus Date: Thu, 14 Dec 2023 22:16:09 +0100 Subject: [PATCH 01/32] Style demo --- src/components/PostView.tsx | 2 +- src/components/PostsContainer.tsx | 72 ++++++++++++++++++++++++------- src/util/api.ts | 2 +- src/util/style.ts | 10 +++-- 4 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/components/PostView.tsx b/src/components/PostView.tsx index 35957b5..c5ea7ea 100644 --- a/src/components/PostView.tsx +++ b/src/components/PostView.tsx @@ -16,7 +16,7 @@ export function PostView({ post }: { post: Post }): JSX.Element { return ( - {thisPost.content} + {thisPost.content} ); } diff --git a/src/components/PostsContainer.tsx b/src/components/PostsContainer.tsx index a67ceb5..2503740 100644 --- a/src/components/PostsContainer.tsx +++ b/src/components/PostsContainer.tsx @@ -1,26 +1,66 @@ import React from "react"; import { View, Text } from "react-native"; -import { getPosts, Post } from "../util/api"; +import { getPost, getPosts, Post } from "../util/api"; import { PostView } from "./PostView"; import { style } from "../util/style"; +import { SafeAreaView } from "react-native"; +import { VirtualizedList } from "react-native"; + +type ItemData = { + id: string; + title: string; +}; + +type ItemProps = { + title: string; +}; + +const Item = ({title}: ItemProps): JSX.Element => ( + + {title} + +); export function PostsContainer(): JSX.Element { - const [posts, setPosts] = React.useState([]); + // const [posts, setPosts] = React.useState([]); - React.useEffect(() => { - async function fetchPosts(): Promise { - const posts = await getPosts(); - setPosts(posts); - } - fetchPosts(); - }, []); + // React.useEffect(() => { + // refreshPosts(); + // }, []); + + const getItemCount = (_data: unknown): number => 50; + + // function refreshPosts(): void { + // async function fetchPosts(): Promise { + // const posts = await getPosts(); + // setPosts(posts); + // } + // fetchPosts(); + // } + + // function getItemCount(): number { + // return posts.length; + // } + + const getItem = (_data: unknown, index: number): ItemData => ({ + id: Math.random().toString(12).substring(0), + title: `Item ${index + 1}`, + }); + + // const getItem = async (data: any, index: number): Promise => { + // const p = await getPost(index); + // return p; + // }; return ( - - Hello World! - {posts.map((post) => ( - - ))} - + + } + keyExtractor={(item: ItemData) => item.id} + getItemCount={getItemCount} + getItem={getItem} + /> + ); -} \ No newline at end of file +} diff --git a/src/util/api.ts b/src/util/api.ts index a72078b..3dce0a2 100644 --- a/src/util/api.ts +++ b/src/util/api.ts @@ -63,7 +63,7 @@ export async function getPosts(): Promise { * @param {string} id - The ID of the post to fetch. * @returns {Promise} A promise that resolves to the requested post. */ -export async function getPost(id: string): Promise { +export async function getPost(id: number): Promise { const res = await fetch(URL + `/api/posts/${id}`); const data = await res.json(); return data; diff --git a/src/util/style.ts b/src/util/style.ts index 568bc45..004d332 100644 --- a/src/util/style.ts +++ b/src/util/style.ts @@ -14,19 +14,23 @@ export const style = StyleSheet.create({ backgroundColor: colorScheme.background, // For the "entire" app alignItems: 'center', justifyContent: 'center', + margin: 0, }, postsContainer: { + margin: 0, height: '100%', + width: '100%', padding: 5, - flex: 1, - alignItems: 'center', + paddingVertical: 30, justifyContent: 'flex-start', backgroundColor: colorScheme.background, // For the container holding the posts }, postView: { + borderRadius: 6, flexDirection: "row", backgroundColor: colorScheme.postBox, - paddingVertical: 5, + margin: 5, + padding: 15, }, postFont: { color: colorScheme.postFont, From b59456505aa688a5e480ac7141b25ea34f35bb3d Mon Sep 17 00:00:00 2001 From: Imbus Date: Thu, 14 Dec 2023 23:14:33 +0100 Subject: [PATCH 02/32] Fixing infinite scroll --- src/components/PostsContainer.tsx | 62 ++++++++++++++++++++++++------- src/util/api.ts | 8 +++- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/components/PostsContainer.tsx b/src/components/PostsContainer.tsx index a67ceb5..71da5eb 100644 --- a/src/components/PostsContainer.tsx +++ b/src/components/PostsContainer.tsx @@ -1,26 +1,62 @@ import React from "react"; -import { View, Text } from "react-native"; -import { getPosts, Post } from "../util/api"; +import { RefreshControl } from "react-native"; +import { getPostsInterval, Post } from "../util/api"; import { PostView } from "./PostView"; import { style } from "../util/style"; +import { SafeAreaView } from "react-native"; +import { VirtualizedList } from "react-native"; export function PostsContainer(): JSX.Element { - const [posts, setPosts] = React.useState([]); + const [postData, setPostData] = React.useState([]); + const [page, setPage] = React.useState(0); + const [refreshing, setRefreshing] = React.useState(false); + + const handleEndReached = (): void => { + setPage((prevPage) => prevPage + 1); + }; React.useEffect(() => { + refreshPosts(); + }, [page]); + + function refreshPosts(): void { async function fetchPosts(): Promise { - const posts = await getPosts(); - setPosts(posts); + const newPosts = await getPostsInterval(page*10, 10) + setPostData((oldPosts: Post[]) => [...oldPosts, ...newPosts]); } fetchPosts(); - }, []); + } + function onRefresh(): void { + setRefreshing(true); + setPage(0); + setPostData(postData.slice(0, 10)); + setRefreshing(false); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const getItemCount = (_data: unknown): number => postData.length; + + const getItem = (_data: unknown, index: number): Post => postData[index]; return ( - - Hello World! - {posts.map((post) => ( - - ))} - + + } + keyExtractor={(item: Post) => item.id} + getItemCount={getItemCount} + getItem={getItem} + onEndReached={handleEndReached} + onEndReachedThreshold={0.4} + refreshControl={ + + } + /> + ); -} \ No newline at end of file +} diff --git a/src/util/api.ts b/src/util/api.ts index a72078b..bd3c62e 100644 --- a/src/util/api.ts +++ b/src/util/api.ts @@ -56,6 +56,12 @@ export async function getPosts(): Promise { return data; } +export async function getPostsInterval(offset: number, limit: number): Promise { + const res = await fetch(URL + `/api/posts?offset=${offset}&limit=${limit}`); + const data = await res.json(); + return data; +} + /** * Fetches a specific post by its ID from the API. * @async @@ -63,7 +69,7 @@ export async function getPosts(): Promise { * @param {string} id - The ID of the post to fetch. * @returns {Promise} A promise that resolves to the requested post. */ -export async function getPost(id: string): Promise { +export async function getPost(id: number): Promise { const res = await fetch(URL + `/api/posts/${id}`); const data = await res.json(); return data; From 57b876bf0590378a4a51621a376767e389cfe3ba Mon Sep 17 00:00:00 2001 From: Imbus Date: Thu, 14 Dec 2023 23:14:51 +0100 Subject: [PATCH 03/32] Styling modifications and some formatting --- src/components/PostView.tsx | 2 +- src/util/style.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/PostView.tsx b/src/components/PostView.tsx index 35957b5..c5ea7ea 100644 --- a/src/components/PostView.tsx +++ b/src/components/PostView.tsx @@ -16,7 +16,7 @@ export function PostView({ post }: { post: Post }): JSX.Element { return ( - {thisPost.content} + {thisPost.content} ); } diff --git a/src/util/style.ts b/src/util/style.ts index 568bc45..004d332 100644 --- a/src/util/style.ts +++ b/src/util/style.ts @@ -14,19 +14,23 @@ export const style = StyleSheet.create({ backgroundColor: colorScheme.background, // For the "entire" app alignItems: 'center', justifyContent: 'center', + margin: 0, }, postsContainer: { + margin: 0, height: '100%', + width: '100%', padding: 5, - flex: 1, - alignItems: 'center', + paddingVertical: 30, justifyContent: 'flex-start', backgroundColor: colorScheme.background, // For the container holding the posts }, postView: { + borderRadius: 6, flexDirection: "row", backgroundColor: colorScheme.postBox, - paddingVertical: 5, + margin: 5, + padding: 15, }, postFont: { color: colorScheme.postFont, From 605d0990d3149ee684edda0c77fc8e32c774ec1c Mon Sep 17 00:00:00 2001 From: Imbus Date: Thu, 14 Dec 2023 23:17:34 +0100 Subject: [PATCH 04/32] Reloads now works without duplicating posts --- src/components/PostsContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PostsContainer.tsx b/src/components/PostsContainer.tsx index 71da5eb..50bc8e9 100644 --- a/src/components/PostsContainer.tsx +++ b/src/components/PostsContainer.tsx @@ -29,8 +29,8 @@ export function PostsContainer(): JSX.Element { function onRefresh(): void { setRefreshing(true); + setPostData([]); setPage(0); - setPostData(postData.slice(0, 10)); setRefreshing(false); } From 60c0d4f74665130272c8289a63c2fc1d52ee247b Mon Sep 17 00:00:00 2001 From: Imbus Date: Thu, 14 Dec 2023 23:39:53 +0100 Subject: [PATCH 05/32] Correct color for navbar icons --- App.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/App.tsx b/App.tsx index 01ab652..7548b82 100644 --- a/App.tsx +++ b/App.tsx @@ -3,12 +3,11 @@ import { Text, View } from "react-native"; import { style } from "./src/util/style"; import { PostsContainer } from "./src/components/PostsContainer"; - export default function App(): JSX.Element { return ( + Open up App.tsx to start working on your app! - ); From 3e906f2c6609be176a170ac987742247c7d9dfe9 Mon Sep 17 00:00:00 2001 From: Imbus Date: Thu, 14 Dec 2023 23:51:05 +0100 Subject: [PATCH 06/32] Initial navigation draft --- App.tsx | 26 +++++- package-lock.json | 197 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 6 +- src/util/style.ts | 31 +++++--- 4 files changed, 243 insertions(+), 17 deletions(-) diff --git a/App.tsx b/App.tsx index 7548b82..25d910f 100644 --- a/App.tsx +++ b/App.tsx @@ -1,13 +1,35 @@ import { StatusBar } from "expo-status-bar"; -import { Text, View } from "react-native"; +import { View } from "react-native"; import { style } from "./src/util/style"; import { PostsContainer } from "./src/components/PostsContainer"; +import { NavigationContainer } from "@react-navigation/native"; +import { createNativeStackNavigator } from "@react-navigation/native-stack"; + +const Stack = createNativeStackNavigator(); + export default function App(): JSX.Element { + return ( + + + + + + ); +} + +function HomeScreen(): JSX.Element { return ( - Open up App.tsx to start working on your app! ); diff --git a/package-lock.json b/package-lock.json index a97159c..5dfd7a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,14 @@ "name": "frostbyte-native", "version": "1.0.0", "dependencies": { + "@react-navigation/native": "^6.1.9", + "@react-navigation/native-stack": "^6.9.17", "expo": "~49.0.15", "expo-status-bar": "~1.6.0", "react": "18.2.0", - "react-native": "0.72.6" + "react-native": "0.72.6", + "react-native-safe-area-context": "4.6.3", + "react-native-screens": "~3.22.0" }, "devDependencies": { "@babel/core": "^7.20.0", @@ -5994,6 +5998,99 @@ "react-native": "*" } }, + "node_modules/@react-navigation/core": { + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", + "integrity": "sha512-oYhqxETRHNHKsipm/BtGL0LI43Hs2VSFoWMbBdHK9OqgQPjTVUitslgLcPpo4zApCcmBWoOLX2qPxhsBda644A==", + "dependencies": { + "@react-navigation/routers": "^6.1.9", + "escape-string-regexp": "^4.0.0", + "nanoid": "^3.1.23", + "query-string": "^7.1.3", + "react-is": "^16.13.0", + "use-latest-callback": "^0.1.7" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@react-navigation/core/node_modules/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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-navigation/core/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/@react-navigation/elements": { + "version": "1.3.21", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.21.tgz", + "integrity": "sha512-eyS2C6McNR8ihUoYfc166O1D8VYVh9KIl0UQPI8/ZJVsStlfSTgeEEh+WXge6+7SFPnZ4ewzEJdSAHH+jzcEfg==", + "peerDependencies": { + "@react-navigation/native": "^6.0.0", + "react": "*", + "react-native": "*", + "react-native-safe-area-context": ">= 3.0.0" + } + }, + "node_modules/@react-navigation/native": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.9.tgz", + "integrity": "sha512-AMuJDpwXE7UlfyhIXaUCCynXmv69Kb8NzKgKJO7v0k0L+u6xUTbt6xvshmJ79vsvaFyaEH9Jg5FMzek5/S5qNw==", + "dependencies": { + "@react-navigation/core": "^6.4.10", + "escape-string-regexp": "^4.0.0", + "fast-deep-equal": "^3.1.3", + "nanoid": "^3.1.23" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/@react-navigation/native-stack": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.17.tgz", + "integrity": "sha512-X8p8aS7JptQq7uZZNFEvfEcPf6tlK4PyVwYDdryRbG98B4bh2wFQYMThxvqa+FGEN7USEuHdv2mF0GhFKfX0ew==", + "dependencies": { + "@react-navigation/elements": "^1.3.21", + "warn-once": "^0.1.0" + }, + "peerDependencies": { + "@react-navigation/native": "^6.0.0", + "react": "*", + "react-native": "*", + "react-native-safe-area-context": ">= 3.0.0", + "react-native-screens": ">= 3.0.0" + } + }, + "node_modules/@react-navigation/native/node_modules/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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-navigation/routers": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz", + "integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==", + "dependencies": { + "nanoid": "^3.1.23" + } + }, "node_modules/@segment/loosely-validate-event": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz", @@ -7618,6 +7715,14 @@ "node": ">=0.10.0" } }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -8546,8 +8651,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -8668,6 +8772,14 @@ "node": ">=8" } }, + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -12741,6 +12853,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -12849,6 +12978,17 @@ } } }, + "node_modules/react-freeze": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.3.tgz", + "integrity": "sha512-ZnXwLQnGzrDpHBHiC56TXFXvmolPeMjTn1UOm610M4EXGzbEDR7oOIyS2ZiItgbs6eZc4oU/a0hpk8PrcKvv5g==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=17.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -12906,6 +13046,28 @@ "react": "18.2.0" } }, + "node_modules/react-native-safe-area-context": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.6.3.tgz", + "integrity": "sha512-3CeZM9HFXkuqiU9HqhOQp1yxhXw6q99axPWrT+VJkITd67gnPSU03+U27Xk2/cr9XrLUnakM07kj7H0hdPnFiQ==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-screens": { + "version": "3.22.1", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.22.1.tgz", + "integrity": "sha512-ffzwUdVKf+iLqhWSzN5DXBm0s2w5sN0P+TaHHPAx42LT7+DT0g8PkHT1QDvxpR5vCEPSS1i3EswyVK4HCuhTYg==", + "dependencies": { + "react-freeze": "^1.0.0", + "warn-once": "^0.1.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native/node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", @@ -13507,6 +13669,14 @@ "node": "*" } }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "engines": { + "node": ">=6" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -13582,6 +13752,14 @@ "node": ">= 0.10.0" } }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -14273,6 +14451,14 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-latest-callback": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.9.tgz", + "integrity": "sha512-CL/29uS74AwreI/f2oz2hLTW7ZqVeV5+gxFeGudzQrgkCytrHw33G4KbnQOrRlAEzzAFXi7dDLMC9zhWcVpzmw==", + "peerDependencies": { + "react": ">=16.8" + } + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", @@ -14337,6 +14523,11 @@ "makeerror": "1.0.12" } }, + "node_modules/warn-once": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz", + "integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==" + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index f8458e1..da6988b 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,14 @@ "lint": "tsc --noEmit && eslint --ext .js,.jsx,.ts,.tsx ./" }, "dependencies": { + "@react-navigation/native": "^6.1.9", + "@react-navigation/native-stack": "^6.9.17", "expo": "~49.0.15", "expo-status-bar": "~1.6.0", "react": "18.2.0", - "react-native": "0.72.6" + "react-native": "0.72.6", + "react-native-safe-area-context": "4.6.3", + "react-native-screens": "~3.22.0" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/src/util/style.ts b/src/util/style.ts index 004d332..c80a90b 100644 --- a/src/util/style.ts +++ b/src/util/style.ts @@ -1,28 +1,29 @@ -import { StyleSheet } from 'react-native'; +import { StyleSheet } from "react-native"; const colorScheme = { background: "#273043", postBox: "#9197AE", postFont: "#EFF6EE", accept: "#4D8B31", - error: "#F02D3A" -} + error: "#F02D3A", +}; export const style = StyleSheet.create({ - app: { // Outermost container + app: { + // Outermost container flex: 1, backgroundColor: colorScheme.background, // For the "entire" app - alignItems: 'center', - justifyContent: 'center', + alignItems: "center", + justifyContent: "center", margin: 0, }, postsContainer: { margin: 0, - height: '100%', - width: '100%', + height: "100%", + width: "100%", padding: 5, - paddingVertical: 30, - justifyContent: 'flex-start', + paddingBottom: 10, + justifyContent: "flex-start", backgroundColor: colorScheme.background, // For the container holding the posts }, postView: { @@ -35,4 +36,12 @@ export const style = StyleSheet.create({ postFont: { color: colorScheme.postFont, }, -}); \ No newline at end of file + header: { + backgroundColor: colorScheme.background, + }, + headerTitle: { + fontSize: 20, + fontWeight: "bold", + color: colorScheme.postFont, + }, +}); From 3855a587a081fea73590e2e53670554f0ed74d6e Mon Sep 17 00:00:00 2001 From: Imbus Date: Fri, 15 Dec 2023 01:19:54 +0100 Subject: [PATCH 07/32] Boilerplate for NewPostContainer --- src/components/NewPostContainer.tsx | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/components/NewPostContainer.tsx diff --git a/src/components/NewPostContainer.tsx b/src/components/NewPostContainer.tsx new file mode 100644 index 0000000..3257858 --- /dev/null +++ b/src/components/NewPostContainer.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import { View, Text, TextInput, Button } from "react-native"; +import { style } from "../util/style"; +import { createPost, NewPost } from "../util/api"; + +export function NewPostContainer(): JSX.Element { + const [currentInput, setCurrentInput] = React.useState(""); + const [currentInputError, setCurrentInputError] = React.useState(""); + + return ( + + { + setCurrentInput(text); + setCurrentInputError(""); + }} + value={currentInput} + /> +