diff --git a/.gitignore b/.gitignore index 4a858ff704..c9b2e3c887 100644 --- a/.gitignore +++ b/.gitignore @@ -107,4 +107,8 @@ artifacts rust/cw-contracts/*/target # cypress -cypress/screenshots \ No newline at end of file +cypress/screenshots + +# multi-app +/app-selector.js +/app.config.js diff --git a/app-selector.js b/app-selector.js new file mode 100644 index 0000000000..4e3081fb3e --- /dev/null +++ b/app-selector.js @@ -0,0 +1 @@ +require("./apps/teritori/index"); diff --git a/app.config.js b/app.config.js index 4c15a00f6d..f16da0f3e5 100644 --- a/app.config.js +++ b/app.config.js @@ -1,79 +1 @@ -const config = { - expo: { - name: "Teritori", - slug: "teritori", - version: "1.0.3", - orientation: "portrait", - icon: "./assets/app-icon.png", - owner: "teritori", - userInterfaceStyle: "light", - splash: { - image: "./assets/splash.png", - resizeMode: "contain", - backgroundColor: "#000000", - }, - updates: { - fallbackToCacheTimeout: 0, - }, - assetBundlePatterns: ["**/*"], - ios: { - supportsTablet: true, - bundleIdentifier: "com.teritori", - buildNumber: "5", - infoPlist: { - NSBluetoothAlwaysUsageDescription: "Used for Bluetooth communications", - NSBluetoothPeripheralUsageDescription: - "Used for Bluetooth communications", - NSPhotoLibraryUsageDescription: - "Access to your photo library is required for image upload functionality.", - ITSAppUsesNonExemptEncryption: false, - UIBackgroundModes: ["audio"], - }, - }, - android: { - package: "com.teritori", - versionCode: "6", - permissions: [ - "WAKE_LOCK", - "BLUETOOTH", - "BLUETOOTH_ADMIN", - "BLUETOOTH_ADVERTISE", - "BLUETOOTH_SCAN", - "BLUETOOTH_CONNECT", - "ACCESS_NETWORK_STATE", - "CHANGE_NETWORK_STATE", - "CHANGE_WIFI_STATE", - "ACCESS_WIFI_STATE", - "CHANGE_WIFI_MULTICAST_STATE", - "NFC", - ], - }, - web: { - bundler: "metro", - favicon: "./assets/favicon.png", - }, - extra: { - eas: { - projectId: "9ce165de-0199-478c-b3bd-8688e5ce03eb", - }, - }, - plugins: [ - "expo-font", - [ - "expo-document-picker", - { - iCloudContainerEnvironment: "Production", - }, - ], - [ - "react-native-vision-camera", - { - cameraPermissionText: "$(PRODUCT_NAME) needs access to your Camera.", - enableCodeScanner: true, - }, - ], - ], - }, -}; - -export default config; +module.exports = require("./apps/teritori/app.config.js"); diff --git a/apps/gno-dapp/App.tsx b/apps/gnotribe/App.tsx similarity index 86% rename from apps/gno-dapp/App.tsx rename to apps/gnotribe/App.tsx index dc629459ca..e146880d78 100644 --- a/apps/gno-dapp/App.tsx +++ b/apps/gnotribe/App.tsx @@ -1,3 +1,4 @@ +import logo from "@/assets/logos/gnotribe-toplogo.svg"; import { AppConfig } from "@/context/AppConfigProvider"; import AppRoot from "@/dapp-root/App"; @@ -8,6 +9,7 @@ const config: AppConfig = { forceDAppsList: ["feed", "organizations"], defaultNetworkId: "gno-test5", homeScreen: "Feed", + logo, }; export const App: React.FC = () => { diff --git a/apps/gnotribe/app.config.js b/apps/gnotribe/app.config.js new file mode 100644 index 0000000000..1fe0ed14b7 --- /dev/null +++ b/apps/gnotribe/app.config.js @@ -0,0 +1,77 @@ +module.exports = { + expo: { + name: "Gnotribe", + slug: "gnotribe", + version: "1.0.3", + orientation: "portrait", + icon: "./apps/gnotribe/icon.png", + owner: "gnotribe", + userInterfaceStyle: "light", + splash: { + image: "./assets/splash.png", + resizeMode: "contain", + backgroundColor: "#000000", + }, + updates: { + fallbackToCacheTimeout: 0, + }, + assetBundlePatterns: ["**/*"], + ios: { + supportsTablet: true, + bundleIdentifier: "com.teritori.gnotribe", + buildNumber: "5", + infoPlist: { + NSBluetoothAlwaysUsageDescription: "Used for Bluetooth communications", + NSBluetoothPeripheralUsageDescription: + "Used for Bluetooth communications", + NSPhotoLibraryUsageDescription: + "Access to your photo library is required for image upload functionality.", + ITSAppUsesNonExemptEncryption: false, + UIBackgroundModes: ["audio"], + }, + }, + android: { + package: "com.teritori.gnotribe", + versionCode: 6, + permissions: [ + "WAKE_LOCK", + "BLUETOOTH", + "BLUETOOTH_ADMIN", + "BLUETOOTH_ADVERTISE", + "BLUETOOTH_SCAN", + "BLUETOOTH_CONNECT", + "ACCESS_NETWORK_STATE", + "CHANGE_NETWORK_STATE", + "CHANGE_WIFI_STATE", + "ACCESS_WIFI_STATE", + "CHANGE_WIFI_MULTICAST_STATE", + "NFC", + ], + }, + web: { + bundler: "metro", + favicon: "./apps/gnotribe/icon.png", + }, + extra: { + eas: { + projectId: "9ce165de-0199-478c-b3bd-8688e5ce03eb", + }, + }, + plugins: [ + "expo-font", + [ + "expo-document-picker", + { + iCloudContainerEnvironment: "Production", + }, + ], + [ + "react-native-vision-camera", + { + cameraPermissionText: "$(PRODUCT_NAME) needs access to your Camera.", + enableCodeScanner: true, + }, + ], + ], + }, +}; diff --git a/apps/gnotribe/icon.png b/apps/gnotribe/icon.png new file mode 100644 index 0000000000..315ce7a7ed Binary files /dev/null and b/apps/gnotribe/icon.png differ diff --git a/apps/gno-dapp/index.js b/apps/gnotribe/index.js similarity index 100% rename from apps/gno-dapp/index.js rename to apps/gnotribe/index.js diff --git a/apps/teritori-dapp/netlify.toml b/apps/gnotribe/netlify.toml similarity index 53% rename from apps/teritori-dapp/netlify.toml rename to apps/gnotribe/netlify.toml index 3ad63160b1..06ee85e43a 100644 --- a/apps/teritori-dapp/netlify.toml +++ b/apps/gnotribe/netlify.toml @@ -1,5 +1,5 @@ [build] -command = 'npm i -g sharp-cli && npx expo-optimize && npx expo export -p web' +command = 'npx tsx packages/scripts/switch-app gnotribe && npm i -g sharp-cli && npx expo-optimize && npx expo export -p web' publish = '/dist' [build.environment] NODE_OPTIONS = "--max_old_space_size=4096" diff --git a/apps/teritori-dapp/App.tsx b/apps/teritori/App.tsx similarity index 100% rename from apps/teritori-dapp/App.tsx rename to apps/teritori/App.tsx diff --git a/apps/teritori/app.config.js b/apps/teritori/app.config.js new file mode 100644 index 0000000000..6538d9dc85 --- /dev/null +++ b/apps/teritori/app.config.js @@ -0,0 +1,77 @@ +module.exports = { + expo: { + name: "Teritori", + slug: "teritori", + version: "1.0.3", + orientation: "portrait", + icon: "./assets/app-icon.png", + owner: "teritori", + userInterfaceStyle: "light", + splash: { + image: "./assets/splash.png", + resizeMode: "contain", + backgroundColor: "#000000", + }, + updates: { + fallbackToCacheTimeout: 0, + }, + assetBundlePatterns: ["**/*"], + ios: { + supportsTablet: true, + bundleIdentifier: "com.teritori", + buildNumber: "5", + infoPlist: { + NSBluetoothAlwaysUsageDescription: "Used for Bluetooth communications", + NSBluetoothPeripheralUsageDescription: + "Used for Bluetooth communications", + NSPhotoLibraryUsageDescription: + "Access to your photo library is required for image upload functionality.", + ITSAppUsesNonExemptEncryption: false, + UIBackgroundModes: ["audio"], + }, + }, + android: { + package: "com.teritori", + versionCode: 6, + permissions: [ + "WAKE_LOCK", + "BLUETOOTH", + "BLUETOOTH_ADMIN", + "BLUETOOTH_ADVERTISE", + "BLUETOOTH_SCAN", + "BLUETOOTH_CONNECT", + "ACCESS_NETWORK_STATE", + "CHANGE_NETWORK_STATE", + "CHANGE_WIFI_STATE", + "ACCESS_WIFI_STATE", + "CHANGE_WIFI_MULTICAST_STATE", + "NFC", + ], + }, + web: { + bundler: "metro", + favicon: "./assets/favicon.png", + }, + extra: { + eas: { + projectId: "9ce165de-0199-478c-b3bd-8688e5ce03eb", + }, + }, + plugins: [ + "expo-font", + [ + "expo-document-picker", + { + iCloudContainerEnvironment: "Production", + }, + ], + [ + "react-native-vision-camera", + { + cameraPermissionText: "$(PRODUCT_NAME) needs access to your Camera.", + enableCodeScanner: true, + }, + ], + ], + }, +}; diff --git a/apps/teritori-dapp/index.js b/apps/teritori/index.js similarity index 100% rename from apps/teritori-dapp/index.js rename to apps/teritori/index.js diff --git a/apps/gno-dapp/netlify.toml b/apps/teritori/netlify.toml similarity index 53% rename from apps/gno-dapp/netlify.toml rename to apps/teritori/netlify.toml index 1736587b69..275f2cd157 100644 --- a/apps/gno-dapp/netlify.toml +++ b/apps/teritori/netlify.toml @@ -1,5 +1,5 @@ [build] -command = 'sed -i "s/teritori-dapp/gno-dapp/" package.json && npm i -g sharp-cli && npx expo-optimize && npx expo export -p web' +command = 'npx tsx packages/scripts/switch-app teritori && npm i -g sharp-cli && npx expo-optimize && npx expo export -p web' publish = '/dist' [build.environment] NODE_OPTIONS = "--max_old_space_size=4096" diff --git a/assets/logos/gnotribe-logo.svg b/assets/logos/gnotribe-logo.svg new file mode 100644 index 0000000000..55844c121e --- /dev/null +++ b/assets/logos/gnotribe-logo.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/logos/gnotribe-toplogo.svg b/assets/logos/gnotribe-toplogo.svg new file mode 100644 index 0000000000..acc8742ae4 --- /dev/null +++ b/assets/logos/gnotribe-toplogo.svg @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index e8ed206254..ed67ee40a5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "teritori-dapp", "version": "1.0.0", - "main": "apps/teritori-dapp/index.js", + "main": "app-selector.js", "scripts": { "start": "expo start", "android": "expo run:android", diff --git a/packages/components/navigation/components/TopLogo.tsx b/packages/components/navigation/components/TopLogo.tsx index 31c04283b3..c8720871ee 100644 --- a/packages/components/navigation/components/TopLogo.tsx +++ b/packages/components/navigation/components/TopLogo.tsx @@ -1,21 +1,22 @@ import React from "react"; import { View, TouchableOpacity, ViewStyle } from "react-native"; -import logoTopVersionSVG from "../../../../assets/logos/logo-hexagon-version-alpha.svg"; -import { layout } from "../../../utils/style/layout"; -import { SVG } from "../../SVG"; - +import logoTopVersionSVG from "@/assets/logos/logo-hexagon-version-alpha.svg"; +import { SVG } from "@/components/SVG"; import { useAppConfig } from "@/context/AppConfigProvider"; import { useAppNavigation } from "@/hooks/navigation/useAppNavigation"; +import { layout } from "@/utils/style/layout"; export const TopLogo = () => { const navigation = useAppNavigation(); - const { homeScreen } = useAppConfig(); + const { homeScreen, logo: configLogo } = useAppConfig(); - const logo = ; + const logoSource = configLogo || logoTopVersionSVG; + const logo = ; const style: ViewStyle = { - marginHorizontal: layout.spacing_x0_5, + marginHorizontal: layout.spacing_x0_25, + overflow: "hidden", }; const content = diff --git a/packages/context/AppConfigProvider.tsx b/packages/context/AppConfigProvider.tsx index 06b6f12e94..0ec5a66b2a 100644 --- a/packages/context/AppConfigProvider.tsx +++ b/packages/context/AppConfigProvider.tsx @@ -1,4 +1,5 @@ import { createContext, useContext } from "react"; +import { SvgProps } from "react-native-svg"; import { RootStackParamList } from "@/utils/navigation"; @@ -9,6 +10,7 @@ export interface AppConfig { forceDAppsList?: string[]; defaultNetworkId: string; homeScreen: keyof RootStackParamList; + logo?: React.FC; } const defaultValue: AppConfig = { defaultNetworkId: "teritori", diff --git a/packages/scripts/app-build/fixGitignore.ts b/packages/scripts/app-build/fixGitignore.ts index 115ce5e1b9..183edbcfd7 100644 --- a/packages/scripts/app-build/fixGitignore.ts +++ b/packages/scripts/app-build/fixGitignore.ts @@ -6,6 +6,8 @@ const TO_REMOVE_ITEMS = [ "/weshd/ios/Frameworks/", "/weshd/android/libs/", "/ios", + "/app-selector.js", + "/app.config.js", ]; fs.readFile(FILE_PATH, "utf8", (err, data) => { diff --git a/packages/scripts/switch-app.ts b/packages/scripts/switch-app.ts new file mode 100644 index 0000000000..4c8cf719bc --- /dev/null +++ b/packages/scripts/switch-app.ts @@ -0,0 +1,35 @@ +import { program } from "commander"; +import fs from "fs"; +import fsp from "fs/promises"; +import path from "path"; + +const main = async () => { + const [appName] = program.argument("").parse().args; + + const rootPath = path.join(__dirname, "..", ".."); + const appsPath = path.join(rootPath, "apps"); + const appPath = path.join(appsPath, appName); + const exists = fs.existsSync(appPath); + if (!exists) { + let apps: string[] = []; + try { + apps = await fsp.readdir(appsPath, {}); + apps = apps.filter((app) => ![".DS_Store"].includes(app)); + } catch {} + console.error( + `ERROR: App ${JSON.stringify(appName)} does not exist, must be one of ${apps.map((app) => JSON.stringify(app)).join(", ")}`, + ); + process.exit(1); + } + + const appSelectorPath = path.join(rootPath, "app-selector.js"); + await fsp.writeFile(appSelectorPath, `require("./apps/${appName}/index");\n`); + + const appConfigPath = path.join(rootPath, "app.config.js"); + await fsp.writeFile( + appConfigPath, + `module.exports = require("./apps/${appName}/app.config.js");\n`, + ); +}; + +main();