mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-14 03:16:24 +00:00
Merge pull request #1257 from KoalaSat/android-robo-identities
Android robo identities
This commit is contained in:
commit
3b18f6a077
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,9 +1,6 @@
|
|||||||
*.py[cod]
|
*.py[cod]
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
*.egg
|
*.egg
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
@ -178,7 +178,7 @@ const Onboarding = ({
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{slot?.hashId ? (
|
{slot?.nickname ? (
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography align='center'>{t('Hi! My name is')}</Typography>
|
<Typography align='center'>{t('Hi! My name is')}</Typography>
|
||||||
<Typography component='h5' variant='h5'>
|
<Typography component='h5' variant='h5'>
|
||||||
|
@ -90,7 +90,7 @@ const RobotProfile = ({
|
|||||||
sx={{ width: '100%' }}
|
sx={{ width: '100%' }}
|
||||||
>
|
>
|
||||||
<Grid item sx={{ height: '2.3em', position: 'relative' }}>
|
<Grid item sx={{ height: '2.3em', position: 'relative' }}>
|
||||||
{slot?.hashId ? (
|
{slot?.nickname ? (
|
||||||
<Typography align='center' component='h5' variant='h5'>
|
<Typography align='center' component='h5' variant='h5'>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
@ -45,7 +45,6 @@ const ClickThroughDataGrid = styled(DataGrid)({
|
|||||||
'& .MuiDataGrid-overlayWrapperInner': {
|
'& .MuiDataGrid-overlayWrapperInner': {
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
},
|
},
|
||||||
...{ headerStyleFix },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const premiumColor = function (baseColor: string, accentColor: string, point: number): string {
|
const premiumColor = function (baseColor: string, accentColor: string, point: number): string {
|
||||||
@ -913,6 +912,7 @@ const BookTable = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ClickThroughDataGrid
|
<ClickThroughDataGrid
|
||||||
|
sx={headerStyleFix}
|
||||||
localeText={localeText}
|
localeText={localeText}
|
||||||
rowHeight={3.714 * theme.typography.fontSize}
|
rowHeight={3.714 * theme.typography.fontSize}
|
||||||
headerHeight={3.25 * theme.typography.fontSize}
|
headerHeight={3.25 * theme.typography.fontSize}
|
||||||
@ -950,6 +950,7 @@ const BookTable = ({
|
|||||||
<Dialog open={fullscreen} fullScreen={true}>
|
<Dialog open={fullscreen} fullScreen={true}>
|
||||||
<Paper style={{ width: '100%', height: '100%', overflow: 'auto' }}>
|
<Paper style={{ width: '100%', height: '100%', overflow: 'auto' }}>
|
||||||
<ClickThroughDataGrid
|
<ClickThroughDataGrid
|
||||||
|
sx={headerStyleFix}
|
||||||
localeText={localeText}
|
localeText={localeText}
|
||||||
rowHeight={3.714 * theme.typography.fontSize}
|
rowHeight={3.714 * theme.typography.fontSize}
|
||||||
headerHeight={3.25 * theme.typography.fontSize}
|
headerHeight={3.25 * theme.typography.fontSize}
|
||||||
|
@ -64,7 +64,7 @@ const ProfileDialog = ({ open = false, onClose }: Props): JSX.Element => {
|
|||||||
<ListItem className='profileNickname'>
|
<ListItem className='profileNickname'>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography component='h6' variant='h6'>
|
<Typography component='h6' variant='h6'>
|
||||||
{garage.getSlot()?.nickname !== undefined && (
|
{!garage.getSlot()?.nickname && (
|
||||||
<div style={{ position: 'relative', left: '-7px' }}>
|
<div style={{ position: 'relative', left: '-7px' }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
@ -3,8 +3,8 @@ import SmoothImage from 'react-smooth-image';
|
|||||||
import { Avatar, Badge, Tooltip } from '@mui/material';
|
import { Avatar, Badge, Tooltip } from '@mui/material';
|
||||||
import { SendReceiveIcon } from '../Icons';
|
import { SendReceiveIcon } from '../Icons';
|
||||||
import placeholder from './placeholder.json';
|
import placeholder from './placeholder.json';
|
||||||
// import { robohash } from './RobohashGenerator';
|
|
||||||
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
|
||||||
|
import { roboidentitiesClient } from '../../services/Roboidentities/Web';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
shortAlias?: string | undefined;
|
shortAlias?: string | undefined;
|
||||||
@ -53,22 +53,21 @@ const RobotAvatar: React.FC<Props> = ({
|
|||||||
const backgroundImage = `url(data:${backgroundData.mime};base64,${backgroundData.data})`;
|
const backgroundImage = `url(data:${backgroundData.mime};base64,${backgroundData.data})`;
|
||||||
const className = placeholderType === 'loading' ? 'loadingAvatar' : 'generatingAvatar';
|
const className = placeholderType === 'loading' ? 'loadingAvatar' : 'generatingAvatar';
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// // TODO: HANDLE ANDROID AVATARS TOO (when window.NativeRobosats !== undefined)
|
if (hashId !== undefined) {
|
||||||
// if (hashId !== undefined) {
|
roboidentitiesClient
|
||||||
// robohash
|
.generateRobohash(hashId, small ? 'small' : 'large')
|
||||||
// .generate(hashId, small ? 'small' : 'large')
|
.then((avatar) => {
|
||||||
// .then((avatar) => {
|
setAvatarSrc(avatar);
|
||||||
// setAvatarSrc(avatar);
|
})
|
||||||
// })
|
.catch(() => {
|
||||||
// .catch(() => {
|
setAvatarSrc('');
|
||||||
// setAvatarSrc('');
|
});
|
||||||
// });
|
setTimeout(() => {
|
||||||
// setTimeout(() => {
|
setActiveBackground(false);
|
||||||
// setActiveBackground(false);
|
}, backgroundFadeTime);
|
||||||
// }, backgroundFadeTime);
|
}
|
||||||
// }
|
}, [hashId]);
|
||||||
// }, [hashId]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shortAlias !== undefined) {
|
if (shortAlias !== undefined) {
|
||||||
@ -78,9 +77,7 @@ const RobotAvatar: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
setAvatarSrc(
|
setAvatarSrc(
|
||||||
`file:///android_asset/Web.bundle/assets/federation/avatars/${shortAlias}${
|
`file:///android_asset/Web.bundle/assets/federation/avatars/${shortAlias}.webp`,
|
||||||
small ? ' .small' : ''
|
|
||||||
}.webp`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -6,11 +6,11 @@ import {
|
|||||||
type Order,
|
type Order,
|
||||||
type Garage,
|
type Garage,
|
||||||
} from '.';
|
} from '.';
|
||||||
|
import { roboidentitiesClient } from '../services/Roboidentities/Web';
|
||||||
import { apiClient } from '../services/api';
|
import { apiClient } from '../services/api';
|
||||||
import { validateTokenEntropy } from '../utils';
|
import { validateTokenEntropy } from '../utils';
|
||||||
import { compareUpdateLimit } from './Limit.model';
|
import { compareUpdateLimit } from './Limit.model';
|
||||||
import { defaultOrder } from './Order.model';
|
import { defaultOrder } from './Order.model';
|
||||||
// import { robohash } from '../components/RobotAvatar/RobohashGenerator';
|
|
||||||
|
|
||||||
export interface Contact {
|
export interface Contact {
|
||||||
nostr?: string | undefined;
|
nostr?: string | undefined;
|
||||||
@ -174,9 +174,9 @@ export class Coordinator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
generateAllMakerAvatars = async (data: [PublicOrder]): Promise<void> => {
|
generateAllMakerAvatars = async (data: [PublicOrder]): Promise<void> => {
|
||||||
// for (const order of data) {
|
for (const order of data) {
|
||||||
// void robohash.generate(order.maker_hash_id, 'small');
|
roboidentitiesClient.generateRobohash(order.maker_hash_id, 'small');
|
||||||
// }
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadBook = (onDataLoad: () => void = () => {}): void => {
|
loadBook = (onDataLoad: () => void = () => {}): void => {
|
||||||
|
@ -59,7 +59,9 @@ class Garage {
|
|||||||
const rawSlots = JSON.parse(slotsDump);
|
const rawSlots = JSON.parse(slotsDump);
|
||||||
Object.values(rawSlots).forEach((rawSlot: Record<any, any>) => {
|
Object.values(rawSlots).forEach((rawSlot: Record<any, any>) => {
|
||||||
if (rawSlot?.token) {
|
if (rawSlot?.token) {
|
||||||
this.slots[rawSlot.token] = new Slot(rawSlot.token, Object.keys(rawSlot.robots), {});
|
this.slots[rawSlot.token] = new Slot(rawSlot.token, Object.keys(rawSlot.robots), {}, () =>
|
||||||
|
this.triggerHook('onRobotUpdate'),
|
||||||
|
);
|
||||||
|
|
||||||
Object.keys(rawSlot.robots).forEach((shortAlias) => {
|
Object.keys(rawSlot.robots).forEach((shortAlias) => {
|
||||||
const rawRobot = rawSlot.robots[shortAlias];
|
const rawRobot = rawSlot.robots[shortAlias];
|
||||||
@ -113,9 +115,10 @@ class Garage {
|
|||||||
if (!token || !shortAliases) return;
|
if (!token || !shortAliases) return;
|
||||||
|
|
||||||
if (this.getSlot(token) === null) {
|
if (this.getSlot(token) === null) {
|
||||||
this.slots[token] = new Slot(token, shortAliases, attributes);
|
this.slots[token] = new Slot(token, shortAliases, attributes, () =>
|
||||||
|
this.triggerHook('onRobotUpdate'),
|
||||||
|
);
|
||||||
this.save();
|
this.save();
|
||||||
this.triggerHook('onRobotUpdate');
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
import { sha256 } from 'js-sha256';
|
import { sha256 } from 'js-sha256';
|
||||||
import { Robot, type Order } from '.';
|
import { Robot, type Order } from '.';
|
||||||
// import { robohash } from '../components/RobotAvatar/RobohashGenerator';
|
import { roboidentitiesClient } from '../services/Roboidentities/Web';
|
||||||
// import { generate_roboname } from 'robo-identities-wasm';
|
|
||||||
|
|
||||||
class Slot {
|
class Slot {
|
||||||
constructor(token: string, shortAliases: string[], robotAttributes: Record<any, any>) {
|
constructor(
|
||||||
|
token: string,
|
||||||
|
shortAliases: string[],
|
||||||
|
robotAttributes: Record<any, any>,
|
||||||
|
onRobotUpdate: () => void,
|
||||||
|
) {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
|
|
||||||
this.hashId = sha256(sha256(this.token));
|
this.hashId = sha256(sha256(this.token));
|
||||||
this.nickname = 'No Nick Display (WIP)';
|
this.nickname = null;
|
||||||
// trigger RoboHash avatar generation in webworker and store in RoboHash class cache.
|
roboidentitiesClient.generateRoboname(this.hashId).then((nickname) => {
|
||||||
// void robohash.generate(this.hashId, 'small');
|
this.nickname = nickname;
|
||||||
// void robohash.generate(this.hashId, 'large');
|
onRobotUpdate();
|
||||||
|
});
|
||||||
|
roboidentitiesClient.generateRobohash(this.hashId, 'small');
|
||||||
|
roboidentitiesClient.generateRobohash(this.hashId, 'large');
|
||||||
|
|
||||||
this.robots = shortAliases.reduce((acc: Record<string, Robot>, shortAlias: string) => {
|
this.robots = shortAliases.reduce((acc: Record<string, Robot>, shortAlias: string) => {
|
||||||
acc[shortAlias] = new Robot(robotAttributes);
|
acc[shortAlias] = new Robot(robotAttributes);
|
||||||
@ -22,6 +29,7 @@ class Slot {
|
|||||||
this.activeShortAlias = null;
|
this.activeShortAlias = null;
|
||||||
this.lastShortAlias = null;
|
this.lastShortAlias = null;
|
||||||
this.copiedToken = false;
|
this.copiedToken = false;
|
||||||
|
onRobotUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
token: string | null;
|
token: string | null;
|
||||||
|
14
frontend/src/services/Native/index.d.ts
vendored
14
frontend/src/services/Native/index.d.ts
vendored
@ -30,7 +30,19 @@ export interface NativeWebViewMessageSystem {
|
|||||||
detail?: string;
|
detail?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare type NativeWebViewMessage = NativeWebViewMessageHttp | NativeWebViewMessageSystem;
|
export interface NativeWebViewMessageRoboidentities {
|
||||||
|
id?: number;
|
||||||
|
category: 'roboidentities';
|
||||||
|
type: 'roboname' | 'robohash';
|
||||||
|
string?: string;
|
||||||
|
size?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare type NativeWebViewMessage =
|
||||||
|
| NativeWebViewMessageHttp
|
||||||
|
| NativeWebViewMessageSystem
|
||||||
|
| NativeWebViewMessageRoboidentities
|
||||||
|
| NA;
|
||||||
|
|
||||||
export interface NativeRobosatsPromise {
|
export interface NativeRobosatsPromise {
|
||||||
resolve: (value: object | PromiseLike<object>) => void;
|
resolve: (value: object | PromiseLike<object>) => void;
|
||||||
|
4
frontend/src/services/Roboidentities/Native.ts
Normal file
4
frontend/src/services/Roboidentities/Native.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import RoboidentitiesClientNativeClient from './RoboidentitiesNativeClient';
|
||||||
|
import { RoboidentitiesClient } from './type';
|
||||||
|
|
||||||
|
export const roboidentitiesClient: RoboidentitiesClient = new RoboidentitiesClientNativeClient();
|
@ -0,0 +1,42 @@
|
|||||||
|
import { type RoboidentitiesClient } from '../type';
|
||||||
|
|
||||||
|
class RoboidentitiesNativeClient implements RoboidentitiesClient {
|
||||||
|
private robonames: Record<string, string> = {};
|
||||||
|
private robohashes: Record<string, string> = {};
|
||||||
|
|
||||||
|
public generateRoboname: (initialString: string) => Promise<string> = async (initialString) => {
|
||||||
|
if (this.robonames[initialString]) {
|
||||||
|
return this.robonames[initialString];
|
||||||
|
} else {
|
||||||
|
const response = await window.NativeRobosats?.postMessage({
|
||||||
|
category: 'roboidentities',
|
||||||
|
type: 'roboname',
|
||||||
|
detail: initialString,
|
||||||
|
});
|
||||||
|
const result = response ? Object.values(response)[0] : '';
|
||||||
|
this.robonames[initialString] = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public generateRobohash: (initialString: string, size: 'small' | 'large') => Promise<string> =
|
||||||
|
async (initialString, size) => {
|
||||||
|
const key = `${initialString};${size === 'small' ? 80 : 256}`;
|
||||||
|
|
||||||
|
if (this.robohashes[key]) {
|
||||||
|
return this.robohashes[key];
|
||||||
|
} else {
|
||||||
|
const response = await window.NativeRobosats?.postMessage({
|
||||||
|
category: 'roboidentities',
|
||||||
|
type: 'robohash',
|
||||||
|
detail: key,
|
||||||
|
});
|
||||||
|
const result = response ? Object.values(response)[0] : '';
|
||||||
|
const image = `data:image/png;base64,${result}`;
|
||||||
|
this.robohashes[key] = image;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RoboidentitiesNativeClient;
|
@ -81,7 +81,7 @@ class RoboGenerator {
|
|||||||
hash,
|
hash,
|
||||||
size,
|
size,
|
||||||
) => {
|
) => {
|
||||||
const cacheKey = `${size}px;${hash}`;
|
const cacheKey = `${hash};${size}`;
|
||||||
if (this.assetsCache[cacheKey]) {
|
if (this.assetsCache[cacheKey]) {
|
||||||
return this.assetsCache[cacheKey];
|
return this.assetsCache[cacheKey];
|
||||||
} else {
|
} else {
|
@ -0,0 +1,18 @@
|
|||||||
|
import { type RoboidentitiesClient } from '../type';
|
||||||
|
import { generate_roboname } from 'robo-identities-wasm';
|
||||||
|
import { robohash } from './RobohashGenerator';
|
||||||
|
|
||||||
|
class RoboidentitiesClientWebClient implements RoboidentitiesClient {
|
||||||
|
public generateRoboname: (initialString: string) => Promise<string> = async (initialString) => {
|
||||||
|
return new Promise<string>(async (resolve, _reject) => {
|
||||||
|
resolve(generate_roboname(initialString));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
public generateRobohash: (initialString: string, size: 'small' | 'large') => Promise<string> =
|
||||||
|
async (initialString, size) => {
|
||||||
|
return robohash.generate(initialString, size);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RoboidentitiesClientWebClient;
|
4
frontend/src/services/Roboidentities/Web.ts
Normal file
4
frontend/src/services/Roboidentities/Web.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import RoboidentitiesClientWebClient from './RoboidentitiesWebClient';
|
||||||
|
import { RoboidentitiesClient } from './type';
|
||||||
|
|
||||||
|
export const roboidentitiesClient: RoboidentitiesClient = new RoboidentitiesClientWebClient();
|
4
frontend/src/services/Roboidentities/type.ts
Normal file
4
frontend/src/services/Roboidentities/type.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface RoboidentitiesClient {
|
||||||
|
generateRoboname: (initialString: string) => Promise<string>;
|
||||||
|
generateRobohash: (initialString: string, size: 'small' | 'large') => Promise<string>;
|
||||||
|
}
|
@ -30,7 +30,6 @@ class ApiNativeClient implements ApiClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private readonly parseResponse = (response: Record<string, any>): object => {
|
private readonly parseResponse = (response: Record<string, any>): object => {
|
||||||
console.log('response', response);
|
|
||||||
if (response.headers['set-cookie'] != null) {
|
if (response.headers['set-cookie'] != null) {
|
||||||
response.headers['set-cookie'].forEach((cookie: string) => {
|
response.headers['set-cookie'].forEach((cookie: string) => {
|
||||||
const keySplit: string[] = cookie.split('=');
|
const keySplit: string[] = cookie.split('=');
|
||||||
|
@ -56,6 +56,15 @@ const configMobile: Configuration = {
|
|||||||
async: true,
|
async: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: path.resolve(__dirname, 'src/services/Roboidentities/Web.ts'),
|
||||||
|
loader: 'file-replace-loader',
|
||||||
|
options: {
|
||||||
|
condition: 'if-replacement-exists',
|
||||||
|
replacement: path.resolve(__dirname, 'src/services/Roboidentities/Native.ts'),
|
||||||
|
async: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: path.resolve(__dirname, 'src/components/RobotAvatar/placeholder.json'),
|
test: path.resolve(__dirname, 'src/components/RobotAvatar/placeholder.json'),
|
||||||
loader: 'file-replace-loader',
|
loader: 'file-replace-loader',
|
||||||
@ -81,6 +90,10 @@ const configMobile: Configuration = {
|
|||||||
from: path.resolve(__dirname, 'static/assets/sounds'),
|
from: path.resolve(__dirname, 'static/assets/sounds'),
|
||||||
to: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/sounds'),
|
to: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/sounds'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
from: path.resolve(__dirname, 'static/federation'),
|
||||||
|
to: path.resolve(__dirname, '../mobile/html/Web.bundle/assets/federation'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -6,6 +6,7 @@ import Clipboard from '@react-native-clipboard/clipboard';
|
|||||||
import EncryptedStorage from 'react-native-encrypted-storage';
|
import EncryptedStorage from 'react-native-encrypted-storage';
|
||||||
import { name as app_name, version as app_version } from './package.json';
|
import { name as app_name, version as app_version } from './package.json';
|
||||||
import TorModule from './native/TorModule';
|
import TorModule from './native/TorModule';
|
||||||
|
import RoboIdentitiesModule from './native/RoboIdentitiesModule';
|
||||||
|
|
||||||
const backgroundColors = {
|
const backgroundColors = {
|
||||||
light: 'white',
|
light: 'white',
|
||||||
@ -129,6 +130,14 @@ const App = () => {
|
|||||||
} else if (data.type === 'deleteCookie') {
|
} else if (data.type === 'deleteCookie') {
|
||||||
EncryptedStorage.removeItem(data.key);
|
EncryptedStorage.removeItem(data.key);
|
||||||
}
|
}
|
||||||
|
} else if (data.category === 'roboidentities') {
|
||||||
|
if (data.type === 'roboname') {
|
||||||
|
const roboname = await RoboIdentitiesModule.generateRoboname(data.detail);
|
||||||
|
injectMessageResolve(data.id, { roboname });
|
||||||
|
} else if (data.type === 'robohash') {
|
||||||
|
const robohash = await RoboIdentitiesModule.generateRobohash(data.detail);
|
||||||
|
injectMessageResolve(data.id, { robohash });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.robosats;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class RoboIdentities {
|
||||||
|
static {
|
||||||
|
System.loadLibrary("robonames");
|
||||||
|
System.loadLibrary("robohash");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateRoboname(String initial_string) {
|
||||||
|
return nativeGenerateRoboname(initial_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateRobohash(String initial_string) {
|
||||||
|
return nativeGenerateRobohash(initial_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Native functions implemented in Rust.
|
||||||
|
private static native String nativeGenerateRoboname(String initial_string);
|
||||||
|
private static native String nativeGenerateRobohash(String initial_string);
|
||||||
|
}
|
@ -4,6 +4,7 @@ import com.facebook.react.ReactPackage;
|
|||||||
import com.facebook.react.bridge.NativeModule;
|
import com.facebook.react.bridge.NativeModule;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.uimanager.ViewManager;
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
|
import com.robosats.modules.RoboIdentitiesModule;
|
||||||
import com.robosats.modules.TorModule;
|
import com.robosats.modules.TorModule;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -22,6 +23,7 @@ public class RobosatsPackage implements ReactPackage {
|
|||||||
List<NativeModule> modules = new ArrayList<>();
|
List<NativeModule> modules = new ArrayList<>();
|
||||||
|
|
||||||
modules.add(new TorModule(reactContext));
|
modules.add(new TorModule(reactContext));
|
||||||
|
modules.add(new RoboIdentitiesModule(reactContext));
|
||||||
|
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.robosats.modules;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.Promise;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||||
|
import com.robosats.RoboIdentities;
|
||||||
|
|
||||||
|
public class RoboIdentitiesModule extends ReactContextBaseJavaModule {
|
||||||
|
private ReactApplicationContext context;
|
||||||
|
|
||||||
|
public RoboIdentitiesModule(ReactApplicationContext reactContext) {
|
||||||
|
context = reactContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "RoboIdentitiesModule";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void generateRoboname(String initial_string, final Promise promise) {
|
||||||
|
String roboname = new RoboIdentities().generateRoboname(initial_string);
|
||||||
|
promise.resolve(roboname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void generateRobohash(String initial_string, final Promise promise) {
|
||||||
|
String robohash = new RoboIdentities().generateRobohash(initial_string);
|
||||||
|
promise.resolve(robohash);
|
||||||
|
}
|
||||||
|
}
|
@ -43,7 +43,6 @@ public class TorModule extends ReactContextBaseJavaModule {
|
|||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void sendRequest(String action, String url, String headers, String body, final Promise promise) throws JSONException {
|
public void sendRequest(String action, String url, String headers, String body, final Promise promise) throws JSONException {
|
||||||
Log.d("RobosatsUrl", url);
|
|
||||||
OkHttpClient client = new OkHttpClient.Builder()
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
.connectTimeout(60, TimeUnit.SECONDS) // Set connection timeout
|
.connectTimeout(60, TimeUnit.SECONDS) // Set connection timeout
|
||||||
.readTimeout(30, TimeUnit.SECONDS) // Set read timeout
|
.readTimeout(30, TimeUnit.SECONDS) // Set read timeout
|
||||||
@ -75,7 +74,6 @@ public class TorModule extends ReactContextBaseJavaModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call call, Response response) throws IOException {
|
public void onResponse(Call call, Response response) throws IOException {
|
||||||
Log.d("RobosatsCode", String.valueOf(response.code()));
|
|
||||||
String body = response.body() != null ? response.body().string() : "{}";
|
String body = response.body() != null ? response.body().string() : "{}";
|
||||||
JSONObject headersJson = new JSONObject();
|
JSONObject headersJson = new JSONObject();
|
||||||
response.headers().names().forEach(name -> {
|
response.headers().names().forEach(name -> {
|
||||||
|
BIN
mobile/android/app/src/main/jniLibs/arm64-v8a/librobohash.so
Executable file
BIN
mobile/android/app/src/main/jniLibs/arm64-v8a/librobohash.so
Executable file
Binary file not shown.
BIN
mobile/android/app/src/main/jniLibs/arm64-v8a/librobonames.so
Executable file
BIN
mobile/android/app/src/main/jniLibs/arm64-v8a/librobonames.so
Executable file
Binary file not shown.
BIN
mobile/android/app/src/main/jniLibs/armeabi-v7a/librobohash.so
Executable file
BIN
mobile/android/app/src/main/jniLibs/armeabi-v7a/librobohash.so
Executable file
Binary file not shown.
BIN
mobile/android/app/src/main/jniLibs/armeabi-v7a/librobonames.so
Executable file
BIN
mobile/android/app/src/main/jniLibs/armeabi-v7a/librobonames.so
Executable file
Binary file not shown.
9
mobile/native/RoboIdentitiesModule.ts
Normal file
9
mobile/native/RoboIdentitiesModule.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { NativeModules } from 'react-native';
|
||||||
|
const { RoboIdentitiesModule } = NativeModules;
|
||||||
|
|
||||||
|
interface RoboIdentitiesModuleInterface {
|
||||||
|
generateRoboname: (initialString: String) => Promise<string>;
|
||||||
|
generateRobohash: (initialString: String) => Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RoboIdentitiesModule as RoboIdentitiesModuleInterface;
|
Loading…
Reference in New Issue
Block a user