mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
add config, usb status fixes
This commit is contained in:
parent
fdd8327464
commit
7fc0e9b530
12 changed files with 194 additions and 53 deletions
|
@ -69,7 +69,7 @@ jlink {
|
||||||
jpackage {
|
jpackage {
|
||||||
imageName = "Sparrow"
|
imageName = "Sparrow"
|
||||||
installerName = "Sparrow"
|
installerName = "Sparrow"
|
||||||
appVersion = "0.51"
|
appVersion = "0.6"
|
||||||
skipInstaller = true
|
skipInstaller = true
|
||||||
imageOptions = []
|
imageOptions = []
|
||||||
installerOptions = [
|
installerOptions = [
|
||||||
|
|
|
@ -290,6 +290,7 @@ public class AppController implements Initializable {
|
||||||
throw new IOException("Unsupported file type");
|
throw new IOException("Unsupported file type");
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
showErrorDialog("Error Opening Wallet", e.getMessage());
|
showErrorDialog("Error Opening Wallet", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,7 +381,8 @@ public class AppController implements Initializable {
|
||||||
controller.setWalletForm(walletForm);
|
controller.setWalletForm(walletForm);
|
||||||
|
|
||||||
if(!storage.getWalletFile().exists() || wallet.containsSource(KeystoreSource.HW_USB)) {
|
if(!storage.getWalletFile().exists() || wallet.containsSource(KeystoreSource.HW_USB)) {
|
||||||
Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(null);
|
Hwi.ScheduledEnumerateService enumerateService = new Hwi.ScheduledEnumerateService(null);
|
||||||
|
enumerateService.setPeriod(new Duration(30 * 1000));
|
||||||
enumerateService.setOnSucceeded(workerStateEvent -> {
|
enumerateService.setOnSucceeded(workerStateEvent -> {
|
||||||
List<Device> devices = enumerateService.getValue();
|
List<Device> devices = enumerateService.getValue();
|
||||||
EventManager.get().post(new UsbDeviceEvent(devices));
|
EventManager.get().post(new UsbDeviceEvent(devices));
|
||||||
|
@ -536,19 +538,26 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void usbDevicesFound(UsbDeviceEvent event) {
|
public void usbDevicesFound(UsbDeviceEvent event) {
|
||||||
if(event.getDevices().isEmpty()) {
|
UsbStatusButton usbStatus = null;
|
||||||
Node usbStatus = null;
|
for(Node node : statusBar.getRightItems()) {
|
||||||
for(Node node : statusBar.getRightItems()) {
|
if(node instanceof UsbStatusButton) {
|
||||||
if(node instanceof UsbStatusButton) {
|
usbStatus = (UsbStatusButton)node;
|
||||||
usbStatus = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.getDevices().isEmpty()) {
|
||||||
if(usbStatus != null) {
|
if(usbStatus != null) {
|
||||||
statusBar.getRightItems().removeAll(usbStatus);
|
statusBar.getRightItems().removeAll(usbStatus);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UsbStatusButton usbStatusButton = new UsbStatusButton(event.getDevices());
|
if(usbStatus == null) {
|
||||||
statusBar.getRightItems().add(usbStatusButton);
|
usbStatus = new UsbStatusButton();
|
||||||
|
statusBar.getRightItems().add(usbStatus);
|
||||||
|
} else {
|
||||||
|
usbStatus.getItems().remove(0, usbStatus.getItems().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
usbStatus.setDevices(event.getDevices());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.sparrowwallet.sparrow;
|
||||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.keystoreimport.KeystoreImportDialog;
|
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
@ -14,9 +13,6 @@ import javafx.scene.image.Image;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.controlsfx.glyphfont.GlyphFontRegistry;
|
import org.controlsfx.glyphfont.GlyphFontRegistry;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
public class MainApp extends Application {
|
public class MainApp extends Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,9 +42,6 @@ public class MainApp extends Application {
|
||||||
// KeystoreImportDialog dlg = new KeystoreImportDialog(wallet);
|
// KeystoreImportDialog dlg = new KeystoreImportDialog(wallet);
|
||||||
// dlg.showAndWait();
|
// dlg.showAndWait();
|
||||||
|
|
||||||
Path path = Paths.get("").toAbsolutePath();
|
|
||||||
System.out.println(path.toFile().getAbsolutePath());
|
|
||||||
|
|
||||||
stage.show();
|
stage.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||||
import com.sparrowwallet.sparrow.io.Device;
|
import com.sparrowwallet.sparrow.io.Device;
|
||||||
import javafx.geometry.Side;
|
import javafx.geometry.Side;
|
||||||
|
@ -10,33 +11,41 @@ import org.controlsfx.glyphfont.Glyph;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UsbStatusButton extends MenuButton {
|
public class UsbStatusButton extends MenuButton {
|
||||||
private final List<Device> devices;
|
public UsbStatusButton() {
|
||||||
|
|
||||||
public UsbStatusButton(List<Device> devices) {
|
|
||||||
super("");
|
super("");
|
||||||
setGraphic(getIcon());
|
setGraphic(getIcon());
|
||||||
this.devices = devices;
|
|
||||||
|
|
||||||
this.setPopupSide(Side.TOP);
|
getStyleClass().add("status-bar-button");
|
||||||
|
this.setPopupSide(Side.RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevices(List<Device> devices) {
|
||||||
for(Device device : devices) {
|
for(Device device : devices) {
|
||||||
MenuItem deviceItem = new MenuItem(device.getModel().toDisplayString());
|
MenuItem deviceItem = new MenuItem(device.getModel().toDisplayString());
|
||||||
|
if(device.getNeedsPinSent()) {
|
||||||
|
deviceItem.setGraphic(getLockIcon());
|
||||||
|
} else {
|
||||||
|
deviceItem.setGraphic(getLockOpenIcon());
|
||||||
|
}
|
||||||
getItems().add(deviceItem);
|
getItems().add(deviceItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node getIcon() {
|
private Node getIcon() {
|
||||||
Glyph usb = new Glyph(FontAwesome5Brands.FONT_NAME, FontAwesome5Brands.Glyph.USB);
|
Glyph usb = new Glyph(FontAwesome5Brands.FONT_NAME, FontAwesome5Brands.Glyph.USB);
|
||||||
usb.setFontSize(10);
|
usb.setFontSize(15);
|
||||||
return usb;
|
return usb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UsbStatusContextMenu extends ContextMenu {
|
private Node getLockIcon() {
|
||||||
public UsbStatusContextMenu() {
|
Glyph usb = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.LOCK);
|
||||||
for(Device device : devices) {
|
usb.setFontSize(12);
|
||||||
MenuItem deviceItem = new MenuItem(device.getModel().toDisplayString());
|
return usb;
|
||||||
getItems().add(deviceItem);
|
}
|
||||||
}
|
|
||||||
}
|
private Node getLockOpenIcon() {
|
||||||
|
Glyph usb = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.LOCK_OPEN);
|
||||||
|
usb.setFontSize(12);
|
||||||
|
return usb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
package com.sparrowwallet.sparrow.event;
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class StorageEvent extends TimedEvent {
|
public class StorageEvent extends TimedEvent {
|
||||||
private static boolean firstRunDone = false;
|
private static boolean firstRunDone = false;
|
||||||
private static int keyDerivationPeriod = -1;
|
|
||||||
private static final Map<File, Long> eventTime = new HashMap<>();
|
private static final Map<File, Long> eventTime = new HashMap<>();
|
||||||
|
|
||||||
public StorageEvent(File file, Action action, String status) {
|
public StorageEvent(File file, Action action, String status) {
|
||||||
super(action, status);
|
super(action, status);
|
||||||
|
|
||||||
|
Integer keyDerivationPeriod = Config.get().getKeyDerivationPeriod();
|
||||||
|
if(keyDerivationPeriod == null) {
|
||||||
|
keyDerivationPeriod = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(action == Action.START) {
|
if(action == Action.START) {
|
||||||
eventTime.put(file, System.currentTimeMillis());
|
eventTime.put(file, System.currentTimeMillis());
|
||||||
timeMills = keyDerivationPeriod;
|
timeMills = keyDerivationPeriod;
|
||||||
|
@ -19,9 +25,9 @@ public class StorageEvent extends TimedEvent {
|
||||||
long start = eventTime.get(file);
|
long start = eventTime.get(file);
|
||||||
if(firstRunDone) {
|
if(firstRunDone) {
|
||||||
keyDerivationPeriod = (int)(System.currentTimeMillis() - start);
|
keyDerivationPeriod = (int)(System.currentTimeMillis() - start);
|
||||||
|
Config.get().setKeyDerivationPeriod(keyDerivationPeriod);
|
||||||
}
|
}
|
||||||
firstRunDone = true;
|
firstRunDone = true;
|
||||||
System.out.println(keyDerivationPeriod);
|
|
||||||
timeMills = 0;
|
timeMills = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ public class FontAwesome5 extends GlyphFont {
|
||||||
EYE('\uf06e'),
|
EYE('\uf06e'),
|
||||||
KEY('\uf084'),
|
KEY('\uf084'),
|
||||||
LAPTOP('\uf109'),
|
LAPTOP('\uf109'),
|
||||||
|
LOCK('\uf023'),
|
||||||
|
LOCK_OPEN('\uf3c1'),
|
||||||
SD_CARD('\uf7c2'),
|
SD_CARD('\uf7c2'),
|
||||||
WALLET('\uf555');
|
WALLET('\uf555');
|
||||||
|
|
||||||
|
|
99
src/main/java/com/sparrowwallet/sparrow/io/Config.java
Normal file
99
src/main/java/com/sparrowwallet/sparrow/io/Config.java
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package com.sparrowwallet.sparrow.io;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import com.sparrowwallet.drongo.Utils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class Config {
|
||||||
|
public static final String CONFIG_FILENAME = ".config";
|
||||||
|
|
||||||
|
private Integer keyDerivationPeriod;
|
||||||
|
private File hwi;
|
||||||
|
|
||||||
|
private static Config INSTANCE;
|
||||||
|
|
||||||
|
private static Gson getGson() {
|
||||||
|
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||||
|
gsonBuilder.registerTypeAdapter(File.class, new FileSerializer());
|
||||||
|
gsonBuilder.registerTypeAdapter(File.class, new FileDeserializer());
|
||||||
|
return gsonBuilder.setPrettyPrinting().disableHtmlEscaping().create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getConfigFile() {
|
||||||
|
return new File(Storage.getSparrowDir(), CONFIG_FILENAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Config load() {
|
||||||
|
File configFile = getConfigFile();
|
||||||
|
if(configFile.exists()) {
|
||||||
|
try {
|
||||||
|
Reader reader = new FileReader(configFile);
|
||||||
|
Config config = getGson().fromJson(reader, Config.class);
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
if(config != null) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
//Ignore and assume no config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Config();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized Config get() {
|
||||||
|
if(INSTANCE == null) {
|
||||||
|
INSTANCE = load();
|
||||||
|
}
|
||||||
|
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getKeyDerivationPeriod() {
|
||||||
|
return keyDerivationPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyDerivationPeriod(Integer keyDerivationPeriod) {
|
||||||
|
this.keyDerivationPeriod = keyDerivationPeriod;
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getHwi() {
|
||||||
|
return hwi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHwi(File hwi) {
|
||||||
|
this.hwi = hwi;
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flush() {
|
||||||
|
Gson gson = getGson();
|
||||||
|
try {
|
||||||
|
File configFile = getConfigFile();
|
||||||
|
Writer writer = new FileWriter(configFile);
|
||||||
|
gson.toJson(this, writer);
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
//Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FileSerializer implements JsonSerializer<File> {
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(File src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FileDeserializer implements JsonDeserializer<File> {
|
||||||
|
@Override
|
||||||
|
public File deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return new File(json.getAsJsonPrimitive().getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import com.google.common.io.ByteStreams;
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||||
|
import javafx.concurrent.ScheduledService;
|
||||||
import javafx.concurrent.Service;
|
import javafx.concurrent.Service;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
|
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
|
||||||
|
@ -23,8 +24,6 @@ import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
public class Hwi {
|
public class Hwi {
|
||||||
private static File hwiExecutable;
|
|
||||||
|
|
||||||
public List<Device> enumerate(String passphrase) throws ImportException {
|
public List<Device> enumerate(String passphrase) throws ImportException {
|
||||||
try {
|
try {
|
||||||
List<String> command;
|
List<String> command;
|
||||||
|
@ -86,9 +85,10 @@ public class Hwi {
|
||||||
return CharStreams.toString(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
|
return CharStreams.toString(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized File getHwiExecutable() throws IOException {
|
private synchronized File getHwiExecutable() {
|
||||||
try {
|
File hwiExecutable = Config.get().getHwi();
|
||||||
if (hwiExecutable == null) {
|
if(hwiExecutable == null || !hwiExecutable.exists()) {
|
||||||
|
try {
|
||||||
Platform platform = Platform.getCurrent();
|
Platform platform = Platform.getCurrent();
|
||||||
Set<PosixFilePermission> ownerExecutableWritable = PosixFilePermissions.fromString("rwxr--r--");
|
Set<PosixFilePermission> ownerExecutableWritable = PosixFilePermissions.fromString("rwxr--r--");
|
||||||
|
|
||||||
|
@ -100,16 +100,15 @@ public class Hwi {
|
||||||
InputStream inputStream = Hwi.class.getResourceAsStream("/external/" + platform.getPlatformId().toLowerCase() + "/hwi-1.1.0-mac-amd64-signed.zip");
|
InputStream inputStream = Hwi.class.getResourceAsStream("/external/" + platform.getPlatformId().toLowerCase() + "/hwi-1.1.0-mac-amd64-signed.zip");
|
||||||
Path tempHwiDirPath = Files.createTempDirectory("hwi", PosixFilePermissions.asFileAttribute(ownerExecutableWritable));
|
Path tempHwiDirPath = Files.createTempDirectory("hwi", PosixFilePermissions.asFileAttribute(ownerExecutableWritable));
|
||||||
File tempHwiDir = tempHwiDirPath.toFile();
|
File tempHwiDir = tempHwiDirPath.toFile();
|
||||||
tempHwiDir.deleteOnExit();
|
//tempHwiDir.deleteOnExit();
|
||||||
|
//System.out.println(tempHwiDir.getAbsolutePath());
|
||||||
System.out.println(tempHwiDir.getAbsolutePath());
|
|
||||||
|
|
||||||
File tempExec = null;
|
File tempExec = null;
|
||||||
ZipInputStream zis = new ZipInputStream(inputStream);
|
ZipInputStream zis = new ZipInputStream(inputStream);
|
||||||
ZipEntry zipEntry = zis.getNextEntry();
|
ZipEntry zipEntry = zis.getNextEntry();
|
||||||
while (zipEntry != null) {
|
while (zipEntry != null) {
|
||||||
File newFile = newFile(tempHwiDir, zipEntry, ownerExecutableWritable);
|
File newFile = newFile(tempHwiDir, zipEntry, ownerExecutableWritable);
|
||||||
newFile.deleteOnExit();
|
//newFile.deleteOnExit();
|
||||||
FileOutputStream fos = new FileOutputStream(newFile);
|
FileOutputStream fos = new FileOutputStream(newFile);
|
||||||
ByteStreams.copy(zis, new FileOutputStream(newFile));
|
ByteStreams.copy(zis, new FileOutputStream(newFile));
|
||||||
fos.flush();
|
fos.flush();
|
||||||
|
@ -129,7 +128,7 @@ public class Hwi {
|
||||||
InputStream inputStream = Hwi.class.getResourceAsStream("/external/" + platform.getPlatformId().toLowerCase() + "/hwi");
|
InputStream inputStream = Hwi.class.getResourceAsStream("/external/" + platform.getPlatformId().toLowerCase() + "/hwi");
|
||||||
Path tempExecPath = Files.createTempFile("hwi", null, PosixFilePermissions.asFileAttribute(ownerExecutableWritable));
|
Path tempExecPath = Files.createTempFile("hwi", null, PosixFilePermissions.asFileAttribute(ownerExecutableWritable));
|
||||||
File tempExec = tempExecPath.toFile();
|
File tempExec = tempExecPath.toFile();
|
||||||
tempExec.deleteOnExit();
|
//tempExec.deleteOnExit();
|
||||||
OutputStream tempExecStream = new BufferedOutputStream(new FileOutputStream(tempExec));
|
OutputStream tempExecStream = new BufferedOutputStream(new FileOutputStream(tempExec));
|
||||||
ByteStreams.copy(new FramedLZ4CompressorInputStream(inputStream), tempExecStream);
|
ByteStreams.copy(new FramedLZ4CompressorInputStream(inputStream), tempExecStream);
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
|
@ -138,9 +137,11 @@ public class Hwi {
|
||||||
|
|
||||||
hwiExecutable = tempExec;
|
hwiExecutable = tempExec;
|
||||||
}
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
Config.get().setHwi(hwiExecutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hwiExecutable;
|
return hwiExecutable;
|
||||||
|
@ -199,6 +200,24 @@ public class Hwi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ScheduledEnumerateService extends ScheduledService<List<Device>> {
|
||||||
|
private final String passphrase;
|
||||||
|
|
||||||
|
public ScheduledEnumerateService(String passphrase) {
|
||||||
|
this.passphrase = passphrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Task<List<Device>> createTask() {
|
||||||
|
return new Task<>() {
|
||||||
|
protected List<Device> call() throws ImportException {
|
||||||
|
Hwi hwi = new Hwi();
|
||||||
|
return hwi.enumerate(passphrase);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class PromptPinService extends Service<Boolean> {
|
public static class PromptPinService extends Service<Boolean> {
|
||||||
private Device device;
|
private Device device;
|
||||||
|
|
||||||
|
|
|
@ -220,11 +220,11 @@ public class Storage {
|
||||||
return walletsDir;
|
return walletsDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File getSparrowDir() {
|
static File getSparrowDir() {
|
||||||
return new File(getHomeDir(), SPARROW_DIR);
|
return new File(getHomeDir(), SPARROW_DIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File getHomeDir() {
|
static File getHomeDir() {
|
||||||
return new File(System.getProperty("user.home"));
|
return new File(System.getProperty("user.home"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,3 +19,7 @@
|
||||||
.drag-over > .background-text {
|
.drag-over > .background-text {
|
||||||
-fx-fill: #383a42;
|
-fx-fill: #383a42;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-bar .right-items {
|
||||||
|
-fx-padding: 0 0 0 8;
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,6 @@
|
||||||
<TabPane fx:id="tabs" />
|
<TabPane fx:id="tabs" />
|
||||||
</StackPane>
|
</StackPane>
|
||||||
|
|
||||||
<StatusBar fx:id="statusBar" text=""/>
|
<StatusBar fx:id="statusBar" text="" minHeight="36"/>
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<ToggleGroup fx:id="walletMenu" />
|
<ToggleGroup fx:id="walletMenu" />
|
||||||
</toggleGroup>
|
</toggleGroup>
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="BTC" />
|
<Glyph fontFamily="FontAwesome" icon="BTC" fontSize="20" />
|
||||||
</graphic>
|
</graphic>
|
||||||
<userData>
|
<userData>
|
||||||
<Function fx:constant="TRANSACTIONS"/>
|
<Function fx:constant="TRANSACTIONS"/>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton VBox.vgrow="ALWAYS" text="Send" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
<ToggleButton VBox.vgrow="ALWAYS" text="Send" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="SEND" />
|
<Glyph fontFamily="FontAwesome" icon="SEND" fontSize="20" />
|
||||||
</graphic>
|
</graphic>
|
||||||
<userData>
|
<userData>
|
||||||
<Function fx:constant="SEND"/>
|
<Function fx:constant="SEND"/>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton VBox.vgrow="ALWAYS" text="Receive" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
<ToggleButton VBox.vgrow="ALWAYS" text="Receive" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="ARROW_DOWN" />
|
<Glyph fontFamily="FontAwesome" icon="ARROW_DOWN" fontSize="20" />
|
||||||
</graphic>
|
</graphic>
|
||||||
<userData>
|
<userData>
|
||||||
<Function fx:constant="RECEIVE"/>
|
<Function fx:constant="RECEIVE"/>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton VBox.vgrow="ALWAYS" text="Addresses" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
<ToggleButton VBox.vgrow="ALWAYS" text="Addresses" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="TH_LIST" />
|
<Glyph fontFamily="FontAwesome" icon="TH_LIST" fontSize="20" />
|
||||||
</graphic>
|
</graphic>
|
||||||
<userData>
|
<userData>
|
||||||
<Function fx:constant="ADDRESSES"/>
|
<Function fx:constant="ADDRESSES"/>
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton VBox.vgrow="ALWAYS" text="Policies" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
<ToggleButton VBox.vgrow="ALWAYS" text="Policies" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="FILE_TEXT" />
|
<Glyph fontFamily="FontAwesome" icon="FILE_TEXT" fontSize="20" />
|
||||||
</graphic>
|
</graphic>
|
||||||
<userData>
|
<userData>
|
||||||
<Function fx:constant="POLICIES"/>
|
<Function fx:constant="POLICIES"/>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton VBox.vgrow="ALWAYS" text="Settings" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
<ToggleButton VBox.vgrow="ALWAYS" text="Settings" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$walletMenu">
|
||||||
<graphic>
|
<graphic>
|
||||||
<Glyph fontFamily="FontAwesome" icon="COG" />
|
<Glyph fontFamily="FontAwesome" icon="COG" fontSize="20" />
|
||||||
</graphic>
|
</graphic>
|
||||||
<userData>
|
<userData>
|
||||||
<Function fx:constant="SETTINGS"/>
|
<Function fx:constant="SETTINGS"/>
|
||||||
|
|
Loading…
Reference in a new issue