draft for desktop app

This commit is contained in:
amitpanwar789 2024-05-25 23:03:07 +05:30
parent 441eddb74c
commit 1cbab240ca
11 changed files with 94 additions and 13 deletions

View File

@ -6,7 +6,8 @@
"scripts": {
"dev": "node --max-old-space-size=4096 ./node_modules/.bin/webpack --watch --progress --mode development",
"test": "jest",
"build": "webpack --mode production",
"build": "webpack --config webpack.config.ts --mode development",
"builds": "react-scripts build",
"lint": "eslint src/**/*.{ts,tsx}",
"lint:fix": "eslint --fix 'src/**/*.{ts,tsx}'",
"format": "prettier --write '**/**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc"

View File

@ -24,7 +24,7 @@ const App = (): JSX.Element => {
<GarageContextProvider>
<FederationContextProvider>
<CssBaseline />
{window.NativeRobosats === undefined ? <HostAlert /> : <TorConnectionBadge />}
{(window.NativeRobosats === undefined && window.DesktopRobosats === undefined )? <HostAlert /> : <TorConnectionBadge />}
<Main />
</FederationContextProvider>
</GarageContextProvider>

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { MemoryRouter, BrowserRouter, Routes, Route } from 'react-router-dom';
import { MemoryRouter,HashRouter ,BrowserRouter, Routes, Route } from 'react-router-dom';
import { Box, Slide, Typography, styled } from '@mui/material';
import { type UseAppStoreType, AppContext, closeAll } from '../contexts/AppContext';
@ -10,7 +10,9 @@ import Notifications from '../components/Notifications';
import { useTranslation } from 'react-i18next';
import { GarageContext, type UseGarageStoreType } from '../contexts/GarageContext';
const Router = window.NativeRobosats === undefined ? BrowserRouter : MemoryRouter;
//const Router = window.NativeRobosats === undefined ? BrowserRouter : MemoryRouter;
const Router = (window.NativeRobosats === undefined && window.DesktopRobosats === undefined)? BrowserRouter : window.DesktopRobosats === 'Desktop-App' ? HashRouter : MemoryRouter;
const TestnetTypography = styled(Typography)({
height: 0,

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import useAutocomplete from '@mui/base/useAutocomplete';
import { useAutocomplete } from '@mui/base/useAutocomplete';
import { styled } from '@mui/material/styles';
import {
Button,

View File

@ -71,9 +71,9 @@ const RobotAvatar: React.FC<Props> = ({
useEffect(() => {
if (shortAlias !== undefined) {
if (window.NativeRobosats === undefined) {
if (window.NativeRobosats === undefined) {
setAvatarSrc(
`${hostUrl}/static/federation/avatars/${shortAlias}${small ? '.small' : ''}.webp`,
`${hostUrl.substring(hostUrl.indexOf("http://")+7)}/static/federation/avatars/${shortAlias}${small ? '.small' : ''}.webp`,
);
} else {
setAvatarSrc(

View File

@ -40,6 +40,7 @@ export interface SlideDirection {
export type TorStatus = 'ON' | 'STARTING' | 'STOPPING' | 'OFF';
export const isNativeRoboSats = !(window.NativeRobosats === undefined);
export const isDesktopRoboSats = !(window.DesktopRobosats === undefined);
const pageFromPath = window.location.pathname.split('/')[1];
const isPagePathEmpty = pageFromPath === '';
@ -77,15 +78,18 @@ const makeTheme = function (settings: Settings): Theme {
const getHostUrl = (network = 'mainnet'): string => {
let host = '';
let protocol = '';
if (window.NativeRobosats === undefined) {
if(window.DesktopRobosats === 'Desktop-App'){
host = defaultFederation.exp[network]['onion'];
protocol = 'http:';
}
else if (window.NativeRobosats === undefined) {
host = getHost();
protocol = location.protocol;
} else {
host = defaultFederation.exp[network].Onion;
host = defaultFederation.exp[network]['onion'];
protocol = 'http:';
}
const hostUrl = `${protocol}//${host}`;
return hostUrl;
};

View File

@ -1,6 +1,6 @@
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export const getWorldmapGeojson = async (apiClient, baseUrl) => {
return apiClient.get(baseUrl, '/static/assets/geo/countries-coastline-10km.geo.json');
return apiClient.get(baseUrl.substring(baseUrl.indexOf("http://")+7), '/static/assets/geo/countries-coastline-10km.geo.json');
};
export default getWorldmapGeojson;

View File

@ -21,7 +21,8 @@ export class Federation {
// Do not add `Local Dev` unless it is running on localhost
return acc;
} else {
acc[key] = new Coordinator(value, origin, settings, hostUrl);
acc[key] = new Coordinator(value, origin, settings, hostUrl.substring(hostUrl.indexOf("http://")+7));
return acc;
}
},

View File

@ -5,6 +5,7 @@ declare global {
ReactNativeWebView?: ReactNativeWebView;
NativeRobosats?: NativeRobosats;
RobosatsSettings: 'web-basic' | 'web-pro' | 'selfhosted-basic' | 'selfhosted-pro';
DesktopRobosats: undefined | 'Desktop-App';
}
}

View File

@ -0,0 +1,71 @@
import { type SystemClient } from '..';
class SystemDesktopClient implements SystemClient {
public loading = false;
public copyToClipboard: (value: string) => void = (value) => {
// navigator clipboard api needs a secure context (https)
// this function attempts to copy also on http contexts
// useful on the http i2p site and on torified browsers
if (navigator.clipboard !== undefined && window.isSecureContext) {
// navigator clipboard api method'
void navigator.clipboard.writeText(value);
} else {
// text area method
const textArea = document.createElement('textarea');
textArea.value = value;
// make the textarea out of viewport
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
// here the magic happens
document.execCommand('copy');
textArea.remove();
}
};
// Cookies
public getCookie: (key: string) => string = (key) => {
let cookieValue = null;
if (document?.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the key we want?
if (cookie.substring(0, key.length + 1) === key + '=') {
cookieValue = decodeURIComponent(cookie.substring(key.length + 1));
break;
}
}
}
return cookieValue ?? '';
};
public setCookie: (key: string, value: string) => void = (key, value) => {
document.cookie = `${key}=${value};path=/;SameSite=None;Secure`;
};
public deleteCookie: (key: string) => void = (key) => {
document.cookie = `${key}= ;path=/; expires = Thu, 01 Jan 1970 00:00:00 GMT`;
};
// Local storage
public getItem: (key: string) => string = (key) => {
const value = window.sessionStorage.getItem(key);
return value ?? '';
};
public setItem: (key: string, value: string) => void = (key, value) => {
window.sessionStorage.setItem(key, value);
};
public deleteItem: (key: string) => void = (key) => {
window.sessionStorage.removeItem(key);
};
}
export default SystemDesktopClient;

View File

@ -1,5 +1,6 @@
import SystemNativeClient from './SystemNativeClient';
import SystemWebClient from './SystemWebClient';
import SystemDesktopClient from './SystemDesktopClient';
export interface SystemClient {
loading: boolean;
@ -17,4 +18,4 @@ export const systemClient: SystemClient =
// react-native-web view of the RoboSats Android app.
window.navigator.userAgent.includes('robosats')
? new SystemNativeClient()
: new SystemWebClient();
: window.navigator.userAgent.includes('Electron')? new SystemDesktopClient() : new SystemWebClient();