From de78feed22d2a1f43e0fe4d22afa0dbf48434c2e Mon Sep 17 00:00:00 2001 From: MSG <59928086+MSghais@users.noreply.github.com> Date: Wed, 21 Aug 2024 23:04:17 +0200 Subject: [PATCH] Release/od hack lfg (#41) * ui tip + todo defi screen * backend + readme + start search base * add linking for web * init screen * init hooks private group --- apps/data-backend/README.Md | 18 ++ apps/data-backend/src/index.js | 40 --- apps/data-backend/src/index.ts | 1 - .../data-backend/src/services/telegram-app.ts | 1 + apps/mobile/src/app/Router.tsx | 132 ++++++---- apps/mobile/src/assets/icons.tsx | 92 +------ .../src/components/PrivateKeyImport/index.tsx | 4 +- .../src/components/RelaysConfig/index.tsx | 96 ++++---- .../src/components/RelaysConfig/styles.ts | 19 +- .../{ => pump}/TokenLaunchDetail/index.tsx | 34 ++- .../{ => pump}/TokenLaunchDetail/styles.ts | 2 +- .../{ => search}/TokenLaunchCard/index.tsx | 34 ++- .../{ => search}/TokenLaunchCard/styles.ts | 2 +- apps/mobile/src/components/search/index.tsx | 5 + .../mobile/src/context/Toast/ToastContext.tsx | 4 +- apps/mobile/src/context/Toast/styles.ts | 3 - .../src/modules/Layout/auth-sidebar/index.tsx | 16 +- .../src/modules/Layout/auth-sidebar/styles.ts | 2 +- apps/mobile/src/modules/Post/index.tsx | 42 +++- apps/mobile/src/modules/TipModal/index.tsx | 16 +- .../src/modules/TipModal/lightning/form.tsx | 114 +++++++++ .../src/modules/TipModal/lightning/index.tsx | 230 ++++++++++++++++++ .../src/modules/TipModal/lightning/styles.ts | 111 +++++++++ apps/mobile/src/screens/Defi/index.tsx | 23 +- apps/mobile/src/screens/Feed/index.tsx | 34 ++- .../mobile/src/screens/LaunchDetail/index.tsx | 2 +- .../screens/Launchpad/LaunchpadComponent.tsx | 3 +- .../src/screens/PrivateGroupDetail/index.tsx | 82 +++++++ .../src/screens/PrivateGroupDetail/styles.ts | 36 +++ apps/mobile/src/screens/Search/index.tsx | 14 +- apps/mobile/src/screens/Settings/index.tsx | 32 +-- apps/mobile/src/screens/Settings/styles.ts | 3 +- apps/mobile/src/screens/Tips/index.tsx | 5 +- apps/mobile/src/types/keys.ts | 4 +- apps/mobile/src/types/routes.ts | 9 + apps/mobile/src/types/tab.ts | 39 +++ .../src/hooks/group/private/useAddMember.ts | 22 ++ .../hooks/group/private/useAddPermissions.ts | 22 ++ .../src/hooks/group/private/useCreateGroup.ts | 22 ++ .../src/hooks/group/private/useDeleteEvent.ts | 22 ++ .../hooks/group/private/useRemoveMember.ts | 22 ++ .../group/private/useRemovePermissions.ts | 22 ++ .../group/private/useSendGroupMessage.ts | 22 ++ setuprelay.md | 5 +- turbo.json | 6 +- 45 files changed, 1128 insertions(+), 341 deletions(-) create mode 100644 apps/data-backend/README.Md delete mode 100644 apps/data-backend/src/index.js rename apps/mobile/src/components/{ => pump}/TokenLaunchDetail/index.tsx (85%) rename apps/mobile/src/components/{ => pump}/TokenLaunchDetail/styles.ts (91%) rename apps/mobile/src/components/{ => search}/TokenLaunchCard/index.tsx (85%) rename apps/mobile/src/components/{ => search}/TokenLaunchCard/styles.ts (91%) create mode 100644 apps/mobile/src/modules/TipModal/lightning/form.tsx create mode 100644 apps/mobile/src/modules/TipModal/lightning/index.tsx create mode 100644 apps/mobile/src/modules/TipModal/lightning/styles.ts create mode 100644 apps/mobile/src/screens/PrivateGroupDetail/index.tsx create mode 100644 apps/mobile/src/screens/PrivateGroupDetail/styles.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useAddMember.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useAddPermissions.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useCreateGroup.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useDeleteEvent.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useRemoveMember.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useRemovePermissions.ts create mode 100644 packages/afk_nostr_sdk/src/hooks/group/private/useSendGroupMessage.ts diff --git a/apps/data-backend/README.Md b/apps/data-backend/README.Md new file mode 100644 index 000000000..dbde46c18 --- /dev/null +++ b/apps/data-backend/README.Md @@ -0,0 +1,18 @@ +# Backend of AFK + +## Description +Express typescript backend. +Routes for Indexer. +Telegram bot answers for AFK Mini app. + +## TODO + +- [] Telegram Alert for Event on AFK +- [] Gamification + +## Kill process issues +``` +sudo lsof -t -i:5050 + +sudo kill -9 [ID_RECEIVED_BEFORE] +``` \ No newline at end of file diff --git a/apps/data-backend/src/index.js b/apps/data-backend/src/index.js deleted file mode 100644 index ce75ce5d2..000000000 --- a/apps/data-backend/src/index.js +++ /dev/null @@ -1,40 +0,0 @@ -import express from "express"; -import {server} from "./graphql" -import dotenv from "dotenv"; -import router from "./router"; -import helmet from "helmet" -import { launchBot, sendWebAppButton } from "./services/telegram-app"; -const cors = require("cors") -dotenv.config(); -const app = express(); -app.use(cors()) -app.use(helmet()) -// Alternatively, you can configure CORS for specific routes or origins -app.use(cors({ - origin: 'http://localhost:8081' // Adjust this to match the URL of your React Native web version if necessary -})); -app.use(express.urlencoded({ extended: false })) -app.use(express.json()) -// app.use(cors) -// app.use(express.urlencoded({ extended: false })) -// app.use(express.json()) -// Start the Backend -const port = process.env.PORT || 5050; -app.use('/', router) -app.use('/telegram-app', router) - -app.listen(port, () => { - console.log(`🚀 Backend server running at http://localhost:${port}`); - try { - launchBot(process.env.TELEGRAM_BOT_TOKEN) - - }catch(e) { - - } - // sendWebAppButton(process.env.TG_ADMIN_CHAT_ID) -}); - -// Start the server GraphQL -// server.listen().then(({ url }) => { -// console.log(`🚀 Backend server running at http://localhost:${port}/graphql`); -// }); diff --git a/apps/data-backend/src/index.ts b/apps/data-backend/src/index.ts index ce75ce5d2..b4cc48722 100644 --- a/apps/data-backend/src/index.ts +++ b/apps/data-backend/src/index.ts @@ -27,7 +27,6 @@ app.listen(port, () => { console.log(`🚀 Backend server running at http://localhost:${port}`); try { launchBot(process.env.TELEGRAM_BOT_TOKEN) - }catch(e) { } diff --git a/apps/data-backend/src/services/telegram-app.ts b/apps/data-backend/src/services/telegram-app.ts index 156c82f25..a505f35f3 100644 --- a/apps/data-backend/src/services/telegram-app.ts +++ b/apps/data-backend/src/services/telegram-app.ts @@ -62,6 +62,7 @@ function listenToCommands(bot) { reply_markup: { inline_keyboard: [ [{ text: "Start Mini App", web_app: { url: process.env.TELEGRAM_WEB_APP } }], + [{ text: "Start AFK", web_app: { url: process.env.TELEGRAM_MOBILE_APP } }], ] } }) diff --git a/apps/mobile/src/app/Router.tsx b/apps/mobile/src/app/Router.tsx index e970f403a..f0c1886d9 100644 --- a/apps/mobile/src/app/Router.tsx +++ b/apps/mobile/src/app/Router.tsx @@ -1,38 +1,38 @@ -import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; -import { createDrawerNavigator } from '@react-navigation/drawer'; -import { NavigationContainer } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { useAuth } from 'afk_nostr_sdk'; -import { useEffect, useMemo, useState } from 'react'; -import { Dimensions, Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; +import {createDrawerNavigator} from '@react-navigation/drawer'; +import {NavigationContainer} from '@react-navigation/native'; +import {createNativeStackNavigator} from '@react-navigation/native-stack'; +import {useAuth} from 'afk_nostr_sdk'; +import {useEffect, useMemo, useState} from 'react'; +import {Dimensions, Platform, StyleSheet, useWindowDimensions, View} from 'react-native'; -import { Icon } from '../components'; -import { Navbar } from '../components/Navbar'; -import { useStyles, useTheme } from '../hooks'; -import Sidebar from '../modules/Layout/sidebar'; +import {Icon} from '../components'; +import {Navbar} from '../components/Navbar'; +import {useStyles, useTheme} from '../hooks'; import AuthSidebar from '../modules/Layout/auth-sidebar'; -import { CreateAccount } from '../screens/Auth/CreateAccount'; -import { ImportKeys } from '../screens/Auth/ImportKeys'; -import { Login } from '../screens/Auth/Login'; -import { SaveKeys } from '../screens/Auth/SaveKeys'; -import { ChannelDetail } from '../screens/ChannelDetail'; -import { ChannelsFeed } from '../screens/ChannelsFeed'; -import { CreateChannel } from '../screens/CreateChannel'; -import { CreateForm } from '../screens/CreateForm'; -import { CreatePost } from '../screens/CreatePost'; -import { Defi } from '../screens/Defi'; -import { EditProfile } from '../screens/EditProfile'; -import { Feed } from '../screens/Feed'; -import { Games } from '../screens/Games'; -import { LaunchDetail } from '../screens/LaunchDetail'; -import { PostDetail } from '../screens/PostDetail'; -import { Profile } from '../screens/Profile'; -import { Search } from '../screens/Search'; -import { Settings } from '../screens/Settings'; -import { Tips } from '../screens/Tips'; -import { ThemedStyleSheet } from '../styles'; -import { AuthStackParams, HomeBottomStackParams, MainStackParams, RootStackParams } from '../types'; -import { retrievePublicKey } from '../utils/storage'; +import Sidebar from '../modules/Layout/sidebar'; +import {CreateAccount} from '../screens/Auth/CreateAccount'; +import {ImportKeys} from '../screens/Auth/ImportKeys'; +import {Login} from '../screens/Auth/Login'; +import {SaveKeys} from '../screens/Auth/SaveKeys'; +import {ChannelDetail} from '../screens/ChannelDetail'; +import {ChannelsFeed} from '../screens/ChannelsFeed'; +import {CreateChannel} from '../screens/CreateChannel'; +import {CreateForm} from '../screens/CreateForm'; +import {CreatePost} from '../screens/CreatePost'; +import {Defi} from '../screens/Defi'; +import {EditProfile} from '../screens/EditProfile'; +import {Feed} from '../screens/Feed'; +import {Games} from '../screens/Games'; +import {LaunchDetail} from '../screens/LaunchDetail'; +import {PostDetail} from '../screens/PostDetail'; +import {Profile} from '../screens/Profile'; +import {Search} from '../screens/Search'; +import {Settings} from '../screens/Settings'; +import {Tips} from '../screens/Tips'; +import {ThemedStyleSheet} from '../styles'; +import {AuthStackParams, HomeBottomStackParams, MainStackParams, RootStackParams} from '../types'; +import {retrievePublicKey} from '../utils/storage'; const DrawerStack = createDrawerNavigator(); const RootStack = createNativeStackNavigator(); @@ -44,8 +44,8 @@ const HomeBottomTabsStack = createBottomTabNavigator(); const HomeBottomTabNavigator: React.FC = () => { const styles = useStyles(stylesheet); - const { publicKey } = useAuth(); - const { theme } = useTheme(); + const {publicKey} = useAuth(); + const {theme} = useTheme(); return ( { options={{ tabBarActiveTintColor: 'white', tabBarInactiveTintColor: theme.colors.background, - tabBarIcon: ({ focused }) => ( + tabBarIcon: ({focused}) => ( { options={{ tabBarActiveTintColor: 'white', tabBarInactiveTintColor: 'grey', - tabBarIcon: ({ focused }) => ( + tabBarIcon: ({focused}) => ( { options={{ tabBarActiveTintColor: 'white', tabBarInactiveTintColor: 'grey', - tabBarIcon: ({ focused }) => ( + tabBarIcon: ({focused}) => ( { ( + tabBarIcon: ({focused}) => ( { options={{ tabBarActiveTintColor: 'white', tabBarInactiveTintColor: 'grey', - tabBarIcon: ({ focused }) => ( + tabBarIcon: ({focused}) => ( { if (publicKey === undefined) return null; return ( - } - screenOptions={({ navigation }) => ({ + screenOptions={({navigation}) => ({ // headerShown:false, // header: () => , - headerShown:false, + headerShown: false, headerStyle: { backgroundColor: theme.theme.colors.background, }, @@ -193,7 +193,7 @@ const AuthNavigator: React.FC = () => { overlayColor: isDesktop ? 'transparent' : theme.theme.colors.background, // Make sure overlay settings are correct // swipeEdgeWidth: 0 drawerStyle: { - width: "25%", // Adjust width or other styling as necessary + width: '25%', // Adjust width or other styling as necessary }, })} > @@ -218,7 +218,7 @@ const MainNavigator: React.FC = () => { // screenOptions={{ headerShown: false }} // initialRouteName="Home" drawerContent={(props) => } - screenOptions={({ navigation }) => ({ + screenOptions={({navigation}) => ({ // headerShown:false, header: () => , headerStyle: { @@ -283,14 +283,37 @@ const MainNavigator: React.FC = () => { const linking = { prefixes: [ - // "home","search", "profile/:publicKey", "details/:id" + 'home', + 'search', + 'profile/:publicKey', + 'details/:id', /* your linking prefixes */ ], config: { screens: { Home: 'home', + MainStack: 'app', Menu: 'menu', Search: 'search', + AuthStack: 'auth', + Feed: 'feed', + ImportKeys: 'import-keys', + KeysMarketplace: 'keys-marketplace', + CreateChannel: 'create-channel', + CreateForm: 'create-form', + EditProfile: 'edit-profile', + Launchpad: 'launchpad', + LaunchToken: 'launch-token', + Games: 'games', + Defi: 'defi', + Settings: 'settings', + Tips: 'Tips', + ChannelDetail: { + path: 'channel/:publicKey', // Example of a path with a parameter + parse: { + id: (id: any) => `${id}`, // Convert the id from the URL to a string, if needed + }, + }, Details: { path: 'profile/:publicKey', // Example of a path with a parameter parse: { @@ -298,20 +321,25 @@ const linking = { }, }, Profile: { - path: 'details/:id', // Example of a path with a parameter + path: 'profile/nostr/', // Example of a path with a parameter parse: { id: (id: any) => `${id}`, // Convert the id from the URL to a string, if needed }, + + // path: 'details/:id', // Example of a path with a parameter + // parse: { + // id: (id: any) => `${id}`, // Convert the id from the URL to a string, if needed + // }, }, }, }, }; const RootNavigator: React.FC = () => { - const { publicKey } = useAuth(); + const {publicKey} = useAuth(); return ( - + {/* */} {publicKey ? ( @@ -327,9 +355,7 @@ export const Router: React.FC = () => { const windowWidth = Dimensions.get('window').width; const shouldShowSidebar = isWeb && windowWidth >= 1024; return ( - + {/* {shouldShowSidebar && } */} diff --git a/apps/mobile/src/assets/icons.tsx b/apps/mobile/src/assets/icons.tsx index bb32ff1d8..9400c6b3e 100644 --- a/apps/mobile/src/assets/icons.tsx +++ b/apps/mobile/src/assets/icons.tsx @@ -242,6 +242,18 @@ export const LikeIcon: React.FC = (props) => { ); }; +export const BookmarkIcon: React.FC = (props) => ( + + + +); + export const LikeFillIcon: React.FC = (props) => { return ( @@ -574,98 +586,18 @@ export const MoonIcon: React.FC = (props) => ( ); -// export const SearchIcon: React.FC = (props) => ( -// -// -// -// ); -{ - /* - - - - - */ -} - -// export const GameIcon: React.FC = (props) => { -// return ( -// -// -// -// ) -// } - -{ - /* - - - - - - - - - - - - - - - */ -} - export const MenuIcon: React.FC = (props) => ( - {/* d="M87.2,56.7c1.1-2.2,1.8-4.6,1.8-7.2c0-6.6-4.2-12.3-10-14.5c0,0,0,0,0,0c0-11.6-9.4-21-21-21 c-9.8,0-18,6.7-20.3,15.8c-1.5-0.5-3-0.8-4.7-0.8c-7.7,0-14,5.8-14.9,13.3C12.9,43.4,9,48,9,53.5C9,59.9,14.1,65,20.5,65 c0.2,0,0.4,0,0.5,0c0,0.2,0,0.3,0,0.5C21,76.8,30.2,86,41.5,86c6.4,0,12.2-3,15.9-7.6c2.2,2.2,5.2,3.6,8.6,3.6 c4.7,0,8.7-2.7,10.7-6.5c1.1,0.3,2.2,0.5,3.3,0.5c6.1,0,11-4.9,11-11C91,61.7,89.5,58.7,87.2,56.7z"> */} - - // /> - {/* d="M87.2,56.7c1.1-2.2,1.8-4.6,1.8-7.2c0-6.6-4.2-12.3-10-14.5c0,0,0,0,0,0c0-11.6-9.4-21-21-21 c-9.8,0-18,6.7-20.3,15.8c-1.5-0.5-3-0.8-4.7-0.8c-7.7,0-14,5.8-14.9,13.3C12.9,43.4,9,48,9,53.5C9,59.9,14.1,65,20.5,65 c0.2,0,0.4,0,0.5,0c0,0.2,0,0.3,0,0.5C21,76.8,30.2,86,41.5,86c6.4,0,12.2-3,15.9-7.6c2.2,2.2,5.2,3.6,8.6,3.6 c4.7,0,8.7-2.7,10.7-6.5c1.1,0.3,2.2,0.5,3.3,0.5c6.1,0,11-4.9,11-11C91,61.7,89.5,58.7,87.2,56.7z" */} - - {/* d="M87.2,56.7c1.1-2.2,1.8-4.6,1.8-7.2c0-6.6-4.2-12.3-10-14.5c0,0,0,0,0,0c0-11.6-9.4-21-21-21 c-9.8,0-18,6.7-20.3,15.8c-1.5-0.5-3-0.8-4.7-0.8c-7.7,0-14,5.8-14.9,13.3C12.9,43.4,9,48,9,53.5C9,59.9,14.1,65,20.5,65 c0.2,0,0.4,0,0.5,0c0,0.2,0,0.3,0,0.5C21,76.8,30.2,86,41.5,86c6.4,0,12.2-3,15.9-7.6c2.2,2.2,5.2,3.6,8.6,3.6 c4.7,0,8.7-2.7,10.7-6.5c1.1,0.3,2.2,0.5,3.3,0.5c6.1,0,11-4.9,11-11C91,61.7,89.5,58.7,87.2,56.7z" */} ); -// export const MenuIcon: React.FC = (props) => ( -// -// -// -// -// ); diff --git a/apps/mobile/src/components/PrivateKeyImport/index.tsx b/apps/mobile/src/components/PrivateKeyImport/index.tsx index be8c31a7a..4698c388b 100644 --- a/apps/mobile/src/components/PrivateKeyImport/index.tsx +++ b/apps/mobile/src/components/PrivateKeyImport/index.tsx @@ -2,7 +2,7 @@ import {useTheme} from '@react-navigation/native'; import {useAuth} from 'afk_nostr_sdk'; import * as Clipboard from 'expo-clipboard'; import {useState} from 'react'; -import {Pressable, TouchableOpacity, View} from 'react-native'; +import {TouchableOpacity, View} from 'react-native'; import {CopyIconStack, LockIcon} from '../../assets/icons'; import {useToast} from '../../hooks/modals'; @@ -12,10 +12,10 @@ import { retrievePassword, retrievePublicKey, } from '../../utils/storage'; +import {Button} from '../Button'; import {Input} from '../Input'; import {Text} from '../Text'; import styles from './styles'; -import { Button } from '../Button'; export const PrivateKeyImport: React.FC = () => { const {publicKey, isExtension, privateKey, setAuth} = useAuth(); diff --git a/apps/mobile/src/components/RelaysConfig/index.tsx b/apps/mobile/src/components/RelaysConfig/index.tsx index 3cda62967..ce1af7ccb 100644 --- a/apps/mobile/src/components/RelaysConfig/index.tsx +++ b/apps/mobile/src/components/RelaysConfig/index.tsx @@ -1,57 +1,58 @@ -import { useSettingsStore } from 'afk_nostr_sdk'; -import { useState } from 'react'; -import { View } from 'react-native'; -import { useToast } from '../../hooks/modals'; -import { Input } from '../Input'; -import { Text } from '../Text'; -import { useStyles } from '../../hooks'; -import { Button } from '../Button'; -import { AFK_RELAYS } from 'afk_nostr_sdk/src/utils/relay'; +import {useSettingsStore} from 'afk_nostr_sdk'; +import {AFK_RELAYS} from 'afk_nostr_sdk/src/utils/relay'; +import {useState} from 'react'; +import {View} from 'react-native'; + +import {useStyles} from '../../hooks'; +import {useToast} from '../../hooks/modals'; +import {Button} from '../Button'; +import {Input} from '../Input'; +import {Text} from '../Text'; import stylesheet from './styles'; export const RelaysConfig: React.FC = () => { - const { showToast } = useToast(); - const styles = useStyles(stylesheet) - const { relays, setRelays } = useSettingsStore(); + const {showToast} = useToast(); + const styles = useStyles(stylesheet); + const {relays, setRelays} = useSettingsStore(); const RELAYS_USED = relays; const AFK_DEFAULT_RELAYS = AFK_RELAYS; - const [relaysUpdated, setRelaysUpdated] = useState(relays) - const [openUpdateMenu, setOpenUpdateMenu] = useState(false) - const [relayToAdd, setRelayToAdd] = useState() + const [relaysUpdated, setRelaysUpdated] = useState(relays); + const [openUpdateMenu, setOpenUpdateMenu] = useState(false); + const [relayToAdd, setRelayToAdd] = useState(); const removeRelay = (relay: string) => { - const newRelays = relaysUpdated.filter((r) => r != relay) - console.log("newRelays") - setRelaysUpdated(newRelays) - } + const newRelays = relaysUpdated.filter((r) => r != relay); + console.log('newRelays'); + setRelaysUpdated(newRelays); + }; const addRelay = (relay?: string) => { if (!relay) { - showToast({ type: "error", title: 'Add a relay' }); + showToast({type: 'error', title: 'Add a relay'}); return; } - if (!relay?.includes("wss://")) { - showToast({ type: "error", title: 'add wss://' }); + if (!relay?.includes('wss://')) { + showToast({type: 'error', title: 'add wss://'}); return; } - const newRelays = [...relaysUpdated, relay] + const newRelays = [...relaysUpdated, relay]; /** @TODO add verify validity of the relayer */ - setRelaysUpdated(newRelays) - } + setRelaysUpdated(newRelays); + }; const updateRelayToUsed = () => { - setRelays(relaysUpdated) - } + setRelays(relaysUpdated); + }; const resetDefault = () => { - setRelays(AFK_DEFAULT_RELAYS) - setRelaysUpdated(AFK_DEFAULT_RELAYS) - } + setRelays(AFK_DEFAULT_RELAYS); + setRelaysUpdated(AFK_DEFAULT_RELAYS); + }; const handleOpenMenu = () => { - setOpenUpdateMenu(!openUpdateMenu) - } + setOpenUpdateMenu(!openUpdateMenu); + }; return ( @@ -60,36 +61,29 @@ export const RelaysConfig: React.FC = () => { {RELAYS_USED?.map((r, i) => { return ( - - Relay: {r} - + Relay: {r} ); })} You can setup your relays - - {openUpdateMenu && + {openUpdateMenu && ( {relaysUpdated?.map((r, i) => { return ( - - Relay: {r} - + Relay: {r} - - } - + )} ); }; diff --git a/apps/mobile/src/components/RelaysConfig/styles.ts b/apps/mobile/src/components/RelaysConfig/styles.ts index 0910ac3cf..367bd3b27 100644 --- a/apps/mobile/src/components/RelaysConfig/styles.ts +++ b/apps/mobile/src/components/RelaysConfig/styles.ts @@ -1,20 +1,19 @@ -import { Spacing, ThemedStyleSheet } from '../../styles'; +import {Spacing, ThemedStyleSheet} from '../../styles'; export default ThemedStyleSheet((theme) => ({ container: { marginHorizontal: 10, - alignItems:"center" + alignItems: 'center', }, relayItem: { - flex:1, - flexDirection:"row", - gap:3, - alignItems:"center" + flex: 1, + flexDirection: 'row', + gap: 3, + alignItems: 'center', }, relayText: { - width:"100%" - }, - relayButton: { + width: '100%', }, + relayButton: {}, title: { color: theme.colors.text, fontSize: 24, @@ -37,7 +36,7 @@ export default ThemedStyleSheet((theme) => ({ borderRadius: 15, }, button: { - marginVertical: 5 + marginVertical: 5, }, name: { diff --git a/apps/mobile/src/components/TokenLaunchDetail/index.tsx b/apps/mobile/src/components/pump/TokenLaunchDetail/index.tsx similarity index 85% rename from apps/mobile/src/components/TokenLaunchDetail/index.tsx rename to apps/mobile/src/components/pump/TokenLaunchDetail/index.tsx index bef57f9d2..72e880535 100644 --- a/apps/mobile/src/components/TokenLaunchDetail/index.tsx +++ b/apps/mobile/src/components/pump/TokenLaunchDetail/index.tsx @@ -6,18 +6,18 @@ import {useProfile} from 'afk_nostr_sdk'; import {useState} from 'react'; import {ImageSourcePropType, View} from 'react-native'; -import {useStyles, useWaitConnection} from '../../hooks'; -import {useBuyCoinByQuoteAmount} from '../../hooks/launchpad/useBuyCoinByQuoteAmount'; -import {useSellCoin} from '../../hooks/launchpad/useSellCoin'; -import {useWalletModal} from '../../hooks/modals'; +import {useStyles, useWaitConnection} from '../../../hooks'; +import {useBuyCoinByQuoteAmount} from '../../../hooks/launchpad/useBuyCoinByQuoteAmount'; +import {useSellCoin} from '../../../hooks/launchpad/useSellCoin'; +import {useWalletModal} from '../../../hooks/modals'; // import {useProfile} from '../../hooks'; -import {MainStackNavigationProps} from '../../types'; -import {TokenLaunchInterface} from '../../types/keys'; -import {feltToAddress} from '../../utils/format'; -import {decimalsScale} from '../../utils/helpers'; -import {Button} from '../Button'; -import {Input} from '../Input'; -import {Text} from '../Text'; +import {MainStackNavigationProps} from '../../../types'; +import {TokenLaunchInterface} from '../../../types/keys'; +import {feltToAddress} from '../../../utils/format'; +import {decimalsScale} from '../../../utils/helpers'; +import {Button} from '../../Button'; +import {Input} from '../../Input'; +import {Text} from '../../Text'; import stylesheet from './styles'; export type LaunchCoinProps = { @@ -162,6 +162,18 @@ export const TokenLaunchDetail: React.FC = ({ } */} + + {launch?.threshold_liquidity && ( + Threshold liquidity: {Number(launch?.threshold_liquidity)} + )} + + {launch?.liquidity_raised && Raised: {Number(launch?.liquidity_raised)}} + + {launch?.is_liquidity_launch && ( + Is launched in DEX: {Number(launch?.is_liquidity_launch)} + )} + + {launch?.token_quote && ( ({ container: { // alignItems: 'center', diff --git a/apps/mobile/src/components/TokenLaunchCard/index.tsx b/apps/mobile/src/components/search/TokenLaunchCard/index.tsx similarity index 85% rename from apps/mobile/src/components/TokenLaunchCard/index.tsx rename to apps/mobile/src/components/search/TokenLaunchCard/index.tsx index 5b6aae713..946b1ccdb 100644 --- a/apps/mobile/src/components/TokenLaunchCard/index.tsx +++ b/apps/mobile/src/components/search/TokenLaunchCard/index.tsx @@ -6,18 +6,18 @@ import {useProfile} from 'afk_nostr_sdk'; import {useState} from 'react'; import {ImageSourcePropType, View} from 'react-native'; -import {useStyles, useWaitConnection} from '../../hooks'; -import {useBuyCoinByQuoteAmount} from '../../hooks/launchpad/useBuyCoinByQuoteAmount'; -import {useSellCoin} from '../../hooks/launchpad/useSellCoin'; -import {useWalletModal} from '../../hooks/modals'; +import {useStyles, useWaitConnection} from '../../../hooks'; +import {useBuyCoinByQuoteAmount} from '../../../hooks/launchpad/useBuyCoinByQuoteAmount'; +import {useSellCoin} from '../../../hooks/launchpad/useSellCoin'; +import {useWalletModal} from '../../../hooks/modals'; // import {useProfile} from '../../hooks'; -import {MainStackNavigationProps} from '../../types'; -import {TokenLaunchInterface} from '../../types/keys'; -import {feltToAddress} from '../../utils/format'; -import {decimalsScale} from '../../utils/helpers'; -import {Button} from '../Button'; -import {Input} from '../Input'; -import {Text} from '../Text'; +import {MainStackNavigationProps} from '../../../types'; +import {TokenLaunchInterface} from '../../../types/keys'; +import {feltToAddress} from '../../../utils/format'; +import {decimalsScale} from '../../../utils/helpers'; +import {Button} from '../../Button'; +import {Input} from '../../Input'; +import {Text} from '../../Text'; import stylesheet from './styles'; export type LaunchCoinProps = { @@ -162,6 +162,18 @@ export const TokenLaunchCard: React.FC = ({ } */} + + {launch?.threshold_liquidity && ( + Threshold liquidity: {Number(launch?.threshold_liquidity)} + )} + + {launch?.liquidity_raised && Raised: {Number(launch?.liquidity_raised)}} + + {launch?.is_liquidity_launch && ( + Is launched in DEX: {Number(launch?.is_liquidity_launch)} + )} + + {launch?.token_quote && ( ({ container: { // alignItems: 'center', diff --git a/apps/mobile/src/components/search/index.tsx b/apps/mobile/src/components/search/index.tsx index 0f2753d1d..6d3a6cad0 100644 --- a/apps/mobile/src/components/search/index.tsx +++ b/apps/mobile/src/components/search/index.tsx @@ -1,3 +1,4 @@ +import {NDKKind} from '@nostr-dev-kit/ndk'; import React from 'react'; import {TextInput, View} from 'react-native'; import Svg, {Path} from 'react-native-svg'; @@ -8,6 +9,10 @@ import stylesheet from './styles'; interface ISearchComponent { searchQuery?: string; setSearchQuery: (search: string) => void; + kinds?: NDKKind[]; + setKinds?: (kinds: NDKKind[]) => void; + isOpenFilter?: boolean; + setIsOpenFilter?: (isOpen: boolean) => void; } const SearchComponent = ({searchQuery, setSearchQuery}: ISearchComponent) => { // const [searchQuery, setSearchQuery] = useState(''); diff --git a/apps/mobile/src/context/Toast/ToastContext.tsx b/apps/mobile/src/context/Toast/ToastContext.tsx index db9df5522..b24f663f6 100644 --- a/apps/mobile/src/context/Toast/ToastContext.tsx +++ b/apps/mobile/src/context/Toast/ToastContext.tsx @@ -4,9 +4,9 @@ import {View} from 'react-native'; import {SafeAreaView} from 'react-native-safe-area-context'; import {ToastProps} from '../../components/Toast'; +import {useStyles} from '../../hooks'; import {AnimatedToast} from './AnimatedToast'; import stylesheet from './styles'; -import { useStyles } from '../../hooks'; export type ToastConfig = ToastProps & { key: string; @@ -21,7 +21,7 @@ export type ToastContextType = { export const ToastContext = createContext(null); export const ToastProvider: React.FC<{children: React.ReactNode}> = ({children}) => { - const styles = useStyles(stylesheet) + const styles = useStyles(stylesheet); const [toasts, setToasts] = useState([]); const hideToast = useCallback((key: string) => { setToasts((prev) => prev.filter((t) => t.key !== key)); diff --git a/apps/mobile/src/context/Toast/styles.ts b/apps/mobile/src/context/Toast/styles.ts index 60cb0a446..ebef29cc3 100644 --- a/apps/mobile/src/context/Toast/styles.ts +++ b/apps/mobile/src/context/Toast/styles.ts @@ -1,10 +1,7 @@ -import {StyleSheet} from 'react-native'; - import {Spacing, ThemedStyleSheet} from '../../styles'; // export default StyleSheet.create({ export default ThemedStyleSheet((theme) => ({ - // export default StyleSheet.create({ container: { position: 'absolute', diff --git a/apps/mobile/src/modules/Layout/auth-sidebar/index.tsx b/apps/mobile/src/modules/Layout/auth-sidebar/index.tsx index 76427f28c..8a3f3723f 100644 --- a/apps/mobile/src/modules/Layout/auth-sidebar/index.tsx +++ b/apps/mobile/src/modules/Layout/auth-sidebar/index.tsx @@ -1,12 +1,13 @@ -import React, { useEffect } from 'react'; -import { Text, View } from 'react-native'; -import { useStyles, useTheme } from '../../../hooks'; +import React, {useEffect} from 'react'; +import {Text, View} from 'react-native'; + +import {useStyles} from '../../../hooks'; import stylesheet from './styles'; interface SidebarInterface { navigation: any; } -const AuthSidebar = ({ navigation }: SidebarInterface) => { +const AuthSidebar = ({navigation}: SidebarInterface) => { const styles = useStyles(stylesheet); useEffect(() => { @@ -23,10 +24,8 @@ const AuthSidebar = ({ navigation }: SidebarInterface) => { All-in-one platform - - Connect or create an Account Acces the AFK app @@ -35,11 +34,8 @@ const AuthSidebar = ({ navigation }: SidebarInterface) => { Coming soon also in IOS and Android - - - + - ); }; diff --git a/apps/mobile/src/modules/Layout/auth-sidebar/styles.ts b/apps/mobile/src/modules/Layout/auth-sidebar/styles.ts index 35772d55f..6976c4846 100644 --- a/apps/mobile/src/modules/Layout/auth-sidebar/styles.ts +++ b/apps/mobile/src/modules/Layout/auth-sidebar/styles.ts @@ -2,7 +2,7 @@ import {Spacing, ThemedStyleSheet} from '../../../styles'; export default ThemedStyleSheet((theme) => ({ container: { - marginVertical:10, + marginVertical: 10, color: theme.colors.text, }, sidebar: { diff --git a/apps/mobile/src/modules/Post/index.tsx b/apps/mobile/src/modules/Post/index.tsx index aeb457ffa..1df47b47c 100644 --- a/apps/mobile/src/modules/Post/index.tsx +++ b/apps/mobile/src/modules/Post/index.tsx @@ -18,7 +18,7 @@ import Animated, { import {CommentIcon, LikeFillIcon, LikeIcon, RepostIcon} from '../../assets/icons'; import {Avatar, Icon, IconButton, Menu, Text} from '../../components'; import {useStyles, useTheme} from '../../hooks'; -import {useTipModal} from '../../hooks/modals'; +import {useTipModal, useToast} from '../../hooks/modals'; import {MainStackNavigationProps} from '../../types'; import {getImageRatio, shortenPubkey} from '../../utils/helpers'; import {getElapsedTimeStringFull} from '../../utils/timestamp'; @@ -34,6 +34,7 @@ export const Post: React.FC = ({asComment, event}) => { const {theme} = useTheme(); const styles = useStyles(stylesheet); + const {showToast} = useToast(); const navigation = useNavigation(); @@ -119,6 +120,14 @@ export const Post: React.FC = ({asComment, event}) => { ); }; + const handleRepost = async () => { + showToast({title: 'Repost coming soon', type: 'info'}); + }; + + const handleBookmarkList = async () => { + showToast({title: 'Bookmark and List coming soon', type: 'info'}); + }; + const content = event?.content || ''; const truncatedContent = content.length > 200 ? `${content.slice(0, 200)}...` : content; @@ -257,16 +266,27 @@ export const Post: React.FC = ({asComment, event}) => { showTipModal(event); }} > - { - // if (!event) return; - - // showTipModal(event); - // }} - /> + + + + { + if (!event) return; + handleRepost(); + }} + > + + + + { + if (!event) return; + handleBookmarkList(); + }} + > + diff --git a/apps/mobile/src/modules/TipModal/index.tsx b/apps/mobile/src/modules/TipModal/index.tsx index c6320c17e..98dfb02c2 100644 --- a/apps/mobile/src/modules/TipModal/index.tsx +++ b/apps/mobile/src/modules/TipModal/index.tsx @@ -5,6 +5,7 @@ import {Pressable, View} from 'react-native'; import {Modalize, Text} from '../../components'; import {useStyles, useTheme} from '../../hooks'; import {TipSuccessModalProps} from '../TipSuccessModal'; +import {FormLightningZap} from './lightning/form'; import {FormTipStarknet} from './starknet/form'; import stylesheet from './styles'; @@ -48,6 +49,7 @@ export const TipModal = forwardRef( }} > setTipType(TipTypeMode.STARKNET)} style={{ padding: 3, borderRadius: 10, @@ -58,13 +60,14 @@ export const TipModal = forwardRef( Starknet tip setTipType(TipTypeMode.ZAP)} style={{ padding: 3, borderRadius: 10, backgroundColor: tipType == TipTypeMode.ZAP ? theme.theme.colors.primary : '', }} > - Zap coming soon + Zap {tipType == TipTypeMode.STARKNET && ( @@ -77,6 +80,17 @@ export const TipModal = forwardRef( ref={ref} > )} + + {tipType == TipTypeMode.ZAP && ( + + )} ); }, diff --git a/apps/mobile/src/modules/TipModal/lightning/form.tsx b/apps/mobile/src/modules/TipModal/lightning/form.tsx new file mode 100644 index 000000000..c8b79fd7d --- /dev/null +++ b/apps/mobile/src/modules/TipModal/lightning/form.tsx @@ -0,0 +1,114 @@ +import {NDKEvent} from '@nostr-dev-kit/ndk'; +import {useProfile} from 'afk_nostr_sdk'; +import React, {useState} from 'react'; +import {View} from 'react-native'; + +import {Avatar, Button, Input, Modalize, Text} from '../../../components'; +import {useStyles} from '../../../hooks'; +import {useToast} from '../../../hooks/modals'; +import {TipSuccessModalProps} from '../../TipSuccessModal'; +import stylesheet from './styles'; + +export type TipModalLightning = Modalize; + +export type FormTipModalLightningProps = { + event?: NDKEvent; + ref?: any; + show: (event: NDKEvent) => void; + hide: () => void; + showSuccess: (props: TipSuccessModalProps) => void; + hideSuccess: () => void; +}; + +export const FormLightningZap: React.FC = ({ + event, + hide: hideTipModal, + showSuccess, + hideSuccess, + ref, +}: FormTipModalLightningProps) => { + const styles = useStyles(stylesheet); + + const [amount, setAmount] = useState(''); + const {data: profile} = useProfile({publicKey: event?.pubkey}); + const {showToast} = useToast(); + const isActive = !!amount; + + const onTipPress = () => { + showToast({title: 'ZAP coming soon', type: 'info'}); + }; + + return ( + + ZAP Coming soon + + + + + + + + {profile?.displayName ?? profile?.name ?? event?.pubkey} + + + {profile?.nip05 && ( + + @{profile?.nip05} + + )} + + + + + + {event?.content} + + + + + + SATS amount + + + + + + + + + + + Tip friends and support creators with BTC in the Lightning network. + + + ); +}; +// FormTipStarknet.displayName = 'FormTipStarknet'; diff --git a/apps/mobile/src/modules/TipModal/lightning/index.tsx b/apps/mobile/src/modules/TipModal/lightning/index.tsx new file mode 100644 index 000000000..93237c04a --- /dev/null +++ b/apps/mobile/src/modules/TipModal/lightning/index.tsx @@ -0,0 +1,230 @@ +import {NDKEvent} from '@nostr-dev-kit/ndk'; +import {useAccount} from '@starknet-react/core'; +import {useProfile} from 'afk_nostr_sdk'; +import {forwardRef, useState} from 'react'; +import {Pressable, View} from 'react-native'; +import {CallData, uint256} from 'starknet'; + +import {Avatar, Button, Input, Modalize, Picker, Text} from '../../../components'; +import {ESCROW_ADDRESSES} from '../../../constants/contracts'; +import {CHAIN_ID} from '../../../constants/env'; +import {DEFAULT_TIMELOCK, Entrypoint} from '../../../constants/misc'; +import {TOKENS, TokenSymbol} from '../../../constants/tokens'; +import {useStyles, useWaitConnection} from '../../../hooks'; +import {useTransactionModal} from '../../../hooks/modals'; +import {useDialog} from '../../../hooks/modals/useDialog'; +import {useTransaction} from '../../../hooks/modals/useTransaction'; +import {useWalletModal} from '../../../hooks/modals/useWalletModal'; +import {TipSuccessModalProps} from '../../TipSuccessModal'; +import stylesheet from './styles'; + +export type TipModalStarknet = Modalize; + +export type TipModalStarknetProps = { + event?: NDKEvent; + + show: (event: NDKEvent) => void; + hide: () => void; + showSuccess: (props: TipSuccessModalProps) => void; + hideSuccess: () => void; +}; + +export const TipModalStarknet = forwardRef( + ({event, hide: hideTipModal, showSuccess, hideSuccess}, ref) => { + const styles = useStyles(stylesheet); + + const [token, setToken] = useState(TokenSymbol.ETH); + const [amount, setAmount] = useState(''); + + const {data: profile} = useProfile({publicKey: event?.pubkey}); + + const account = useAccount(); + const walletModal = useWalletModal(); + const sendTransaction = useTransaction(); + const {hide: hideTransactionModal} = useTransactionModal(); + const waitConnection = useWaitConnection(); + + const {showDialog, hideDialog} = useDialog(); + + const isActive = !!amount && !!token; + + const onTipPress = async () => { + if (!account.address) { + walletModal.show(); + + const result = await waitConnection(); + if (!result) return; + } + + const amountUint256 = uint256.bnToUint256( + Math.ceil(Number(amount) * 10 ** TOKENS[token][CHAIN_ID].decimals), + ); + + const approveCallData = CallData.compile([ + ESCROW_ADDRESSES[CHAIN_ID], // Contract address + amountUint256, // Amount + ]); + + const depositCallData = CallData.compile([ + amountUint256, // Amount + TOKENS[token][CHAIN_ID].address, // Token address + uint256.bnToUint256(`0x${event?.pubkey}`), // Recipient nostr pubkey + DEFAULT_TIMELOCK, // timelock + ]); + + const receipt = await sendTransaction({ + calls: [ + { + contractAddress: TOKENS[token][CHAIN_ID].address, + entrypoint: Entrypoint.APPROVE, + calldata: approveCallData, + }, + { + contractAddress: ESCROW_ADDRESSES[CHAIN_ID], + entrypoint: Entrypoint.DEPOSIT, + calldata: depositCallData, + }, + ], + }); + + if (receipt?.isSuccess()) { + hideTipModal(); + hideTransactionModal(); + showSuccess({ + amount: Number(amount), + symbol: token, + user: + (profile?.nip05 && `@${profile.nip05}`) ?? + profile?.displayName ?? + profile?.name ?? + event?.pubkey, + hide: hideSuccess, + }); + } else { + let description = 'Please Try Again Later.'; + if (receipt?.isRejected()) { + description = receipt.transaction_failure_reason.error_message; + } + + showDialog({ + title: 'Failed to send the tip', + description, + buttons: [{type: 'secondary', label: 'Close', onPress: () => hideDialog()}], + }); + } + }; + + return ( + + + Starknet tip + + Zap coming soon + + + + + + + + + {profile?.displayName ?? profile?.name ?? event?.pubkey} + + + {profile?.nip05 && ( + + @{profile?.nip05} + + )} + + + + + + {event?.content} + + + + + + setToken(itemValue as TokenSymbol)} + > + {Object.values(TOKENS).map((tkn) => ( + + ))} + + + + + + + + + + Sending + + + {amount.length > 0 && token.length > 0 ? ( + + {amount} {token} + + ) : ( + + ... + + )} + + + + + to + + + {(profile?.nip05 && `@${profile.nip05}`) ?? + profile?.displayName ?? + profile?.name ?? + event?.pubkey} + + + + + + + + + + Tip friends and support creators with your favorite tokens. + + + ); + }, +); +TipModalStarknet.displayName = 'TipModalStarknet'; diff --git a/apps/mobile/src/modules/TipModal/lightning/styles.ts b/apps/mobile/src/modules/TipModal/lightning/styles.ts new file mode 100644 index 000000000..53d34a7bf --- /dev/null +++ b/apps/mobile/src/modules/TipModal/lightning/styles.ts @@ -0,0 +1,111 @@ +import {Platform} from 'react-native'; + +import {Spacing, ThemedStyleSheet} from '../../../styles'; + +export default ThemedStyleSheet((theme) => ({ + modal: { + paddingBottom: Spacing.xxlarge, + }, + + header: { + width: '100%', + marginBottom: Spacing.medium, + paddingTop: Spacing.small, + paddingLeft: Spacing.small, + paddingBottom: Spacing.medium, + paddingRight: Spacing.small, + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + icon: { + color: theme.colors.primary, + }, + + cardHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + cardContent: { + flex: 1, + flexDirection: 'row', + gap: 5, + alignItems: 'center', + }, + cardInfo: { + flex: 1, + paddingRight: Spacing.small, + }, + + title: { + marginBottom: Spacing.xsmall, + }, + + cardContentText: { + paddingTop: Spacing.small, + paddingRight: Spacing.small, + color: theme.colors.text, + }, + likes: { + flexDirection: 'row', + gap: 3, + alignItems: 'center', + }, + + sending: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + sendingText: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + gap: Spacing.xsmall, + }, + + recipient: { + flex: 1, + flexDirection: 'row', + gap: 4, + alignItems: 'center', + justifyContent: 'flex-end', + }, + card: { + width: '100%', + backgroundColor: theme.colors.primaryLight, + borderRadius: 16, + padding: Spacing.medium, + }, + + comment: { + paddingTop: Spacing.small, + }, + + pickerContainer: { + flex: 1, + gap: 20, + paddingTop: Spacing.xxlarge, + paddingBottom: Spacing.xxlarge, + }, + + more: { + paddingLeft: Spacing.small, + color: theme.colors.primary, + }, + + likeIcon: { + color: theme.colors.primary, + }, + + content: { + padding: Spacing.xlarge, + paddingTop: Platform.OS === 'ios' ? Spacing.xlarge : Spacing.xsmall, + }, + + submitButton: { + paddingTop: Spacing.xlarge, + }, +})); diff --git a/apps/mobile/src/screens/Defi/index.tsx b/apps/mobile/src/screens/Defi/index.tsx index 38b2677b8..5498d4d92 100644 --- a/apps/mobile/src/screens/Defi/index.tsx +++ b/apps/mobile/src/screens/Defi/index.tsx @@ -3,14 +3,15 @@ import {KeyboardAvoidingView, Text, View} from 'react-native'; import {SafeAreaView} from 'react-native-safe-area-context'; import {TextButton} from '../../components'; +import TabSelector from '../../components/TabSelector'; import {useStyles} from '../../hooks'; import {DefiScreenProps} from '../../types'; -import {SelectedTab} from '../../types/tab'; +import {SelectedTab, TABS_DEFI} from '../../types/tab'; import stylesheet from './styles'; export const Defi: React.FC = ({navigation}) => { const styles = useStyles(stylesheet); - const [selectedTab, setSelectedTab] = useState(SelectedTab.CREATE_NOTE); + const [selectedTab, setSelectedTab] = useState(SelectedTab.BTC_FI_VAULT); const handleTabSelected = (tab: string | SelectedTab, screen?: string) => { setSelectedTab(tab as any); @@ -28,15 +29,27 @@ export const Defi: React.FC = ({navigation}) => { - {/* */} + > DeFi, Ramp and more soon Stay tuned for the AFK Fi + + {selectedTab == SelectedTab.BTC_FI_VAULT && ( + + Vault coming soon + + )} + + {selectedTab == SelectedTab.BTC_BRIDGE && ( + + Brdige coming soon + + )} diff --git a/apps/mobile/src/screens/Feed/index.tsx b/apps/mobile/src/screens/Feed/index.tsx index 1985c0e58..e8ca1d97a 100644 --- a/apps/mobile/src/screens/Feed/index.tsx +++ b/apps/mobile/src/screens/Feed/index.tsx @@ -18,12 +18,25 @@ export const Feed: React.FC = ({navigation}) => { const profiles = useAllProfiles(); const [search, setSearch] = useState(undefined); // const notes = useRootNotes(); + const [isAllKinds, setIsAllKinds] = useState(false); + const [isFilterOpen, setISFilterOpen] = useState(false); + const [isOpenProfile, setIsOpenProfile] = useState(false); + const [kinds, setKinds] = useState([ + NDKKind.Text, + NDKKind.ChannelCreation, + NDKKind.GroupChat, + NDKKind.ChannelMessage, + NDKKind.Metadata, + ]); const notes = useSearchNotes({ // search: search, - kinds: [NDKKind.Text, NDKKind.ChannelCreation, NDKKind.GroupChat, NDKKind.ChannelMessage], + kinds, }); - const profilesSearch = profiles?.data?.pages?.flat() ?? []; + const profilesSearch = + profiles?.data?.pages?.flat().map((item) => { + item?.content?.includes(search) && search && search?.length > 0; + }) ?? []; return ( @@ -79,13 +92,16 @@ export const Feed: React.FC = ({navigation}) => { } // data={stories} ItemSeparatorComponent={() => } - renderItem={({item}) => ( - - )} + renderItem={({item}) => { + if (!item?.content?.includes(search) && search && search?.length > 0) return <>; + return ( + + ); + }} /> } contentContainerStyle={styles.flatListContent} diff --git a/apps/mobile/src/screens/LaunchDetail/index.tsx b/apps/mobile/src/screens/LaunchDetail/index.tsx index 0658a0914..2c15c8edc 100644 --- a/apps/mobile/src/screens/LaunchDetail/index.tsx +++ b/apps/mobile/src/screens/LaunchDetail/index.tsx @@ -3,7 +3,7 @@ import {useNostrContext} from 'afk_nostr_sdk'; import {useEffect, useState} from 'react'; import {Text, View} from 'react-native'; -import {TokenLaunchDetail} from '../../components/TokenLaunchDetail'; +import {TokenLaunchDetail} from '../../components/pump/TokenLaunchDetail'; import {useStyles, useTheme} from '../../hooks'; import {useDataCoins} from '../../hooks/launchpad/useDataCoins'; import {LaunchDetailScreenProps} from '../../types'; diff --git a/apps/mobile/src/screens/Launchpad/LaunchpadComponent.tsx b/apps/mobile/src/screens/Launchpad/LaunchpadComponent.tsx index 8d8e439b0..cf0479425 100644 --- a/apps/mobile/src/screens/Launchpad/LaunchpadComponent.tsx +++ b/apps/mobile/src/screens/Launchpad/LaunchpadComponent.tsx @@ -4,9 +4,8 @@ import {useState} from 'react'; import {ActivityIndicator, FlatList, RefreshControl, Text, View} from 'react-native'; import {Button} from '../../components'; -import {TokenLaunchCard} from '../../components/TokenLaunchCard'; +import {TokenLaunchCard} from '../../components/search/TokenLaunchCard'; import {useStyles, useTheme, useWindowDimensions} from '../../hooks'; -import {useGetTokenLaunch} from '../../hooks/api/indexer/useLaunchTokens'; import {useQueryAllLaunch} from '../../hooks/launchpad/useQueryAllLaunch'; import {useKeyModal} from '../../hooks/modals/useKeyModal'; import {useTokenCreatedModal} from '../../hooks/modals/useTokenCreateModal'; diff --git a/apps/mobile/src/screens/PrivateGroupDetail/index.tsx b/apps/mobile/src/screens/PrivateGroupDetail/index.tsx new file mode 100644 index 000000000..1f9f95dac --- /dev/null +++ b/apps/mobile/src/screens/PrivateGroupDetail/index.tsx @@ -0,0 +1,82 @@ +import {useQueryClient} from '@tanstack/react-query'; +import {useNote, useReplyNotes} from 'afk_nostr_sdk'; +import {useState} from 'react'; +import {FlatList, RefreshControl, View} from 'react-native'; + +import {Divider, IconButton, Input, KeyboardFixedView} from '../../components'; +import {useStyles} from '../../hooks'; +import {useToast} from '../../hooks/modals'; +import {Post} from '../../modules/Post'; +import {PrivateGroupScreenProps} from '../../types'; +import stylesheet from './styles'; + +export const PrivateGroupDetail: React.FC = ({navigation, route}) => { + const {postId, post} = route.params; + + const styles = useStyles(stylesheet); + const [comment, setComment] = useState(''); + // const sendNote = useSendNote(); + const {data: note = post} = useNote({noteId: postId}); + const comments = useReplyNotes({noteId: note?.id}); + const queryClient = useQueryClient(); + const {showToast} = useToast(); + + return ( + + {/*
} + right={} + title="Conversation" + /> */} + + + + + + + + + + + + } + ItemSeparatorComponent={() => } + renderItem={({item}) => ( + + + + )} + refreshControl={ + comments.refetch()} /> + } + onEndReached={() => comments.fetchNextPage()} + /> + + + + + + + + + + + + + ); +}; diff --git a/apps/mobile/src/screens/PrivateGroupDetail/styles.ts b/apps/mobile/src/screens/PrivateGroupDetail/styles.ts new file mode 100644 index 000000000..6f126da5b --- /dev/null +++ b/apps/mobile/src/screens/PrivateGroupDetail/styles.ts @@ -0,0 +1,36 @@ +import {Spacing, ThemedStyleSheet} from '../../styles'; + +export default ThemedStyleSheet((theme) => ({ + container: { + flex: 1, + }, + content: { + flex: 1, + backgroundColor: theme.colors.surface, + }, + + post: { + paddingVertical: Spacing.small, + paddingHorizontal: Spacing.pagePadding, + }, + comment: { + paddingVertical: Spacing.large, + paddingHorizontal: Spacing.pagePadding, + }, + + commentInputContainer: { + backgroundColor: theme.colors.surface, + }, + commentInputContent: { + gap: Spacing.small, + flexDirection: 'row', + alignItems: 'center', + paddingVertical: Spacing.xsmall, + paddingHorizontal: Spacing.pagePadding, + backgroundColor: theme.colors.surface, + }, + commentInput: { + flex: 1, + width: 'auto', + }, +})); diff --git a/apps/mobile/src/screens/Search/index.tsx b/apps/mobile/src/screens/Search/index.tsx index 0aec068dd..753af048a 100644 --- a/apps/mobile/src/screens/Search/index.tsx +++ b/apps/mobile/src/screens/Search/index.tsx @@ -20,10 +20,20 @@ export const Search: React.FC = ({navigation}) => { const [search, setSearch] = useState(undefined); const [kindSelected, setKindSelected] = useState(NDKKind.Text); const [kindsArray, setKindsSelected] = useState([]); - // const notes = useSearchNotes({ search: search, kinds: [NDKKind.Text, NDKKind.ChannelCreation, NDKKind.GroupChat, NDKKind.ChannelMessage] }); + + const [isAllKinds, setIsAllKinds] = useState(false); + const [isFilterOpen, setISFilterOpen] = useState(false); + const [isOpenProfile, setIsOpenProfile] = useState(false); + + const [kinds, setKinds] = useState([ + NDKKind.Text, + NDKKind.ChannelCreation, + NDKKind.GroupChat, + NDKKind.ChannelMessage, + ]); const notes = useSearchNotes({ // search: search, - kinds: [NDKKind.Text, NDKKind.ChannelCreation, NDKKind.GroupChat, NDKKind.ChannelMessage], + kinds, }); // const profiles = useAllProfiles({ diff --git a/apps/mobile/src/screens/Settings/index.tsx b/apps/mobile/src/screens/Settings/index.tsx index 051d8db61..e95370ba2 100644 --- a/apps/mobile/src/screens/Settings/index.tsx +++ b/apps/mobile/src/screens/Settings/index.tsx @@ -1,21 +1,18 @@ -import { useAuth, useSettingsStore } from 'afk_nostr_sdk'; -import { Text, View } from 'react-native'; -import { ScrollView } from 'react-native-gesture-handler'; -import { SafeAreaView } from 'react-native-safe-area-context'; +import {useAuth} from 'afk_nostr_sdk'; +import {Text, View} from 'react-native'; -import { Button, Divider, Icon, IconButton } from '../../components'; -import { HeaderScreen } from '../../components/HeaderScreen'; -import { PrivateKeyImport } from '../../components/PrivateKeyImport'; -import { useStyles, useTheme } from '../../hooks'; -import { useToast } from '../../hooks/modals'; -import { SettingsScreenProps } from '../../types'; +import {Button, Divider, Icon, IconButton} from '../../components'; +import {HeaderScreen} from '../../components/HeaderScreen'; +import {PrivateKeyImport} from '../../components/PrivateKeyImport'; +import {RelaysConfig} from '../../components/RelaysConfig'; +import {useStyles, useTheme} from '../../hooks'; +import {SettingsScreenProps} from '../../types'; import stylesheet from './styles'; -import { RelaysConfig } from '../../components/RelaysConfig'; -export const Settings: React.FC = ({ navigation }) => { +export const Settings: React.FC = ({navigation}) => { const styles = useStyles(stylesheet); - const { theme, toggleTheme } = useTheme(); - const { publicKey, isExtension } = useAuth(); + const {theme, toggleTheme} = useTheme(); + const {publicKey, isExtension} = useAuth(); return ( = ({ navigation }) => { icon="ChevronLeftIcon" size={24} onPress={() => { - navigation.navigate('Profile', { publicKey }); + navigation.navigate('Profile', {publicKey}); // navigation.goBack }} /> @@ -45,10 +42,7 @@ export const Settings: React.FC = ({ navigation }) => { /> */} -