mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-03 03:59:10 +01:00
ADD: Today Extension and Quick Actions.
Update MainInterface.storyboard ADD: Cache fetched data ADD: Add "Up from/Down from" data OPS: Add Provision Profile Update project.pbxproj ADD: Synchronize user selected currency with Today extension Update Info.plist ADD: quick actions Update App.js Update App.js Update App.js Update App.js Update App.js FIX: Fix currency bugs FIX: Hide balance from quick actions ADD: cqc Update currency.js Update TodayViewController.swift Update App.js REF: headercolor Update App.js FIX: carousel would not show FIX: Fix FIX FIX Update API.swift FIX: Fixed alerts TST Revert "TST" This reverts commit bcdf62e9b238cc5da200cc4bce45e4e55f480d6d. ADD: Tests mocks REF: Device Quick Actions ref FIX: Fixed crash Update quickActions.ios.js ADD: QuickActions for Android D FIX: Tests OP
This commit is contained in:
parent
12b84fecb3
commit
00bb9fe28b
25 changed files with 882 additions and 86 deletions
74
App.js
74
App.js
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Linking, AppState, Clipboard, StyleSheet, KeyboardAvoidingView, Platform, View } from 'react-native';
|
||||
import { Linking, DeviceEventEmitter, AppState, Clipboard, StyleSheet, KeyboardAvoidingView, Platform, View } from 'react-native';
|
||||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import Modal from 'react-native-modal';
|
||||
import { NavigationActions } from 'react-navigation';
|
||||
|
@ -10,8 +10,9 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
|||
import url from 'url';
|
||||
import { AppStorage, LightningCustodianWallet } from './class';
|
||||
import { Chain } from './models/bitcoinUnits';
|
||||
|
||||
import QuickActions from 'react-native-quick-actions';
|
||||
import * as Sentry from '@sentry/react-native';
|
||||
import OnAppLaunch from './class/onAppLaunch';
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
Sentry.init({
|
||||
|
@ -36,17 +37,70 @@ export default class App extends React.Component {
|
|||
clipboardContent: '',
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
Linking.getInitialURL()
|
||||
.then(url => {
|
||||
async componentDidMount() {
|
||||
Linking.addEventListener('url', this.handleOpenURL);
|
||||
AppState.addEventListener('change', this._handleAppStateChange);
|
||||
QuickActions.popInitialAction().then(this.popInitialAction);
|
||||
DeviceEventEmitter.addListener('quickActionShortcut', this.walletQuickActions);
|
||||
}
|
||||
|
||||
popInitialAction = async data => {
|
||||
if (data) {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.navigator.dismiss;
|
||||
const wallet = BlueApp.getWallets().find(wallet => wallet.getID() === data.userInfo.url.split('wallet/')[1]);
|
||||
this.navigator.dispatch(
|
||||
NavigationActions.navigate({
|
||||
key: `WalletTransactions-${wallet.getID()}`,
|
||||
routeName: 'WalletTransactions',
|
||||
params: {
|
||||
wallet,
|
||||
},
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
const url = await Linking.getInitialURL();
|
||||
if (url) {
|
||||
if (this.hasSchema(url)) {
|
||||
this.handleOpenURL({ url });
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
Linking.addEventListener('url', this.handleOpenURL);
|
||||
AppState.addEventListener('change', this._handleAppStateChange);
|
||||
}
|
||||
} else {
|
||||
const isViewAllWalletsEnabled = await OnAppLaunch.isViewAllWalletsEnabled();
|
||||
if (!isViewAllWalletsEnabled) {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.navigator.dismiss;
|
||||
const selectedDefaultWallet = await OnAppLaunch.getSelectedDefaultWallet();
|
||||
const wallet = BlueApp.getWallets().find(wallet => wallet.getID() === selectedDefaultWallet.getID());
|
||||
if (wallet) {
|
||||
this.navigator.dispatch(
|
||||
NavigationActions.navigate({
|
||||
routeName: 'WalletTransactions',
|
||||
key: `WalletTransactions-${wallet.getID()}`,
|
||||
params: {
|
||||
wallet,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
walletQuickActions = data => {
|
||||
const wallet = BlueApp.getWallets().find(wallet => wallet.getID() === data.userInfo.url.split('wallet/')[1]);
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.navigator.dismiss;
|
||||
this.navigator.dispatch(
|
||||
NavigationActions.navigate({
|
||||
routeName: 'WalletTransactions',
|
||||
key: `WalletTransactions-${wallet.getID()}`,
|
||||
params: {
|
||||
wallet,
|
||||
},
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
Linking.removeEventListener('url', this.handleOpenURL);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* @exports {AppStorage}
|
||||
*/
|
||||
import { AppStorage } from './class';
|
||||
import DeviceQuickActions from './class/quickActions';
|
||||
let prompt = require('./prompt');
|
||||
let EV = require('./events');
|
||||
let currency = require('./currency');
|
||||
|
@ -19,6 +20,7 @@ async function startAndDecrypt(retry) {
|
|||
}
|
||||
let password = false;
|
||||
if (await BlueApp.storageIsEncrypted()) {
|
||||
DeviceQuickActions.clearShortcutItems();
|
||||
do {
|
||||
password = await prompt((retry && loc._.bad_password) || loc._.enter_password, loc._.storage_is_encrypted, false);
|
||||
} while (!password);
|
||||
|
|
|
@ -64,6 +64,8 @@ const WalletsStackNavigator = createStackNavigator(
|
|||
},
|
||||
WalletTransactions: {
|
||||
screen: WalletTransactions,
|
||||
path: 'WalletTransactions',
|
||||
routeName: 'WalletTransactions',
|
||||
},
|
||||
TransactionStatus: {
|
||||
screen: TransactionStatus,
|
||||
|
|
|
@ -65,8 +65,6 @@ export default class WatchConnectivity {
|
|||
}
|
||||
|
||||
return InteractionManager.runAfterInteractions(async () => {
|
||||
console.warn(WatchConnectivity.shared.isAppInstalled);
|
||||
|
||||
if (WatchConnectivity.shared.isAppInstalled) {
|
||||
let wallets = [];
|
||||
|
||||
|
|
BIN
android/app/src/main/res/drawable/quickactions.png
Normal file
BIN
android/app/src/main/res/drawable/quickactions.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 514 B |
|
@ -12,6 +12,7 @@ import {
|
|||
} from './';
|
||||
import { LightningCustodianWallet } from './lightning-custodian-wallet';
|
||||
import WatchConnectivity from '../WatchConnectivity';
|
||||
import DeviceQuickActions from './quickActions';
|
||||
const encryption = require('../encryption');
|
||||
|
||||
export class AppStorage {
|
||||
|
@ -137,6 +138,8 @@ export class AppStorage {
|
|||
this.cachedPassword = password;
|
||||
await this.setItem('data', data);
|
||||
await this.setItem(AppStorage.FLAG_ENCRYPTED, '1');
|
||||
DeviceQuickActions.clearShortcutItems();
|
||||
DeviceQuickActions.removeAllWallets();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,6 +254,8 @@ export class AppStorage {
|
|||
await this.saveToDisk();
|
||||
};
|
||||
await WatchConnectivity.shared.sendWalletsToWatch(this.wallets);
|
||||
DeviceQuickActions.setWallets(this.wallets);
|
||||
DeviceQuickActions.setQuickActions();
|
||||
return true;
|
||||
} else {
|
||||
return false; // failed loading data or loading/decryptin data
|
||||
|
@ -326,7 +331,9 @@ export class AppStorage {
|
|||
}
|
||||
WatchConnectivity.shared.wallets = this.wallets;
|
||||
WatchConnectivity.shared.tx_metadata = this.tx_metadata;
|
||||
await WatchConnectivity.shared.sendWalletsToWatch();
|
||||
WatchConnectivity.shared.sendWalletsToWatch();
|
||||
DeviceQuickActions.setWallets(this.wallets);
|
||||
DeviceQuickActions.setQuickActions();
|
||||
return this.setItem('data', JSON.stringify(data));
|
||||
}
|
||||
|
||||
|
|
46
class/quickActions.js
Normal file
46
class/quickActions.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import QuickActions from 'react-native-quick-actions';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
export default class DeviceQuickActions {
|
||||
static shared = new DeviceQuickActions();
|
||||
wallets;
|
||||
|
||||
static setWallets(wallets) {
|
||||
DeviceQuickActions.shared.wallets = wallets;
|
||||
}
|
||||
|
||||
static removeAllWallets() {
|
||||
DeviceQuickActions.shared.wallets = undefined;
|
||||
}
|
||||
|
||||
static setQuickActions() {
|
||||
if (DeviceQuickActions.shared.wallets === undefined) {
|
||||
return;
|
||||
}
|
||||
QuickActions.isSupported((error, supported) => {
|
||||
if (supported && error === null) {
|
||||
let shortcutItems = [];
|
||||
const loc = require('../loc/');
|
||||
for (const wallet of DeviceQuickActions.shared.wallets) {
|
||||
shortcutItems.push({
|
||||
type: 'Wallets', // Required
|
||||
title: wallet.getLabel(), // Optional, if empty, `type` will be used instead
|
||||
subtitle:
|
||||
wallet.hideBalance || wallet.getBalance() <= 0
|
||||
? ''
|
||||
: loc.formatBalance(Number(wallet.getBalance()), wallet.getPreferredBalanceUnit(), true),
|
||||
userInfo: {
|
||||
url: `bluewallet://wallet/${wallet.getID()}`, // Provide any custom data like deep linking URL
|
||||
},
|
||||
icon: Platform.select({ android: 'quickactions', ios: 'bookmark' }),
|
||||
});
|
||||
}
|
||||
QuickActions.setShortcutItems(shortcutItems);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static clearShortcutItems() {
|
||||
QuickActions.clearShortcutItems();
|
||||
}
|
||||
}
|
17
currency.js
17
currency.js
|
@ -2,6 +2,8 @@ import Frisbee from 'frisbee';
|
|||
import AsyncStorage from '@react-native-community/async-storage';
|
||||
import { AppStorage } from './class';
|
||||
import { FiatUnit } from './models/fiatUnit';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import DeviceQuickActions from './class/quickActions';
|
||||
let BigNumber = require('bignumber.js');
|
||||
let preferredFiatCurrency = FiatUnit.USD;
|
||||
let exchangeRates = {};
|
||||
|
@ -19,10 +21,17 @@ const STRUCT = {
|
|||
*/
|
||||
async function setPrefferedCurrency(item) {
|
||||
await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(item));
|
||||
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
|
||||
await DefaultPreference.set('preferredCurrency', item.endPointKey);
|
||||
await DefaultPreference.set('preferredCurrencyLocale', item.locale.replace('-', '_'));
|
||||
DeviceQuickActions.setQuickActions();
|
||||
}
|
||||
|
||||
async function getPreferredCurrency() {
|
||||
return JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERRED_CURRENCY));
|
||||
let preferredCurrency = await JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERRED_CURRENCY));
|
||||
await DefaultPreference.set('preferredCurrency', preferredCurrency.endPointKey);
|
||||
await DefaultPreference.set('preferredCurrencyLocale', preferredCurrency.locale.replace('-', '_'));
|
||||
return preferredCurrency;
|
||||
}
|
||||
|
||||
async function updateExchangeRate() {
|
||||
|
@ -57,6 +66,7 @@ async function updateExchangeRate() {
|
|||
exchangeRates['BTC_' + preferredFiatCurrency.endPointKey] = json.bpi[preferredFiatCurrency.endPointKey].rate_float * 1;
|
||||
await AsyncStorage.setItem(AppStorage.EXCHANGE_RATES, JSON.stringify(exchangeRates));
|
||||
await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(preferredFiatCurrency));
|
||||
DeviceQuickActions.setQuickActions();
|
||||
}
|
||||
|
||||
let interval = false;
|
||||
|
@ -71,7 +81,10 @@ async function startUpdater() {
|
|||
}
|
||||
|
||||
function satoshiToLocalCurrency(satoshi) {
|
||||
if (!exchangeRates['BTC_' + preferredFiatCurrency.endPointKey]) return '...';
|
||||
if (!exchangeRates['BTC_' + preferredFiatCurrency.endPointKey]) {
|
||||
startUpdater();
|
||||
return '...';
|
||||
}
|
||||
|
||||
let b = new BigNumber(satoshi);
|
||||
b = b
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
vim ios/BlueWallet/Info.plist
|
||||
vim ios/BlueWalletWatch/Info.plist
|
||||
vim "ios/BlueWalletWatch Extension/Info.plist"
|
||||
vim "ios/TodayExtension/Info.plist"
|
||||
vim android/app/build.gradle
|
||||
vim package.json
|
||||
vim package-lock.json
|
||||
|
|
|
@ -19,7 +19,13 @@
|
|||
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; };
|
||||
2DCD954D1E0B4F2C00145EB5 /* BlueWalletTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* BlueWalletTests.m */; };
|
||||
32002D9D236FAA9F00B93396 /* TodayDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32002D9C236FAA9F00B93396 /* TodayDataStore.swift */; };
|
||||
3208E93922F63279007F5A27 /* AppCenter-Config.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3208E93822F63279007F5A27 /* AppCenter-Config.plist */; };
|
||||
3271B0AB236E2E0700DA766F /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3271B0AA236E2E0700DA766F /* NotificationCenter.framework */; };
|
||||
3271B0AE236E2E0700DA766F /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3271B0AD236E2E0700DA766F /* TodayViewController.swift */; };
|
||||
3271B0B1236E2E0700DA766F /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3271B0AF236E2E0700DA766F /* MainInterface.storyboard */; };
|
||||
3271B0B5236E2E0700DA766F /* BlueWallet - Bitcoin Price.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3271B0A9236E2E0700DA766F /* BlueWallet - Bitcoin Price.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
3271B0BB236E329400DA766F /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3271B0BA236E329400DA766F /* API.swift */; };
|
||||
32B5A32A2334450100F8D608 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32B5A3292334450100F8D608 /* Bridge.swift */; };
|
||||
32F0A29A2311DBB20095C559 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F0A2992311DBB20095C559 /* ComplicationController.swift */; };
|
||||
398DED6337DF58F0ECFD8F2E /* libPods-BlueWalletTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 70089FECE936F9A0AC45B7CE /* libPods-BlueWalletTests.a */; };
|
||||
|
@ -68,6 +74,13 @@
|
|||
remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;
|
||||
remoteInfo = "BlueWallet-tvOS";
|
||||
};
|
||||
3271B0B3236E2E0700DA766F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 3271B0A8236E2E0700DA766F;
|
||||
remoteInfo = TodayExtension;
|
||||
};
|
||||
B40D4E3E225841ED00428FCC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
|
@ -85,6 +98,17 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
3271B0B6236E2E0700DA766F /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
3271B0B5236E2E0700DA766F /* BlueWallet - Bitcoin Price.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B40D4E2D225841C300428FCC /* Embed Watch Content */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -131,7 +155,15 @@
|
|||
2D02E4901E0B4A5D006451C7 /* BlueWallet-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "BlueWallet-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2FCC2CD6FF4448229D0CE0F3 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = "<group>"; };
|
||||
32002D9C236FAA9F00B93396 /* TodayDataStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayDataStore.swift; sourceTree = "<group>"; };
|
||||
3208E93822F63279007F5A27 /* AppCenter-Config.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "AppCenter-Config.plist"; sourceTree = "<group>"; };
|
||||
32475F792370F6D30070E6CF /* BlueWallet - Bitcoin Price.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "BlueWallet - Bitcoin Price.entitlements"; sourceTree = "<group>"; };
|
||||
3271B0A9236E2E0700DA766F /* BlueWallet - Bitcoin Price.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "BlueWallet - Bitcoin Price.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3271B0AA236E2E0700DA766F /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; };
|
||||
3271B0AD236E2E0700DA766F /* TodayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewController.swift; sourceTree = "<group>"; };
|
||||
3271B0B0236E2E0700DA766F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
3271B0B2236E2E0700DA766F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
3271B0BA236E329400DA766F /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = "<group>"; };
|
||||
32B5A3282334450100F8D608 /* BlueWallet-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BlueWallet-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
32B5A3292334450100F8D608 /* Bridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bridge.swift; sourceTree = "<group>"; };
|
||||
32F0A24F2310B0700095C559 /* BlueWalletWatch Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "BlueWalletWatch Extension.entitlements"; sourceTree = "<group>"; };
|
||||
|
@ -255,6 +287,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3271B0A6236E2E0700DA766F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3271B0AB236E2E0700DA766F /* NotificationCenter.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
421830728822A20A50D8A07C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -326,10 +366,33 @@
|
|||
154B05BEF3C3512F67A08374 /* libPods-BlueWalletWatch Extension.a */,
|
||||
70089FECE936F9A0AC45B7CE /* libPods-BlueWalletTests.a */,
|
||||
731973BA0AC6EA78962CE5B6 /* libPods-BlueWallet.a */,
|
||||
3271B0AA236E2E0700DA766F /* NotificationCenter.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3271B0AC236E2E0700DA766F /* TodayExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32475F792370F6D30070E6CF /* BlueWallet - Bitcoin Price.entitlements */,
|
||||
32A5F95E236E4A2A00443927 /* API */,
|
||||
3271B0AD236E2E0700DA766F /* TodayViewController.swift */,
|
||||
3271B0AF236E2E0700DA766F /* MainInterface.storyboard */,
|
||||
3271B0B2236E2E0700DA766F /* Info.plist */,
|
||||
32002D9C236FAA9F00B93396 /* TodayDataStore.swift */,
|
||||
);
|
||||
path = TodayExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
32A5F95E236E4A2A00443927 /* API */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3271B0BA236E329400DA766F /* API.swift */,
|
||||
);
|
||||
name = API;
|
||||
path = "New Group";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B0CACE36C3348E1BCEA92C8 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -359,6 +422,7 @@
|
|||
00E356EF1AD99517003FC87E /* BlueWalletTests */,
|
||||
B40D4E31225841EC00428FCC /* BlueWalletWatch */,
|
||||
B40D4E40225841ED00428FCC /* BlueWalletWatch Extension */,
|
||||
3271B0AC236E2E0700DA766F /* TodayExtension */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
B40FE50A21FAD228005D5578 /* Recovered References */,
|
||||
|
@ -379,6 +443,7 @@
|
|||
2D02E4901E0B4A5D006451C7 /* BlueWallet-tvOSTests.xctest */,
|
||||
B40D4E30225841EC00428FCC /* BlueWalletWatch.app */,
|
||||
B40D4E3C225841ED00428FCC /* BlueWalletWatch Extension.appex */,
|
||||
3271B0A9236E2E0700DA766F /* BlueWallet - Bitcoin Price.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -508,11 +573,13 @@
|
|||
B40D4E2D225841C300428FCC /* Embed Watch Content */,
|
||||
791C03B6EF06B63A39F55115 /* [CP] Copy Pods Resources */,
|
||||
2130DE983D1D45AC8FC45F7E /* Upload Debug Symbols to Sentry */,
|
||||
3271B0B6236E2E0700DA766F /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
B40D4E4C225841ED00428FCC /* PBXTargetDependency */,
|
||||
3271B0B4236E2E0700DA766F /* PBXTargetDependency */,
|
||||
);
|
||||
name = BlueWallet;
|
||||
productName = "Hello World";
|
||||
|
@ -555,6 +622,23 @@
|
|||
productReference = 2D02E4901E0B4A5D006451C7 /* BlueWallet-tvOSTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
3271B0A8236E2E0700DA766F /* TodayExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3271B0B9236E2E0700DA766F /* Build configuration list for PBXNativeTarget "TodayExtension" */;
|
||||
buildPhases = (
|
||||
3271B0A5236E2E0700DA766F /* Sources */,
|
||||
3271B0A6236E2E0700DA766F /* Frameworks */,
|
||||
3271B0A7236E2E0700DA766F /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = TodayExtension;
|
||||
productName = TodayExtension;
|
||||
productReference = 3271B0A9236E2E0700DA766F /* BlueWallet - Bitcoin Price.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
B40D4E2F225841EC00428FCC /* BlueWalletWatch */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B40D4E52225841ED00428FCC /* Build configuration list for PBXNativeTarget "BlueWalletWatch" */;
|
||||
|
@ -598,7 +682,7 @@
|
|||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1020;
|
||||
LastSwiftUpdateCheck = 1120;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
|
@ -610,7 +694,7 @@
|
|||
13B07F861A680F5B00A75B9A = {
|
||||
DevelopmentTeam = A7W54YZ4WU;
|
||||
LastSwiftMigration = 1030;
|
||||
ProvisioningStyle = Manual;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.Keychain = {
|
||||
enabled = 0;
|
||||
|
@ -628,6 +712,11 @@
|
|||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = 2D02E47A1E0B4A5D006451C7;
|
||||
};
|
||||
3271B0A8236E2E0700DA766F = {
|
||||
CreatedOnToolsVersion = 11.2;
|
||||
DevelopmentTeam = A7W54YZ4WU;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
B40D4E2F225841EC00428FCC = {
|
||||
CreatedOnToolsVersion = 10.2;
|
||||
DevelopmentTeam = A7W54YZ4WU;
|
||||
|
@ -665,6 +754,7 @@
|
|||
2D02E48F1E0B4A5D006451C7 /* BlueWallet-tvOSTests */,
|
||||
B40D4E2F225841EC00428FCC /* BlueWalletWatch */,
|
||||
B40D4E3B225841ED00428FCC /* BlueWalletWatch Extension */,
|
||||
3271B0A8236E2E0700DA766F /* TodayExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -702,6 +792,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3271B0A7236E2E0700DA766F /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3271B0B1236E2E0700DA766F /* MainInterface.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B40D4E2E225841EC00428FCC /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -938,6 +1036,16 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3271B0A5236E2E0700DA766F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3271B0BB236E329400DA766F /* API.swift in Sources */,
|
||||
3271B0AE236E2E0700DA766F /* TodayViewController.swift in Sources */,
|
||||
32002D9D236FAA9F00B93396 /* TodayDataStore.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B40D4E38225841ED00428FCC /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -973,6 +1081,11 @@
|
|||
target = 2D02E47A1E0B4A5D006451C7 /* BlueWallet-tvOS */;
|
||||
targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;
|
||||
};
|
||||
3271B0B4236E2E0700DA766F /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 3271B0A8236E2E0700DA766F /* TodayExtension */;
|
||||
targetProxy = 3271B0B3236E2E0700DA766F /* PBXContainerItemProxy */;
|
||||
};
|
||||
B40D4E3F225841ED00428FCC /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = B40D4E3B225841ED00428FCC /* BlueWalletWatch Extension */;
|
||||
|
@ -995,6 +1108,14 @@
|
|||
path = BlueWallet;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3271B0AF236E2E0700DA766F /* MainInterface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
3271B0B0236E2E0700DA766F /* Base */,
|
||||
);
|
||||
name = MainInterface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B40D4E32225841EC00428FCC /* Interface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
|
@ -1109,16 +1230,18 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9B3A324B70BC8C6D9314FD4F /* Pods-BlueWallet.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CODE_SIGN_ENTITLEMENTS = BlueWallet/BlueWallet.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = BlueWallet/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -1131,7 +1254,7 @@
|
|||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet;
|
||||
PRODUCT_NAME = BlueWallet;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "io.bluewallet.bluewallet AppStore";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
|
@ -1144,15 +1267,17 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = B459EE96941AE09BCB547DC0 /* Pods-BlueWallet.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_ENTITLEMENTS = BlueWallet/BlueWallet.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = BlueWallet/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -1387,6 +1512,67 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
3271B0B7236E2E0700DA766F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "TodayExtension/BlueWallet - Bitcoin Price.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = TodayExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension;
|
||||
PRODUCT_NAME = "BlueWallet - Bitcoin Price";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3271B0B8236E2E0700DA766F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "TodayExtension/BlueWallet - Bitcoin Price.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = TodayExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension;
|
||||
PRODUCT_NAME = "BlueWallet - Bitcoin Price";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -1438,7 +1624,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -1486,7 +1672,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
@ -1502,6 +1688,7 @@
|
|||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "BlueWalletWatch Extension/BlueWalletWatch Extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
|
@ -1535,6 +1722,7 @@
|
|||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "BlueWalletWatch Extension/BlueWalletWatch Extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
|
@ -1584,7 +1772,7 @@
|
|||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 5.0;
|
||||
};
|
||||
|
@ -1617,7 +1805,7 @@
|
|||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 5.0;
|
||||
};
|
||||
|
@ -1662,6 +1850,15 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
3271B0B9236E2E0700DA766F /* Build configuration list for PBXNativeTarget "TodayExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3271B0B7236E2E0700DA766F /* Debug */,
|
||||
3271B0B8236E2E0700DA766F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "BlueWallet" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import "RNQuickActionManager.h"
|
||||
#import <AppCenterReactNativeShared/AppCenterReactNativeShared.h>
|
||||
#import <AppCenterReactNative.h>
|
||||
#import <AppCenterReactNativeAnalytics.h>
|
||||
|
@ -49,4 +50,8 @@
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler {
|
||||
[RNQuickActionManager onQuickActionPress:shortcutItem completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.io.bluewallet.bluewallet</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -47,21 +47,6 @@
|
|||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>electrum3.bluewallet.io</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>electrum2.bluewallet.io</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>electrum1.bluewallet.io</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
|
|
|
@ -10,13 +10,13 @@ PODS:
|
|||
- AppCenter/Crashes
|
||||
- AppCenterReactNativeShared
|
||||
- React
|
||||
- AppCenter/Analytics (2.5.0):
|
||||
- AppCenter/Analytics (2.5.1):
|
||||
- AppCenter/Core
|
||||
- AppCenter/Core (2.5.0)
|
||||
- AppCenter/Crashes (2.5.0):
|
||||
- AppCenter/Core (2.5.1)
|
||||
- AppCenter/Crashes (2.5.1):
|
||||
- AppCenter/Core
|
||||
- AppCenterReactNativeShared (2.5.0):
|
||||
- AppCenter/Core (= 2.5.0)
|
||||
- AppCenterReactNativeShared (2.6.0):
|
||||
- AppCenter/Core (= 2.5.1)
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BVLinearGradient (2.5.4):
|
||||
- React
|
||||
|
@ -133,6 +133,8 @@ PODS:
|
|||
- React
|
||||
- RNCAsyncStorage (1.6.2):
|
||||
- React
|
||||
- RNDefaultPreference (1.4.1):
|
||||
- React
|
||||
- RNDeviceInfo (4.0.1):
|
||||
- React
|
||||
- RNFS (2.13.3):
|
||||
|
@ -141,6 +143,8 @@ PODS:
|
|||
- React
|
||||
- RNHandoff (0.0.3):
|
||||
- React
|
||||
- RNQuickAction (0.3.12):
|
||||
- React
|
||||
- RNRate (1.0.1):
|
||||
- React
|
||||
- RNSecureKeyStore (1.0.0):
|
||||
|
@ -156,9 +160,9 @@ PODS:
|
|||
- React
|
||||
- RNWatch (0.4.1):
|
||||
- React
|
||||
- Sentry (4.4.1):
|
||||
- Sentry/Core (= 4.4.1)
|
||||
- Sentry/Core (4.4.1)
|
||||
- Sentry (4.4.2):
|
||||
- Sentry/Core (= 4.4.2)
|
||||
- Sentry/Core (4.4.2)
|
||||
- swift_qrcodejs (1.1.2)
|
||||
- TcpSockets (3.3.2):
|
||||
- React
|
||||
|
@ -204,10 +208,12 @@ DEPENDENCIES:
|
|||
- ReactNativePrivacySnapshot (from `../node_modules/react-native-privacy-snapshot`)
|
||||
- "RemobileReactNativeQrcodeLocalImage (from `../node_modules/@remobile/react-native-qrcode-local-image`)"
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
|
||||
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
|
||||
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
|
||||
- RNFS (from `../node_modules/react-native-fs`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNHandoff (from `../node_modules/react-native-handoff`)
|
||||
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
|
||||
- RNRate (from `../node_modules/react-native-rate/ios`)
|
||||
- RNSecureKeyStore (from `../node_modules/react-native-secure-key-store/ios`)
|
||||
- "RNSentry (from `../node_modules/@sentry/react-native`)"
|
||||
|
@ -302,6 +308,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/@remobile/react-native-qrcode-local-image"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-community/async-storage"
|
||||
RNDefaultPreference:
|
||||
:path: "../node_modules/react-native-default-preference"
|
||||
RNDeviceInfo:
|
||||
:path: "../node_modules/react-native-device-info"
|
||||
RNFS:
|
||||
|
@ -310,6 +318,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNHandoff:
|
||||
:path: "../node_modules/react-native-handoff"
|
||||
RNQuickAction:
|
||||
:path: "../node_modules/react-native-quick-actions"
|
||||
RNRate:
|
||||
:path: "../node_modules/react-native-rate/ios"
|
||||
RNSecureKeyStore:
|
||||
|
@ -332,11 +342,11 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppCenter: 637f180deefc61e8ab3f94223869ee50f61dabea
|
||||
AppCenter: fddcbac6e4baae3d93a196ceb0bfe0e4ce407dec
|
||||
appcenter: bde9923b687332a25607fc1aa9577c9361cfed85
|
||||
appcenter-analytics: 0ee7a35def715d4bce58ec435f54161770195166
|
||||
appcenter-crashes: 9f9c5647dba19026ff09509576fb7233f69697ff
|
||||
AppCenterReactNativeShared: 99e7f662ec66b1cb41306ecf357aabac35931c08
|
||||
AppCenterReactNativeShared: d5e360f8a4cb5126d29e31ab98051d2f070ba631
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: 8cbc5155c978f2e43098818c91d206d07aae6d30
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
|
@ -373,10 +383,12 @@ SPEC CHECKSUMS:
|
|||
ReactNativePrivacySnapshot: cc295e45dc22810e9ff2c93380d643de20a77015
|
||||
RemobileReactNativeQrcodeLocalImage: 57aadc12896b148fb5e04bc7c6805f3565f5c3fa
|
||||
RNCAsyncStorage: 5ae4d57458804e99f73d427214442a6b10a53856
|
||||
RNDefaultPreference: 12d246dd2222e66dadcd76cc1250560663befc3a
|
||||
RNDeviceInfo: 12faae605ba42a1a5041c3c41a77834bc23f049d
|
||||
RNFS: c9bbde46b0d59619f8e7b735991c60e0f73d22c1
|
||||
RNGestureHandler: 5329a942fce3d41c68b84c2c2276ce06a696d8b0
|
||||
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa
|
||||
RNQuickAction: eca9a5dd04b5cdf8a0dd32d8be8844dc33aba2bd
|
||||
RNRate: 29be49c24b314c4e8ec09d848c3965f61cb0be47
|
||||
RNSecureKeyStore: f1ad870e53806453039f650720d2845c678d89c8
|
||||
RNSentry: 2803ba8c8129dcf26b79e9b4d8c80168be6e4390
|
||||
|
@ -384,7 +396,7 @@ SPEC CHECKSUMS:
|
|||
RNSVG: 0eb087cfb5d7937be93c45b163b26352a647e681
|
||||
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
|
||||
RNWatch: a14e378448e187cc12f307f61d41fe8a65400e86
|
||||
Sentry: 5d312a04e369154aeac616214f4dfc3cbcc8b296
|
||||
Sentry: bba998b0fb157fdd6596aa73290a9d67ae47be79
|
||||
swift_qrcodejs: 4d024fc98b0778b804ec6a5c810880fd092aec9d
|
||||
TcpSockets: 8d839b9b14f6f344d98e4642ded13ab3112b462d
|
||||
ToolTipMenu: bdcaa0e888bcf44778a67fe34639b094352e904e
|
||||
|
|
125
ios/TodayExtension/Base.lproj/MainInterface.storyboard
Normal file
125
ios/TodayExtension/Base.lproj/MainInterface.storyboard
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="M4Y-Lb-cyx">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Today View Controller-->
|
||||
<scene sceneID="cwh-vc-ff4">
|
||||
<objects>
|
||||
<viewController id="M4Y-Lb-cyx" customClass="TodayViewController" customModule="BlueWallet___Bitcoin_Price" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" simulatedAppContext="notificationCenter" id="S3S-Oj-5AN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitcoin Price" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aaf-Pc-Y9i">
|
||||
<rect key="frame" x="16" y="8" width="288" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="fON-Nf-oBQ"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bcB-MD-aJf">
|
||||
<rect key="frame" x="104" y="73" width="200" height="15"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Last Updated:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vU4-uK-6ow">
|
||||
<rect key="frame" x="16" y="73" width="80" height="15"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="USD" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lkL-gv-1a1">
|
||||
<rect key="frame" x="16" y="40" width="35" height="33"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="35" id="4Nq-zK-gi3"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bEQ-e6-Puo">
|
||||
<rect key="frame" x="59" y="46.5" width="14" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrow.up" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="eST-DU-WIK">
|
||||
<rect key="frame" x="221" y="47.5" width="17" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="17" id="gkK-pz-TDJ"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="..." textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gm7-vT-KrH" userLabel="...">
|
||||
<rect key="frame" x="290" y="40" width="14" height="33"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="14" id="KoT-51-551"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="from" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aqr-Mt-cor">
|
||||
<rect key="frame" x="246" y="40" width="36" height="33"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="33" id="u9N-WC-Os2"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="aqr-Mt-cor" firstAttribute="top" secondItem="aaf-Pc-Y9i" secondAttribute="bottom" constant="11" id="0ca-1C-JqG"/>
|
||||
<constraint firstItem="ssy-KU-ocm" firstAttribute="trailing" secondItem="aaf-Pc-Y9i" secondAttribute="trailing" constant="16" id="197-jr-Kn5"/>
|
||||
<constraint firstItem="eST-DU-WIK" firstAttribute="centerY" secondItem="aqr-Mt-cor" secondAttribute="centerY" id="2yd-pY-y1Y"/>
|
||||
<constraint firstItem="bcB-MD-aJf" firstAttribute="leading" secondItem="vU4-uK-6ow" secondAttribute="trailing" constant="8" id="5bB-Zv-Yeq"/>
|
||||
<constraint firstItem="lkL-gv-1a1" firstAttribute="leading" secondItem="ssy-KU-ocm" secondAttribute="leading" constant="16" id="Bgx-xM-CSS"/>
|
||||
<constraint firstItem="ssy-KU-ocm" firstAttribute="bottom" secondItem="bcB-MD-aJf" secondAttribute="bottom" constant="12" id="EPP-OS-3b6"/>
|
||||
<constraint firstItem="vU4-uK-6ow" firstAttribute="leading" secondItem="ssy-KU-ocm" secondAttribute="leading" constant="16" id="EkD-jp-arv"/>
|
||||
<constraint firstItem="gm7-vT-KrH" firstAttribute="centerY" secondItem="aqr-Mt-cor" secondAttribute="centerY" id="Eo2-n1-zbi"/>
|
||||
<constraint firstItem="ssy-KU-ocm" firstAttribute="bottom" secondItem="vU4-uK-6ow" secondAttribute="bottom" constant="12" id="JSh-ZE-k1H"/>
|
||||
<constraint firstItem="bcB-MD-aJf" firstAttribute="centerY" secondItem="vU4-uK-6ow" secondAttribute="centerY" id="MUL-tE-LmX"/>
|
||||
<constraint firstItem="bEQ-e6-Puo" firstAttribute="leading" secondItem="lkL-gv-1a1" secondAttribute="trailing" constant="8" id="Ml2-4o-Yqk"/>
|
||||
<constraint firstItem="ssy-KU-ocm" firstAttribute="trailing" secondItem="gm7-vT-KrH" secondAttribute="trailing" constant="16" id="OLV-lQ-T8a"/>
|
||||
<constraint firstItem="gm7-vT-KrH" firstAttribute="centerY" secondItem="bEQ-e6-Puo" secondAttribute="centerY" id="Rle-PT-j9m"/>
|
||||
<constraint firstItem="gm7-vT-KrH" firstAttribute="leading" secondItem="aqr-Mt-cor" secondAttribute="trailing" constant="8" id="Rtu-ah-AvP"/>
|
||||
<constraint firstItem="gm7-vT-KrH" firstAttribute="firstBaseline" secondItem="aqr-Mt-cor" secondAttribute="firstBaseline" id="YIV-xq-qlw"/>
|
||||
<constraint firstItem="bEQ-e6-Puo" firstAttribute="centerY" secondItem="lkL-gv-1a1" secondAttribute="centerY" id="Ys3-7f-RIc"/>
|
||||
<constraint firstItem="aaf-Pc-Y9i" firstAttribute="leading" secondItem="S3S-Oj-5AN" secondAttribute="leading" constant="16" id="a1b-Yq-aZb"/>
|
||||
<constraint firstItem="aaf-Pc-Y9i" firstAttribute="top" secondItem="S3S-Oj-5AN" secondAttribute="top" constant="8" id="aIo-h1-w4F"/>
|
||||
<constraint firstItem="lkL-gv-1a1" firstAttribute="top" secondItem="aaf-Pc-Y9i" secondAttribute="bottom" constant="11" id="dET-8J-W4K"/>
|
||||
<constraint firstItem="ssy-KU-ocm" firstAttribute="trailing" secondItem="bcB-MD-aJf" secondAttribute="trailing" constant="16" id="kkD-VZ-BAt"/>
|
||||
<constraint firstItem="vU4-uK-6ow" firstAttribute="firstBaseline" secondItem="lkL-gv-1a1" secondAttribute="baseline" constant="16" symbolType="layoutAnchor" id="lml-Hc-8Sv"/>
|
||||
<constraint firstItem="aqr-Mt-cor" firstAttribute="leading" secondItem="eST-DU-WIK" secondAttribute="trailing" constant="8" id="t4j-U9-sOm"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="ssy-KU-ocm"/>
|
||||
</view>
|
||||
<extendedEdge key="edgesForExtendedLayout"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<size key="freeformSize" width="320" height="100"/>
|
||||
<connections>
|
||||
<outlet property="currencyLabel" destination="lkL-gv-1a1" id="Gzb-TF-E6W"/>
|
||||
<outlet property="lastPrice" destination="gm7-vT-KrH" id="YIE-KJ-0qW"/>
|
||||
<outlet property="lastPriceArrowImage" destination="eST-DU-WIK" id="VWH-ED-VL1"/>
|
||||
<outlet property="lastPriceFromLabel" destination="aqr-Mt-cor" id="p17-Aq-ufa"/>
|
||||
<outlet property="lastUpdatedDate" destination="bcB-MD-aJf" id="A9U-MB-qJq"/>
|
||||
<outlet property="priceLabel" destination="bEQ-e6-Puo" id="0IP-Yg-dWr"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="vXp-U4-Rya" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="137.68115942028987" y="96.428571428571431"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="arrow.up" catalog="system" width="60" height="64"/>
|
||||
</resources>
|
||||
</document>
|
10
ios/TodayExtension/BlueWallet - Bitcoin Price.entitlements
Normal file
10
ios/TodayExtension/BlueWallet - Bitcoin Price.entitlements
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.io.bluewallet.bluewallet</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
31
ios/TodayExtension/Info.plist
Normal file
31
ios/TodayExtension/Info.plist
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.7.3</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.widget-extension</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
65
ios/TodayExtension/New Group/API.swift
Normal file
65
ios/TodayExtension/New Group/API.swift
Normal file
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// API.swift
|
||||
// TodayExtension
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/2/19.
|
||||
// Copyright © 2019 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class API {
|
||||
|
||||
static func fetchPrice(currency: String, completion: @escaping ((Dictionary<String, Any>?, Error?) -> Void)) {
|
||||
guard let url = URL(string: "https://api.coindesk.com/v1/bpi/currentPrice/\(currency).json") else {return}
|
||||
|
||||
URLSession.shared.dataTask(with: url) { (data, response, error) in
|
||||
guard let dataResponse = data,
|
||||
let json = try? JSONSerialization.jsonObject(with: dataResponse, options: .mutableContainers) as? Dictionary<String, Any>,
|
||||
error == nil else {
|
||||
print(error?.localizedDescription ?? "Response Error")
|
||||
completion(nil, error)
|
||||
return }
|
||||
|
||||
completion(json, nil)
|
||||
}.resume()
|
||||
}
|
||||
|
||||
static func getUserPreferredCurrency() -> String {
|
||||
guard let userDefaults = UserDefaults(suiteName: "group.io.bluewallet.bluewallet"),
|
||||
let preferredCurrency = userDefaults.string(forKey: "preferredCurrency")
|
||||
else {
|
||||
return "USD"
|
||||
}
|
||||
|
||||
if preferredCurrency != API.getLastSelectedCurrency() {
|
||||
UserDefaults.standard.removeObject(forKey: TodayData.TodayCachedDataStoreKey)
|
||||
UserDefaults.standard.removeObject(forKey: TodayData.TodayDataStoreKey)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
return preferredCurrency
|
||||
}
|
||||
|
||||
static func getUserPreferredCurrencyLocale() -> String {
|
||||
guard let userDefaults = UserDefaults(suiteName: "group.io.bluewallet.bluewallet"),
|
||||
let preferredCurrency = userDefaults.string(forKey: "preferredCurrencyLocale")
|
||||
else {
|
||||
return "en_US"
|
||||
}
|
||||
return preferredCurrency
|
||||
}
|
||||
|
||||
static func getLastSelectedCurrency() -> String {
|
||||
guard let dataStore = UserDefaults.standard.string(forKey: "currency") else {
|
||||
return "USD"
|
||||
}
|
||||
|
||||
return dataStore
|
||||
}
|
||||
|
||||
static func saveNewSelectedCurrency() {
|
||||
UserDefaults.standard.setValue(API.getUserPreferredCurrency(), forKey: "currency")
|
||||
}
|
||||
|
||||
}
|
89
ios/TodayExtension/TodayDataStore.swift
Normal file
89
ios/TodayExtension/TodayDataStore.swift
Normal file
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// TodayDataStore.swift
|
||||
// TodayExtension
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/3/19.
|
||||
// Copyright © 2019 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TodayDataStore {
|
||||
let rate: String
|
||||
let lastUpdate: String
|
||||
|
||||
var formattedDate: String? {
|
||||
let isoDateFormatter = ISO8601DateFormatter()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.timeStyle = .short
|
||||
dateFormatter.dateStyle = .short
|
||||
|
||||
if let date = isoDateFormatter.date(from: lastUpdate) {
|
||||
return dateFormatter.string(from: date)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var rateDoubleValue: Double? {
|
||||
let rateDigits = rate.replacingOccurrences(of: ",", with: "");
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.numberStyle = .decimal
|
||||
numberFormatter.maximumFractionDigits = 2
|
||||
numberFormatter.minimumFractionDigits = 2
|
||||
|
||||
if let rateDoubleValue = numberFormatter.number(from: rateDigits) {
|
||||
return rateDoubleValue.doubleValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var formattedRate: String? {
|
||||
let rateDigits = rate.replacingOccurrences(of: ",", with: "");
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.numberStyle = .decimal
|
||||
numberFormatter.maximumFractionDigits = 2
|
||||
numberFormatter.minimumFractionDigits = 2
|
||||
if let rateNumber = numberFormatter.number(from: rateDigits) {
|
||||
numberFormatter.numberStyle = .currency
|
||||
numberFormatter.locale = Locale(identifier: API.getUserPreferredCurrencyLocale())
|
||||
return numberFormatter.string(from: rateNumber);
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
class TodayData {
|
||||
|
||||
static let TodayDataStoreKey = "TodayDataStoreKey"
|
||||
static let TodayCachedDataStoreKey = "TodayCachedDataStoreKey"
|
||||
|
||||
static func savePriceRateAndLastUpdate(rate: String, lastUpdate: String) {
|
||||
UserDefaults.standard.setValue(["rate": rate, "lastUpdate": lastUpdate], forKey: TodayDataStoreKey)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
static func getPriceRateAndLastUpdate() -> TodayDataStore? {
|
||||
guard let dataStore = UserDefaults.standard.value(forKey: TodayDataStoreKey) as? [String: String], let rate = dataStore["rate"], let lastUpdate = dataStore["lastUpdate"] else {
|
||||
return nil
|
||||
}
|
||||
return TodayDataStore(rate: rate, lastUpdate: lastUpdate)
|
||||
}
|
||||
|
||||
static func saveCachePriceRateAndLastUpdate(rate: String, lastUpdate: String) {
|
||||
UserDefaults.standard.setValue(["rate": rate, "lastUpdate": lastUpdate], forKey: TodayCachedDataStoreKey)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
static func getCachedPriceRateAndLastUpdate() -> TodayDataStore? {
|
||||
guard let dataStore = UserDefaults.standard.value(forKey: TodayCachedDataStoreKey) as? [String: String], var rate = dataStore["rate"], let lastUpdate = dataStore["lastUpdate"] else {
|
||||
return nil
|
||||
}
|
||||
rate = rate.replacingOccurrences(of: ",", with: "");
|
||||
return TodayDataStore(rate: rate, lastUpdate: lastUpdate)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
130
ios/TodayExtension/TodayViewController.swift
Normal file
130
ios/TodayExtension/TodayViewController.swift
Normal file
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// TodayViewController.swift
|
||||
// TodayExtension
|
||||
//
|
||||
// Created by Marcos Rodriguez on 11/2/19.
|
||||
// Copyright © 2019 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import NotificationCenter
|
||||
|
||||
class TodayViewController: UIViewController, NCWidgetProviding {
|
||||
|
||||
|
||||
@IBOutlet weak var currencyLabel: UILabel!
|
||||
@IBOutlet weak var lastUpdatedDate: UILabel!
|
||||
@IBOutlet weak var priceLabel: UILabel!
|
||||
|
||||
@IBOutlet weak var lastPriceArrowImage: UIImageView!
|
||||
@IBOutlet weak var lastPrice: UILabel!
|
||||
@IBOutlet weak var lastPriceFromLabel: UILabel!
|
||||
private var lastPriceNumber: NSNumber?
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
setLastPriceOutletsHidden(isHidden: true)
|
||||
if let lastStoredTodayStore = TodayData.getPriceRateAndLastUpdate() {
|
||||
processRateAndLastUpdate(todayStore: lastStoredTodayStore)
|
||||
} else {
|
||||
setLastPriceOutletsHidden(isHidden: true)
|
||||
}
|
||||
}
|
||||
|
||||
func setLastPriceOutletsHidden(isHidden: Bool) {
|
||||
lastPrice.isHidden = isHidden
|
||||
lastPriceFromLabel.isHidden = isHidden
|
||||
lastPriceArrowImage.isHidden = isHidden
|
||||
}
|
||||
|
||||
func processRateAndLastUpdate(todayStore: TodayDataStore) {
|
||||
guard let rateString = todayStore.formattedRate, let dateFormatted = todayStore.formattedDate else { return }
|
||||
|
||||
priceLabel.text = rateString
|
||||
lastUpdatedDate.text = dateFormatted
|
||||
}
|
||||
|
||||
func processStoredRateAndLastUpdate(todayStore: TodayDataStore) {
|
||||
guard let lastPriceNumber = todayStore.formattedRate else { return }
|
||||
|
||||
lastPrice.text = lastPriceNumber
|
||||
}
|
||||
|
||||
func processCachedStoredRateAndLastUpdate(new: TodayDataStore, cached: TodayDataStore) {
|
||||
guard let newPriceDoubleValue = new.rateDoubleValue, let cachedPriceNumber = cached.formattedRate, let cachedPriceNumberDoubleValue = cached.rateDoubleValue else { return }
|
||||
|
||||
lastPrice.text = cachedPriceNumber
|
||||
|
||||
|
||||
if newPriceDoubleValue > cachedPriceNumberDoubleValue {
|
||||
self.lastPriceArrowImage.image = UIImage(systemName: "arrow.up")
|
||||
self.setLastPriceOutletsHidden(isHidden: false)
|
||||
} else {
|
||||
self.lastPriceArrowImage.image = UIImage(systemName: "arrow.down")
|
||||
self.setLastPriceOutletsHidden(isHidden: false)
|
||||
}
|
||||
}
|
||||
|
||||
func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
|
||||
// Perform any setup necessary in order to update the view.
|
||||
|
||||
// If an error is encountered, use NCUpdateResult.Failed
|
||||
// If there's no update required, use NCUpdateResult.NoData
|
||||
// If there's an update, use NCUpdateResult.NewData
|
||||
let userPreferredCurrency = API.getUserPreferredCurrency();
|
||||
self.currencyLabel.text = userPreferredCurrency
|
||||
API.fetchPrice(currency: userPreferredCurrency, completion: { (result, error) in
|
||||
DispatchQueue.main.async { [unowned self] in
|
||||
guard let result = result else {
|
||||
completionHandler(.failed)
|
||||
return
|
||||
}
|
||||
|
||||
guard let bpi = result["bpi"] as? Dictionary<String, Any>, let preferredCurrency = bpi[userPreferredCurrency] as? Dictionary<String, Any>, let rateString = preferredCurrency["rate"] as? String,
|
||||
let time = result["time"] as? Dictionary<String, Any>, let lastUpdatedString = time["updatedISO"] as? String
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
let latestRateDataStore = TodayDataStore(rate: rateString, lastUpdate: lastUpdatedString)
|
||||
|
||||
if let lastStoredTodayStore = TodayData.getPriceRateAndLastUpdate(), lastStoredTodayStore.lastUpdate == latestRateDataStore.lastUpdate, rateString == lastStoredTodayStore.rate, API.getLastSelectedCurrency() == userPreferredCurrency {
|
||||
if let cached = TodayData.getCachedPriceRateAndLastUpdate() {
|
||||
self.processCachedStoredRateAndLastUpdate(new: lastStoredTodayStore, cached: cached)
|
||||
} else {
|
||||
self.setLastPriceOutletsHidden(isHidden: true)
|
||||
}
|
||||
completionHandler(.noData)
|
||||
} else {
|
||||
self.processRateAndLastUpdate(todayStore: latestRateDataStore)
|
||||
let priceRiceAndLastUpdate = TodayData.getPriceRateAndLastUpdate()
|
||||
|
||||
if let rate = priceRiceAndLastUpdate?.rate, let lastUpdate = priceRiceAndLastUpdate?.lastUpdate {
|
||||
TodayData.saveCachePriceRateAndLastUpdate(rate: rate, lastUpdate: lastUpdate);
|
||||
}
|
||||
|
||||
if let latestRateDataStore = latestRateDataStore.rateDoubleValue, let lastStoredPriceNumber = priceRiceAndLastUpdate?.rateDoubleValue, API.getLastSelectedCurrency() == userPreferredCurrency {
|
||||
|
||||
if latestRateDataStore > lastStoredPriceNumber {
|
||||
self.lastPriceArrowImage.image = UIImage(systemName: "arrow.up")
|
||||
self.setLastPriceOutletsHidden(isHidden: false)
|
||||
} else {
|
||||
self.lastPriceArrowImage.image = UIImage(systemName: "arrow.down")
|
||||
self.setLastPriceOutletsHidden(isHidden: false)
|
||||
}
|
||||
self.lastPrice.text = priceRiceAndLastUpdate?.formattedRate
|
||||
} else {
|
||||
self.setLastPriceOutletsHidden(isHidden: true)
|
||||
}
|
||||
|
||||
TodayData.savePriceRateAndLastUpdate(rate: latestRateDataStore.rate, lastUpdate: latestRateDataStore.lastUpdate)
|
||||
API.saveNewSelectedCurrency()
|
||||
completionHandler(.newData)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -12227,6 +12227,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-native-default-preference": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-default-preference/-/react-native-default-preference-1.4.1.tgz",
|
||||
"integrity": "sha512-UHX8Hsgq2AwEI8SA1IkjU+u6y+Uroht0sCP70UVLhEZWyqRnn8elrcEjRSInWFNUwxSeFF/c7Tnf17fWFHZEcw=="
|
||||
},
|
||||
"react-native-device-info": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-4.0.1.tgz",
|
||||
|
@ -12331,6 +12336,11 @@
|
|||
"qrcode": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"react-native-quick-actions": {
|
||||
"version": "0.3.12",
|
||||
"resolved": "https://registry.npmjs.org/react-native-quick-actions/-/react-native-quick-actions-0.3.12.tgz",
|
||||
"integrity": "sha512-jQkzbA6L1/+FIqvHnPenHUe2IrBihh48KOMTOa0QbOaxWzsejSB8kkWpSQOjYxjGu7k+3DVgosQ8wGJTB/l4JA=="
|
||||
},
|
||||
"react-native-randombytes": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-randombytes/-/react-native-randombytes-3.5.3.tgz",
|
||||
|
@ -12391,9 +12401,9 @@
|
|||
"integrity": "sha512-J8Xl3mq0L9KDFtSYtKsQDAnZWw/niZIpAD1PRiNfZFHo44Rc+oS2bEIhskNnoQXKEgBNdPzCl/DenMXYAHXRYg=="
|
||||
},
|
||||
"react-native-snap-carousel": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-snap-carousel/-/react-native-snap-carousel-3.8.0.tgz",
|
||||
"integrity": "sha512-YtDZLv2Di77HfnH4yf+NyyYyISPNjrnjXDQLrzOkG9kkSlho/BROgHLQKGRLg3C2YSUMArFOePrb9CH3yeV5FA==",
|
||||
"version": "3.8.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-snap-carousel/-/react-native-snap-carousel-3.8.4.tgz",
|
||||
"integrity": "sha512-KMxLl75Tyf12DzeTCtV7xU0KuPZQQs/2+2iM90cgxcm3lrg4+hLXff5/61ynasBkzzJ5v4bTRq5CEy/qGUJVQw==",
|
||||
"requires": {
|
||||
"prop-types": "^15.6.1",
|
||||
"react-addons-shallow-compare": "15.6.2"
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
"react-native": "0.60.5",
|
||||
"react-native-biometrics": "git+https://github.com/BlueWallet/react-native-biometrics.git",
|
||||
"react-native-camera": "3.4.0",
|
||||
"react-native-default-preference": "1.4.1",
|
||||
"react-native-device-info": "4.0.1",
|
||||
"react-native-elements": "0.19.0",
|
||||
"react-native-flexi-radio-button": "0.2.2",
|
||||
|
@ -106,11 +107,12 @@
|
|||
"react-native-privacy-snapshot": "git+https://github.com/BlueWallet/react-native-privacy-snapshot.git",
|
||||
"react-native-prompt-android": "git+https://github.com/marcosrdz/react-native-prompt-android.git",
|
||||
"react-native-qrcode-svg": "5.1.2",
|
||||
"react-native-quick-actions": "0.3.12",
|
||||
"react-native-randombytes": "3.5.3",
|
||||
"react-native-rate": "1.1.7",
|
||||
"react-native-secure-key-store": "git+https://github.com/marcosrdz/react-native-secure-key-store.git",
|
||||
"react-native-share": "2.0.0",
|
||||
"react-native-snap-carousel": "3.8.0",
|
||||
"react-native-snap-carousel": "3.8.4",
|
||||
"react-native-sortable-list": "0.0.23",
|
||||
"react-native-svg": "9.5.1",
|
||||
"react-native-tcp": "git+https://github.com/aprock/react-native-tcp.git",
|
||||
|
|
|
@ -5,8 +5,6 @@ import { Icon } from 'react-native-elements';
|
|||
import { NavigationEvents } from 'react-navigation';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
import PropTypes from 'prop-types';
|
||||
import WalletGradient from '../../class/walletGradient';
|
||||
import OnAppLaunch from '../../class/onAppLaunch';
|
||||
let EV = require('../../events');
|
||||
let A = require('../../analytics');
|
||||
/** @type {AppStorage} */
|
||||
|
@ -51,13 +49,6 @@ export default class WalletsList extends Component {
|
|||
// the idea is that upon wallet launch we will refresh
|
||||
// all balances and all transactions here:
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
const isViewAllWalletsEnabled = await OnAppLaunch.isViewAllWalletsEnabled();
|
||||
if (!isViewAllWalletsEnabled) {
|
||||
const selectedDefaultWallet = await OnAppLaunch.getSelectedDefaultWallet();
|
||||
const walletIndex = this.state.wallets.findIndex(wallet => wallet.getID() === selectedDefaultWallet.getID());
|
||||
this.handleClick(walletIndex);
|
||||
}
|
||||
|
||||
let noErr = true;
|
||||
try {
|
||||
await BlueElectrum.waitTillConnected();
|
||||
|
@ -143,7 +134,7 @@ export default class WalletsList extends Component {
|
|||
if (wallet) {
|
||||
this.props.navigation.navigate('WalletTransactions', {
|
||||
wallet: wallet,
|
||||
headerColor: WalletGradient.headerColorFor(wallet.type),
|
||||
key: `WalletTransactions-${wallet.getID()}`,
|
||||
});
|
||||
} else {
|
||||
// if its out of index - this must be last card with incentive to create wallet
|
||||
|
@ -266,6 +257,7 @@ export default class WalletsList extends Component {
|
|||
>
|
||||
<BlueHeaderDefaultMain leftText={loc.wallets.list.title} onNewWalletPress={() => this.props.navigation.navigate('AddWallet')} />
|
||||
<WalletsCarousel
|
||||
removeClippedSubviews={false}
|
||||
data={this.state.wallets}
|
||||
handleClick={index => {
|
||||
this.handleClick(index);
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
BlueTransactionListItem,
|
||||
BlueWalletNavigationHeader,
|
||||
} from '../../BlueComponents';
|
||||
import WalletGradient from '../../class/walletGradient';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { LightningCustodianWallet } from '../../class';
|
||||
import Handoff from 'react-native-handoff';
|
||||
|
@ -54,7 +55,7 @@ export default class WalletTransactions extends Component {
|
|||
</TouchableOpacity>
|
||||
),
|
||||
headerStyle: {
|
||||
backgroundColor: navigation.getParam('headerColor'),
|
||||
backgroundColor: WalletGradient.headerColorFor(navigation.state.params.wallet.type),
|
||||
borderBottomWidth: 0,
|
||||
elevation: 0,
|
||||
shadowRadius: 0,
|
||||
|
@ -354,29 +355,28 @@ export default class WalletTransactions extends Component {
|
|||
};
|
||||
|
||||
onWalletSelect = async wallet => {
|
||||
NavigationService.navigate('WalletTransactions');
|
||||
/** @type {LightningCustodianWallet} */
|
||||
let toAddress = false;
|
||||
if (this.state.wallet.refill_addressess.length > 0) {
|
||||
toAddress = this.state.wallet.refill_addressess[0];
|
||||
} else {
|
||||
try {
|
||||
await this.state.wallet.fetchBtcAddress();
|
||||
toAddress = this.state.wallet.refill_addressess[0];
|
||||
} catch (Err) {
|
||||
return alert(Err.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (wallet) {
|
||||
NavigationService.navigate('WalletTransactions', {
|
||||
key: `WalletTransactions-${wallet.getID()}`,
|
||||
});
|
||||
/** @type {LightningCustodianWallet} */
|
||||
let toAddress = false;
|
||||
if (this.state.wallet.refill_addressess.length > 0) {
|
||||
toAddress = this.state.wallet.refill_addressess[0];
|
||||
} else {
|
||||
try {
|
||||
await this.state.wallet.fetchBtcAddress();
|
||||
toAddress = this.state.wallet.refill_addressess[0];
|
||||
} catch (Err) {
|
||||
return alert(Err.message);
|
||||
}
|
||||
}
|
||||
this.props.navigation.navigate('SendDetails', {
|
||||
memo: loc.lnd.refill_lnd_balance,
|
||||
fromSecret: wallet.getSecret(),
|
||||
address: toAddress,
|
||||
fromWallet: wallet,
|
||||
});
|
||||
} else {
|
||||
return alert('Internal error');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,3 +5,18 @@ jest.mock('react-native-watch-connectivity', () => {
|
|||
updateApplicationContext: jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock('react-native-quick-actions', () => {
|
||||
return {
|
||||
clearShortcutItems: jest.fn(),
|
||||
setQuickActions: jest.fn(),
|
||||
isSupported: jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock('react-native-default-preference', () => {
|
||||
return {
|
||||
setName: jest.fn(),
|
||||
set: jest.fn(),
|
||||
}
|
||||
})
|
Loading…
Add table
Reference in a new issue