Revert "Track dist"
This reverts commit 3299e3e77e352106842f631db8ca51e86a084468
|
|
@ -1,3 +0,0 @@
|
|||
NODE_ENV=production
|
||||
VUE_APP_PLATFORM=web
|
||||
VUE_APP_TARGET=electron-renderer
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
|
||||
# Cache modules in between jobs
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- node_modules/
|
||||
|
||||
|
||||
# Electron app build
|
||||
build:
|
||||
stage: build
|
||||
image: electronuserland/builder:wine
|
||||
|
||||
script:
|
||||
# Install node dependencies
|
||||
- npm install
|
||||
# Create build directory
|
||||
- mkdir -p "release-builds"
|
||||
# Build electron app
|
||||
- npm run build:app
|
||||
- npm run release
|
||||
|
||||
artifacts:
|
||||
name: "dist"
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- "./release-builds/*.AppImage"
|
||||
- "./release-builds/*.exe"
|
||||
- "./release-builds/*.exe.blockmap"
|
||||
- "./release-builds/latest*.yml"
|
||||
- "./release-builds/beta*.yml"
|
||||
|
||||
only:
|
||||
- merge_requests
|
||||
- master
|
||||
- web
|
||||
- tags
|
||||
|
||||
|
||||
# Deploy to builds.openflexure.org
|
||||
deploy:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- build
|
||||
image: ubuntu:latest
|
||||
|
||||
before_script:
|
||||
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
|
||||
- eval $(ssh-agent -s)
|
||||
- ssh-add <(echo "$SSH_PRIVATE_KEY_BATH_OPENFLEXURE_BASE64" | base64 --decode)
|
||||
- mkdir -p ~/.ssh
|
||||
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
|
||||
|
||||
script:
|
||||
# Install rsync if not already installed
|
||||
- 'which rsync || ( apt-get update -y && apt-get install rsync -y )'
|
||||
|
||||
# Upload the builds folder to openflexure-microscope builds
|
||||
- rsync -hrvz -e ssh release-builds/ ci-user@openflexure.bath.ac.uk:/var/www/build/openflexure-ev/
|
||||
|
||||
# Run update-latest.py on the build server
|
||||
- ssh -t ci-user@openflexure.bath.ac.uk "/var/www/build/update-latest.py"
|
||||
|
||||
only:
|
||||
- tags
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
const electron = require("electron");
|
||||
const contextMenu = require("electron-context-menu");
|
||||
const path = require("path");
|
||||
|
||||
const app = electron.app;
|
||||
const BrowserWindow = electron.BrowserWindow;
|
||||
|
||||
let url = "http://localhost:8080/";
|
||||
|
||||
// Set the application menu
|
||||
require("./menu.js");
|
||||
|
||||
app.on("ready", () => {
|
||||
let window = new BrowserWindow({
|
||||
width: 1124,
|
||||
height: 800,
|
||||
icon: path.join(__dirname, "/icons/png/64x64.png")
|
||||
});
|
||||
|
||||
contextMenu({
|
||||
showCopyImageAddress: true,
|
||||
showSaveImageAs: true,
|
||||
showInspectElement: true
|
||||
});
|
||||
|
||||
window.loadURL(url);
|
||||
});
|
||||
197
app/app.js
|
|
@ -1,197 +0,0 @@
|
|||
// Required packages
|
||||
const electron = require("electron");
|
||||
const { dialog } = require("electron");
|
||||
const updater = require("electron-updater");
|
||||
const autoUpdater = updater.autoUpdater;
|
||||
const contextMenu = require("electron-context-menu");
|
||||
const ProgressBar = require("electron-progressbar");
|
||||
const path = require("path");
|
||||
|
||||
// Attach settings store
|
||||
const { store } = require("./store");
|
||||
|
||||
// Auto upadater
|
||||
autoUpdater.autoDownload = false;
|
||||
|
||||
autoUpdater.on("checking-for-update", function() {});
|
||||
|
||||
autoUpdater.on("update-available", function(info) {
|
||||
sendStatusToWindow("Update available." + info);
|
||||
dialog.showMessageBox(
|
||||
mainWindow,
|
||||
{
|
||||
type: "info",
|
||||
title: "Update available",
|
||||
message: "A new version of OpenFlexure eV is available.",
|
||||
buttons: ["Download", "Later"]
|
||||
},
|
||||
buttonIndex => {
|
||||
if (buttonIndex === 0) {
|
||||
console.log("Downloading update selected");
|
||||
handleDownloadUpdate();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Download, with a progress bar
|
||||
function handleDownloadUpdate() {
|
||||
console.log("Downloading update");
|
||||
var progressBar = new ProgressBar({
|
||||
indeterminate: false,
|
||||
text: "Downloading update...",
|
||||
detail: "Please wait...",
|
||||
browserWindow: {
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
progressBar.on("ready", function() {
|
||||
autoUpdater.on("download-progress", function(info) {
|
||||
progressBar.value = info.percent;
|
||||
progressBar.detail = `${Math.floor(info.percent)}% ${info.bytesPerSecond /
|
||||
1000}kb/s`;
|
||||
});
|
||||
autoUpdater.on("update-downloaded", function() {
|
||||
progressBar.close();
|
||||
});
|
||||
autoUpdater.on("error", function() {
|
||||
progressBar.close();
|
||||
});
|
||||
autoUpdater.downloadUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger update installation
|
||||
autoUpdater.on("update-downloaded", function(info) {
|
||||
sendStatusToWindow("Update downloaded." + info);
|
||||
dialog.showMessageBox(
|
||||
mainWindow,
|
||||
{
|
||||
type: "info",
|
||||
title: "Update downloaded",
|
||||
message: "Please restart the application to apply the update.",
|
||||
buttons: ["Update", "Later"]
|
||||
},
|
||||
buttonIndex => {
|
||||
if (buttonIndex === 0) {
|
||||
autoUpdater.quitAndInstall();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
autoUpdater.on("update-not-available", function() {
|
||||
sendStatusToWindow("Update not available.");
|
||||
});
|
||||
|
||||
autoUpdater.on("error", function() {
|
||||
sendStatusToWindow("Error in auto-updater.");
|
||||
});
|
||||
|
||||
autoUpdater.on("download-progress", function(progressObj) {
|
||||
let log_message = "Download speed: " + progressObj.bytesPerSecond;
|
||||
log_message =
|
||||
log_message + " - Downloaded " + parseInt(progressObj.percent) + "%";
|
||||
log_message =
|
||||
log_message +
|
||||
" (" +
|
||||
progressObj.transferred +
|
||||
"/" +
|
||||
progressObj.total +
|
||||
")";
|
||||
sendStatusToWindow(log_message);
|
||||
});
|
||||
|
||||
function sendStatusToWindow(message) {
|
||||
console.log(message);
|
||||
}
|
||||
|
||||
// Set up the app
|
||||
const app = electron.app;
|
||||
const BrowserWindow = electron.BrowserWindow;
|
||||
|
||||
// Set the window content
|
||||
let url = `file://${path.join(__dirname, "/dist/index.html")}`;
|
||||
let mainWindow;
|
||||
|
||||
// Set the application menu
|
||||
require("./menu.js");
|
||||
|
||||
// Handle redrawing the mainWindow
|
||||
let recreatingWindowInProgress = false;
|
||||
|
||||
function toggleCustomTitleBar() {
|
||||
// Mark window as being recreated, to prevent stopping the application
|
||||
recreatingWindowInProgress = true;
|
||||
|
||||
// Invert the drawCustomTitleBar setting
|
||||
store.set("drawCustomTitleBar", !store.get("drawCustomTitleBar"));
|
||||
|
||||
// Destroy old window
|
||||
mainWindow.destroy();
|
||||
// Create new window
|
||||
createWindow();
|
||||
|
||||
// Mark window as no longer being recreated
|
||||
recreatingWindowInProgress = false;
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
frame: !store.get("drawCustomTitleBar"),
|
||||
width: 1200,
|
||||
height: 900,
|
||||
icon: path.join(__dirname, "/icons/png/64x64.png"),
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
});
|
||||
|
||||
// Make a context menu
|
||||
contextMenu({
|
||||
showCopyImageAddress: true,
|
||||
showSaveImageAs: true,
|
||||
showInspectElement: false
|
||||
});
|
||||
|
||||
// Load window contents
|
||||
mainWindow.loadURL(url);
|
||||
|
||||
// Check for updates
|
||||
autoUpdater.checkForUpdates();
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on("closed", function() {
|
||||
mainWindow = null; // Dereference the window object
|
||||
});
|
||||
|
||||
mainWindow.webContents.on("new-window", function(event, url) {
|
||||
event.preventDefault();
|
||||
electron.shell.openExternal(url);
|
||||
});
|
||||
}
|
||||
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on("ready", () => {
|
||||
createWindow();
|
||||
});
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on("window-all-closed", function() {
|
||||
if (process.platform !== "darwin" && recreatingWindowInProgress != true) {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on("activate", function() {
|
||||
if (mainWindow === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// Export toggleCustomTitleBar for use in ./menu.js
|
||||
module.exports.toggleCustomTitleBar = toggleCustomTitleBar;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
extends: app/builder-config-base.yaml
|
||||
win:
|
||||
target:
|
||||
- appx
|
||||
icon: app/icons/win/icon.ico
|
||||
appx:
|
||||
applicationId: OpenFlexureEV
|
||||
identityName: 60425J.T.Collins.OpenFlexureeV
|
||||
publisher: CN=CC867BEF-0715-4D48-8035-8881993DBB68
|
||||
publisherDisplayName: J. T. Collins
|
||||
backgroundColor: '#C5247F'
|
||||
electronVersion: 4.1.5
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
directories:
|
||||
output: release-builds
|
||||
buildResources: app/resources
|
||||
appId: org.openflexure.ev
|
||||
artifactName: ${name}-${version}-${os}-${arch}.${ext}
|
||||
asar: true
|
||||
publish:
|
||||
- provider: generic
|
||||
url: https://build.openflexure.org/openflexure-ev/
|
||||
files:
|
||||
- filter:
|
||||
- '**/*'
|
||||
- '!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}'
|
||||
- '!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}'
|
||||
- '!**/node_modules/*.d.ts'
|
||||
- '!**/node_modules/.bin'
|
||||
- '!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}'
|
||||
- '!.editorconfig'
|
||||
- '!**/._*'
|
||||
- '!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}'
|
||||
- '!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}'
|
||||
- '!**/{appveyor.yml,.travis.yml,circle.yml}'
|
||||
- '!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json}'
|
||||
- '!**/.env.*'
|
||||
- '!**/{.idea,.vscode}${/*}'
|
||||
- '!**/app/installers${/*}'
|
||||
- '!**/hooks${/*}'
|
||||
- '!**/platforms${/*}'
|
||||
- '!**/release-builds${/*}'
|
||||
- '!src${/*}'
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
extends: app/builder-config-base.yaml
|
||||
linux:
|
||||
target:
|
||||
- target: deb
|
||||
arch:
|
||||
- armv7l
|
||||
- target: appImage
|
||||
arch:
|
||||
- armv7l
|
||||
icon: app/icons/png/
|
||||
category: Science
|
||||
deb:
|
||||
fpm: ['--architecture', 'armhf']
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
extends: app/builder-config-base.yaml
|
||||
win:
|
||||
target:
|
||||
- NSIS
|
||||
icon: app/icons/win/icon.ico
|
||||
linux:
|
||||
target:
|
||||
- target: deb
|
||||
arch:
|
||||
- x64
|
||||
- target: appImage
|
||||
arch:
|
||||
- x64
|
||||
icon: app/icons/png/
|
||||
category: Science
|
||||
mac:
|
||||
icon: app/icons/mac/icon.icns
|
||||
category: public.app-category.utilities
|
||||
dmg:
|
||||
contents:
|
||||
- x: 110
|
||||
y: 150
|
||||
- x: 240
|
||||
y: 150
|
||||
type: link
|
||||
path: /Applications
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
provider: generic
|
||||
url: https://build.openflexure.org/openflexure-ev/
|
||||
channel: latest
|
||||
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 885 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 733 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 353 KiB |
|
|
@ -1,103 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
packageName='openflexure-ev'
|
||||
|
||||
scriptPath=$(dirname "$0")
|
||||
packagePath="$(dirname "$scriptPath")"
|
||||
packageJson="$packagePath/package.json"
|
||||
|
||||
installerPath="$packagePath/openflexure-ev-win.exe"
|
||||
installerHash=`sha256sum ${installerPath} | awk '{ print $1 }'`
|
||||
echo "$installerHash"
|
||||
|
||||
outpath="$packagePath/release-builds/choco"
|
||||
toolspath="$outpath/tools"
|
||||
mkdir -p "$toolspath"
|
||||
|
||||
echo "$scriptPath"
|
||||
echo "$packageJson"
|
||||
echo "$outpath"
|
||||
|
||||
# Get package version from package.json
|
||||
packageVersion=$(grep version < "$packageJson" | head -1 \
|
||||
| awk -F: '{ print $2 }' \
|
||||
| sed 's/[",]//g' \
|
||||
| tr -d ':space:')
|
||||
|
||||
echo "Package version: $packageVersion"
|
||||
|
||||
# Convert into a nupkg-safe version string
|
||||
majVer="$(echo "$packageVersion" | cut -d'-' -f1)"
|
||||
minVer="$(echo "$packageVersion" | cut -d'-' -f2)"
|
||||
|
||||
if [ "$majVer" = "$minVer" ]; then
|
||||
version="$majVer"
|
||||
else
|
||||
minVer="${minVer//.}"
|
||||
version="$majVer-$minVer"
|
||||
fi
|
||||
|
||||
echo "Nupkg version: $version"
|
||||
|
||||
# Build installer URL
|
||||
pipelineURL="$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_REF_NAME/raw"
|
||||
instURL="$pipelineURL/openflexure-ev-win.exe?job=package"
|
||||
nuspecURL="$CI_JOB_URL/artifacts/browse"
|
||||
|
||||
echo "$instURL"
|
||||
|
||||
# Build nuspec
|
||||
cat > "$outpath/openflexure-ev.nuspec" <<- EOL
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<metadata>
|
||||
<id>$packageName</id>
|
||||
<title>OpenFlexure eV</title>
|
||||
<version>$version</version>
|
||||
<authors>OpenFlexure</authors>
|
||||
<owners>Joel Collins</owners>
|
||||
<summary>OpenFlexure Microscope client</summary>
|
||||
<description>An electron-based user client for the OpenFlexure Microscope Server</description>
|
||||
|
||||
<projectUrl>https://www.openflexure.org/</projectUrl>
|
||||
<docsUrl>https://www.openflexure.org/projects/microscope/</docsUrl>
|
||||
<bugTrackerUrl>https://gitlab.com/openflexure/openflexure-microscope-jsclient/issues</bugTrackerUrl>
|
||||
|
||||
<projectSourceUrl>https://gitlab.com/openflexure/openflexure-microscope-jsclient/</projectSourceUrl>
|
||||
<packageSourceUrl>$nuspecURL</packageSourceUrl>
|
||||
|
||||
<tags>openflexure microscope ev</tags>
|
||||
<licenseUrl>https://gitlab.com/openflexure/openflexure-microscope-jsclient/raw/master/LICENSE</licenseUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<iconUrl>https://glcdn.githack.com/openflexure/openflexure-microscope-jsclient/raw/v1.1.0/app/icons/png/512x512.png</iconUrl>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="tools/**" target="tools" />
|
||||
</files>
|
||||
</package>
|
||||
EOL
|
||||
|
||||
# Build installer PS1 content
|
||||
cat > "$toolspath/chocolateyInstall.ps1" <<- EOL
|
||||
\$ErrorActionPreference = "Stop";
|
||||
\$toolsDir = "\$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||
\$url = "$instURL"
|
||||
|
||||
\$packageArgs = @{
|
||||
packageName = "openflexure-ev"
|
||||
unzipLocation = \$toolsDir
|
||||
fileType = "exe"
|
||||
url = \$url
|
||||
url64bit = \$url
|
||||
|
||||
softwareName = "OpenFlexure eV"
|
||||
|
||||
checksum = "${installerHash}"
|
||||
checksumType = "sha256"
|
||||
|
||||
silentArgs = "/S"
|
||||
}
|
||||
|
||||
Install-ChocolateyPackage @packageArgs
|
||||
|
||||
EOL
|
||||
122
app/menu.js
|
|
@ -1,122 +0,0 @@
|
|||
const { app, shell, Menu } = require("electron");
|
||||
const updater = require("electron-updater");
|
||||
const autoUpdater = updater.autoUpdater;
|
||||
const path = require("path");
|
||||
|
||||
const openAboutWindow = require("about-window").default;
|
||||
|
||||
const main = require("./app");
|
||||
const { store } = require("./store");
|
||||
|
||||
const template = [
|
||||
{
|
||||
label: "Edit",
|
||||
submenu: [
|
||||
{ role: "undo" },
|
||||
{ role: "redo" },
|
||||
{ type: "separator" },
|
||||
{ role: "cut" },
|
||||
{ role: "copy" },
|
||||
{ role: "paste" },
|
||||
{ role: "delete" },
|
||||
{ role: "selectall" }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "View",
|
||||
submenu: [
|
||||
{ role: "reload" },
|
||||
{ role: "forcereload" },
|
||||
{ role: "toggledevtools" },
|
||||
{ type: "separator" },
|
||||
{ role: "togglefullscreen" },
|
||||
{ type: "separator" },
|
||||
{
|
||||
type: "checkbox",
|
||||
checked: store.get("drawCustomTitleBar"),
|
||||
label: "Custom titlebar",
|
||||
click() {
|
||||
main.toggleCustomTitleBar();
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: "window",
|
||||
submenu: [{ role: "minimize" }, { role: "close" }]
|
||||
},
|
||||
{
|
||||
role: "help",
|
||||
submenu: [
|
||||
{
|
||||
label: "About",
|
||||
click() {
|
||||
openAboutWindow({
|
||||
package_json_dir: path.join(__dirname, ".."),
|
||||
icon_path: path.join(__dirname, "/icons/png/512x512.png"),
|
||||
bug_report_url:
|
||||
"https://gitlab.com/openflexure/openflexure-microscope-jsclient/issues",
|
||||
homepage:
|
||||
"https://gitlab.com/openflexure/openflexure-microscope-jsclient"
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Homepage",
|
||||
click() {
|
||||
shell.openExternal("https://openflexure.org");
|
||||
}
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "Check for Updates",
|
||||
click() {
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
template.unshift({
|
||||
label: app.getName(),
|
||||
submenu: [
|
||||
{ role: "about" },
|
||||
{ type: "separator" },
|
||||
{ role: "services" },
|
||||
{ type: "separator" },
|
||||
{ role: "hide" },
|
||||
{ role: "hideothers" },
|
||||
{ role: "unhide" },
|
||||
{ type: "separator" },
|
||||
{ role: "quit" }
|
||||
]
|
||||
});
|
||||
|
||||
// Edit menu
|
||||
template[1].submenu.push(
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "Speech",
|
||||
submenu: [{ role: "startspeaking" }, { role: "stopspeaking" }]
|
||||
}
|
||||
);
|
||||
|
||||
// Window menu
|
||||
template[3].submenu = [
|
||||
{ role: "close" },
|
||||
{ role: "minimize" },
|
||||
{ role: "zoom" },
|
||||
{ type: "separator" },
|
||||
{ role: "front" }
|
||||
];
|
||||
} else {
|
||||
template.unshift({
|
||||
label: "File",
|
||||
submenu: [{ role: "quit" }]
|
||||
});
|
||||
}
|
||||
|
||||
const menu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(menu);
|
||||
|
Before Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
|
|
@ -1,9 +0,0 @@
|
|||
const Store = require("electron-store");
|
||||
const store = new Store();
|
||||
|
||||
if (store.has("drawCustomTitleBar") !== true) {
|
||||
// Default to false if on MacOS, otherwise true
|
||||
store.set("drawCustomTitleBar", process.platform === "win32" ? true : false);
|
||||
}
|
||||
|
||||
module.exports.store = store;
|
||||
3641
package-lock.json
generated
28
package.json
|
|
@ -2,34 +2,18 @@
|
|||
"name": "openflexure-ev",
|
||||
"version": "2.1.2",
|
||||
"private": true,
|
||||
"description": "An electron-based user client for the OpenFlexure Microscope Server",
|
||||
"description": "User client for the OpenFlexure Microscope Server",
|
||||
"author": "OpenFlexure <contact@openflexure.org> (https://www.openflexure.org)",
|
||||
"homepage": "https://gitlab.com/openflexure/openflexure-microscope-jsclient",
|
||||
"productName": "OpenFlexure eV",
|
||||
"publisher": "Bath Open Instrumentation Group",
|
||||
"displayName": "OpenFlexure eV",
|
||||
"license": "GNU General Public License v3.0 ",
|
||||
"main": "./app/app.js",
|
||||
"scripts": {
|
||||
"build:web": "vue-cli-service build --mode production.web",
|
||||
"build:app": "vue-cli-service build --mode production.app",
|
||||
"serve:web": "vue-cli-service serve --mode development.web",
|
||||
"start": "npm run build:app && electron app/app.js",
|
||||
"dist:linux": "electron-builder --linux --config app/builder-config-x86_64.yaml",
|
||||
"dist:raspi": "electron-builder --linux --config app/builder-config-raspi.yaml",
|
||||
"dist:win": "electron-builder --win --config app/builder-config-x86_64.yaml",
|
||||
"dist:dmg": "electron-builder --mac --config app/builder-config-x86_64.yaml",
|
||||
"dist:appx": "electron-builder --win --config app/builder-config-appx.yaml",
|
||||
"release": "electron-builder --linux --config app/builder-config-raspi.yaml & electron-builder --win --linux --config app/builder-config-x86_64.yaml",
|
||||
"make-icons": "electron-icon-builder --input=./app/icons/icon_base.png --output=./app/"
|
||||
"build": "vue-cli-service build --mode production",
|
||||
"serve": "vue-cli-service serve --mode development"
|
||||
},
|
||||
"dependencies": {
|
||||
"about-window": "^1.13.2",
|
||||
"custom-electron-titlebar": "^3.2.2",
|
||||
"electron-context-menu": "^0.15.2",
|
||||
"electron-progressbar": "^1.2.0",
|
||||
"electron-store": "^5.1.1",
|
||||
"electron-updater": "^4.3.1",
|
||||
"material-design-icons": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -38,9 +22,6 @@
|
|||
"axios": "^0.19.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"css-loader": "^3.5.3",
|
||||
"electron": "^6.1.12",
|
||||
"electron-builder": "^21.2.0",
|
||||
"electron-icon-builder": "^1.0.2",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
|
|
@ -56,9 +37,6 @@
|
|||
"vue-tour": "^1.3.1",
|
||||
"vuex": "^3.4.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"electron-windows-store": "^2.1.0"
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
|
|
|
|||
74
src/App.vue
|
|
@ -4,9 +4,11 @@
|
|||
class="uk-height-1-1 uk-margin-remove uk-padding-remove"
|
||||
:class="handleTheme"
|
||||
>
|
||||
<div id="tour-header"></div>
|
||||
<appContent />
|
||||
<loadingContent v-if="!$store.getters.ready" />
|
||||
<div v-if="$store.getters.ready" id="tour-header"></div>
|
||||
<appContent v-if="$store.getters.ready" />
|
||||
<v-tour
|
||||
v-if="$store.getters.ready"
|
||||
name="guidedTour"
|
||||
:steps="tourSteps"
|
||||
:callbacks="tourCallbacks"
|
||||
|
|
@ -16,9 +18,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import isElectron from "./modules/isElectron";
|
||||
// Import components
|
||||
import appContent from "./components/appContent.vue";
|
||||
import loadingContent from "./components/loadingContent.vue";
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
// Key Codes
|
||||
const keyCodes = {
|
||||
|
|
@ -40,15 +44,16 @@ export default {
|
|||
name: "App",
|
||||
|
||||
components: {
|
||||
appContent
|
||||
appContent,
|
||||
loadingContent
|
||||
},
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
appAvailable: false,
|
||||
keysDown: {},
|
||||
systemDark: undefined,
|
||||
themeObserver: undefined,
|
||||
isElectron: isElectron(),
|
||||
tourCallbacks: {
|
||||
onStop: () => {
|
||||
this.setLocalStorageObj("completedTour", true);
|
||||
|
|
@ -94,33 +99,6 @@ export default {
|
|||
placement: "bottom"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
target: "#new-connection-card",
|
||||
header: {
|
||||
title: "New connection"
|
||||
},
|
||||
content: `Connect locally if you're running on a microscope, \nor open a new remote connection to a microscope`
|
||||
},
|
||||
...(this.isElectron
|
||||
? [
|
||||
{
|
||||
target: "#nearby-connections-grid",
|
||||
header: {
|
||||
title: "Nearby microscopes"
|
||||
},
|
||||
content: `Connect to microscopes found on your network`
|
||||
}
|
||||
]
|
||||
: []),
|
||||
|
||||
{
|
||||
target: "#saved-connections-grid",
|
||||
header: {
|
||||
title: "Saved microscopes"
|
||||
},
|
||||
content: `Connect to your saved microscopes for faster access`
|
||||
},
|
||||
{
|
||||
target: "#gallery-tab-icon",
|
||||
header: {
|
||||
|
|
@ -175,8 +153,11 @@ export default {
|
|||
this.systemDark = false;
|
||||
}
|
||||
});
|
||||
// Check connection to API
|
||||
this.checkConnection();
|
||||
// Handle guided tour
|
||||
// If the user has already completed or skipped the guided tour
|
||||
// TODO: Only run this if connected to the API
|
||||
var completedTour = this.getLocalStorageObj("completedTour") || false;
|
||||
if (!completedTour) {
|
||||
this.$tours["guidedTour"].start();
|
||||
|
|
@ -189,6 +170,16 @@ export default {
|
|||
window.addEventListener("keydown", this.keyDownMonitor);
|
||||
window.addEventListener("keyup", this.keyUpMonitor);
|
||||
window.addEventListener("wheel", this.wheelMonitor);
|
||||
// Watch for origin changes
|
||||
this.unwatchOriginFunction = this.$store.watch(
|
||||
(state, getters) => {
|
||||
return getters.uriV2;
|
||||
},
|
||||
uriV2 => {
|
||||
this.checkConnection();
|
||||
console.log(uriV2);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
beforeDestroy: function() {
|
||||
|
|
@ -200,9 +191,28 @@ export default {
|
|||
window.removeEventListener("keydown", this.keyDownMonitor);
|
||||
window.removeEventListener("keyup", this.keyUpMonitor);
|
||||
window.removeEventListener("wheel", this.wheelMonitor);
|
||||
// Remove origin watcher
|
||||
this.unwatchOriginFunction();
|
||||
},
|
||||
|
||||
methods: {
|
||||
checkConnection: function() {
|
||||
var uriV2 = this.$store.getters.uriV2;
|
||||
this.$store.commit("changeWaiting", true);
|
||||
axios
|
||||
.get(uriV2)
|
||||
.then(() => {
|
||||
this.$store.commit("setConnected");
|
||||
this.$store.commit("setErrorMessage", null);
|
||||
})
|
||||
.catch(error => {
|
||||
this.$store.commit("setErrorMessage", error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.$store.commit("changeWaiting", false);
|
||||
});
|
||||
},
|
||||
|
||||
handleExit: function() {
|
||||
console.log("Triggered beforeunload");
|
||||
this.$root.$emit("globalTogglePreview", false);
|
||||
|
|
|
|||
|
|
@ -16,14 +16,15 @@
|
|||
class="uk-flex uk-flex-column uk-padding-remove uk-width-auto uk-height-1-1 uk-text-center"
|
||||
>
|
||||
<tabIcon
|
||||
id="connect-tab-icon"
|
||||
tab-i-d="connect"
|
||||
:require-connection="false"
|
||||
id="view-tab-icon"
|
||||
tab-i-d="view"
|
||||
:require-connection="true"
|
||||
:current-tab="currentTab"
|
||||
@set-tab="setTab"
|
||||
>
|
||||
<i class="material-icons">bug_report</i>
|
||||
<i class="material-icons">visibility</i>
|
||||
</tabIcon>
|
||||
|
||||
<tabIcon
|
||||
id="gallery-tab-icon"
|
||||
tab-i-d="gallery"
|
||||
|
|
@ -36,15 +37,6 @@
|
|||
|
||||
<hr />
|
||||
|
||||
<tabIcon
|
||||
id="view-tab-icon"
|
||||
tab-i-d="view"
|
||||
:require-connection="true"
|
||||
:current-tab="currentTab"
|
||||
@set-tab="setTab"
|
||||
>
|
||||
<i class="material-icons">visibility</i>
|
||||
</tabIcon>
|
||||
<tabIcon
|
||||
id="navigate-tab-icon"
|
||||
tab-i-d="navigate"
|
||||
|
|
@ -95,11 +87,11 @@
|
|||
class="uk-padding-remove uk-height-1-1 uk-width-expand"
|
||||
>
|
||||
<tabContent
|
||||
tab-i-d="connect"
|
||||
:require-connection="false"
|
||||
tab-i-d="view"
|
||||
:require-connection="true"
|
||||
:current-tab="currentTab"
|
||||
>
|
||||
<connectContent />
|
||||
<viewContent />
|
||||
</tabContent>
|
||||
<tabContent
|
||||
tab-i-d="gallery"
|
||||
|
|
@ -108,13 +100,6 @@
|
|||
>
|
||||
<galleryContent />
|
||||
</tabContent>
|
||||
<tabContent
|
||||
tab-i-d="view"
|
||||
:require-connection="true"
|
||||
:current-tab="currentTab"
|
||||
>
|
||||
<viewContent />
|
||||
</tabContent>
|
||||
<tabContent
|
||||
tab-i-d="navigate"
|
||||
:require-connection="true"
|
||||
|
|
@ -164,7 +149,6 @@ import tabIcon from "./genericComponents/tabIcon";
|
|||
import tabContent from "./genericComponents/tabContent";
|
||||
|
||||
// Import new content components
|
||||
import connectContent from "./tabContentComponents/connectContent.vue";
|
||||
import navigateContent from "./tabContentComponents/navigateContent.vue";
|
||||
import captureContent from "./tabContentComponents/captureContent.vue";
|
||||
import viewContent from "./tabContentComponents/viewContent.vue";
|
||||
|
|
@ -182,7 +166,6 @@ export default {
|
|||
components: {
|
||||
tabIcon,
|
||||
tabContent,
|
||||
connectContent,
|
||||
navigateContent,
|
||||
captureContent,
|
||||
viewContent,
|
||||
|
|
@ -195,7 +178,7 @@ export default {
|
|||
data: function() {
|
||||
return {
|
||||
plugins: [],
|
||||
currentTab: "connect",
|
||||
currentTab: "view",
|
||||
unwatchStoreFunction: null
|
||||
};
|
||||
},
|
||||
|
|
|
|||
33
src/components/loadingContent.vue
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<template>
|
||||
<div class="uk-flex uk-flex-column uk-flex-center uk-height-1-1">
|
||||
<div
|
||||
v-if="$store.state.waiting"
|
||||
class="uk-align-center"
|
||||
uk-spinner="ratio: 3"
|
||||
></div>
|
||||
<div v-if="$store.state.waiting" class="uk-align-center">Loading...</div>
|
||||
<i class="material-icons uk-align-center error-icon">error_outline</i>
|
||||
<div v-if="$store.state.error" class="uk-align-center">
|
||||
{{ $store.state.error }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Export main app
|
||||
export default {
|
||||
name: "LoadingContent",
|
||||
|
||||
components: {},
|
||||
|
||||
data: function() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.error-icon {
|
||||
font-size: 120px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<template>
|
||||
<!-- Grid managing tab content -->
|
||||
<div uk-grid class="uk-height-1-1 uk-margin-remove uk-padding-remove">
|
||||
<div class="view-component uk-width-expand">
|
||||
<connectDisplay />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import connectDisplay from "../viewComponents/connectDisplay.vue";
|
||||
|
||||
export default {
|
||||
name: "ConnectContent",
|
||||
|
||||
components: {
|
||||
connectDisplay
|
||||
},
|
||||
|
||||
data: function() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,410 +0,0 @@
|
|||
<template>
|
||||
<div class="connectDisplay uk-padding uk-padding-remove-left">
|
||||
<div
|
||||
uk-grid
|
||||
class="uk-height-1-1 uk-margin-remove uk-padding-remove uk-flex-column"
|
||||
margin="0"
|
||||
>
|
||||
<div class="uk-width-auto">
|
||||
<div
|
||||
id="new-connection-card"
|
||||
class="uk-card uk-card-default uk-padding-remove uk-width-medium connect-card-align-top"
|
||||
>
|
||||
<div class="uk-card-body uk-padding-small">
|
||||
<form id="formConnectToHost" @submit.prevent="handleSubmit">
|
||||
<div class="uk-form-controls uk-margin">
|
||||
<label
|
||||
><input
|
||||
v-model="computedLocalMode"
|
||||
class="uk-radio"
|
||||
type="radio"
|
||||
name="radio_local"
|
||||
:value="true"
|
||||
/>
|
||||
Connect locally</label
|
||||
><br />
|
||||
<label
|
||||
><input
|
||||
v-model="computedLocalMode"
|
||||
class="uk-radio"
|
||||
type="radio"
|
||||
name="radio_local"
|
||||
:value="false"
|
||||
checked
|
||||
/>
|
||||
Connect remotely</label
|
||||
>
|
||||
</div>
|
||||
<div v-if="!localMode">
|
||||
<div class="uk-inline uk-width-1-1">
|
||||
<span class="uk-form-icon"
|
||||
><i class="material-icons">dns</i></span
|
||||
>
|
||||
<input
|
||||
v-model="hostname"
|
||||
:class="IpFormClasses"
|
||||
class="uk-input uk-form-small"
|
||||
type="text"
|
||||
placeholder="Hostname or IP address"
|
||||
/>
|
||||
</div>
|
||||
<label class="uk-form-label" for="form-stacked-text"
|
||||
>Port</label
|
||||
>
|
||||
<div class="uk-form-controls">
|
||||
<input
|
||||
id="form-stacked-text"
|
||||
v-model="computedPort"
|
||||
class="uk-input uk-form-small"
|
||||
type="number"
|
||||
value="5000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="uk-card-footer uk-padding-small">
|
||||
<button
|
||||
type="submit"
|
||||
form="formConnectToHost"
|
||||
class="uk-button uk-button-primary uk-form-small uk-float-right uk-margin uk-margin-remove-top uk-width-1-1"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
Connect
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="$store.getters.ready"
|
||||
class="uk-button uk-button-default uk-form-small uk-margin-small uk-width-1-1"
|
||||
@click="saveHost()"
|
||||
>
|
||||
Save Current
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="$store.getters.ready"
|
||||
class="uk-button uk-button-danger uk-form-small uk-float-right uk-margin uk-margin-remove-top uk-width-1-1"
|
||||
@click="$store.commit('resetState')"
|
||||
>
|
||||
Disconnect
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-width-expand">
|
||||
<ul uk-accordion="multiple: true; animation: false">
|
||||
<li v-show="isElectron" id="nearby-connections-grid" class="uk-open">
|
||||
<a class="uk-accordion-title" href="#">Nearby devices</a>
|
||||
<div class="uk-accordion-content">
|
||||
<div class="uk-grid-medium uk-grid-match uk-margin-top" uk-grid>
|
||||
<div v-for="host in foundHostArray" :key="host.name">
|
||||
<hostCard
|
||||
:name="host.name"
|
||||
:hostname="host.hostname"
|
||||
:port="host.port"
|
||||
:deletable="false"
|
||||
@connect="handleConnectButton(host)"
|
||||
></hostCard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li id="saved-connections-grid" class="uk-open">
|
||||
<a class="uk-accordion-title" href="#">Saved devices</a>
|
||||
<div class="uk-accordion-content">
|
||||
<div class="uk-grid-medium uk-grid-match uk-margin-top" uk-grid>
|
||||
<div v-for="host in savedHosts" :key="host.name">
|
||||
<hostCard
|
||||
:name="host.name"
|
||||
:hostname="host.hostname"
|
||||
:port="host.port"
|
||||
@connect="handleConnectButton(host)"
|
||||
@delete="delSavedHost(host)"
|
||||
></hostCard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Import mDNS package if running in Electron
|
||||
import isElectron from "../../modules/isElectron";
|
||||
if (isElectron()) {
|
||||
var mdns = require("mdns-js");
|
||||
}
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
import hostCard from "./connectComponents/hostCard.vue";
|
||||
|
||||
// Export main app
|
||||
export default {
|
||||
name: "ConnectDisplay",
|
||||
|
||||
components: {
|
||||
hostCard
|
||||
},
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
isElectron: isElectron(),
|
||||
localMode: true,
|
||||
hostname: "",
|
||||
port: 5000,
|
||||
selectedHost: "",
|
||||
savedHosts: [],
|
||||
foundHosts: {}
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
foundHostArray: function() {
|
||||
return Object.values(this.foundHosts);
|
||||
},
|
||||
// Stylises the hostname input box based on connection status
|
||||
IpFormClasses: function() {
|
||||
return {
|
||||
"uk-form-danger": !this.$store.state.available,
|
||||
"uk-form-success": this.$store.getters.ready
|
||||
};
|
||||
},
|
||||
|
||||
computedLocalMode: {
|
||||
get: function() {
|
||||
return this.localMode;
|
||||
},
|
||||
set: function(state) {
|
||||
this.localMode = state;
|
||||
this.setLocalMode(state);
|
||||
}
|
||||
},
|
||||
|
||||
computedPort: {
|
||||
get: function() {
|
||||
if (this.hostname.includes(":")) {
|
||||
var port = parseInt(this.hostname.split(":")[1]);
|
||||
return !isNaN(port) ? port : this.port;
|
||||
} else {
|
||||
return this.port;
|
||||
}
|
||||
},
|
||||
set: function(newPort) {
|
||||
this.port = newPort;
|
||||
if (this.hostname.includes(":")) {
|
||||
this.hostname = this.hostname.split(":")[0] + ":" + this.port;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// When savedHosts changes, serialise to JSON and save to localStorage
|
||||
watch: {
|
||||
savedHosts() {
|
||||
this.setLocalStorageObj("savedHosts", this.savedHosts);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// Propagate localMode settings
|
||||
this.setLocalMode(this.localMode);
|
||||
|
||||
// Try loading savedHosts from localStorage. If null, don't change.
|
||||
this.savedHosts = this.getLocalStorageObj("savedHosts") || this.savedHosts;
|
||||
|
||||
// Handle mDNS browsing
|
||||
if (mdns) {
|
||||
// TODO: Have this run periodically on a timer
|
||||
|
||||
// Create a browser to search for 'openflexure' type services
|
||||
var browser = mdns.createBrowser(mdns.tcp("openflexure"));
|
||||
|
||||
// Start discovering services when ready
|
||||
browser.on("ready", function() {
|
||||
browser.discover();
|
||||
});
|
||||
|
||||
browser.on("update", data => {
|
||||
console.log(data);
|
||||
|
||||
// We will be checking if it's a valid openflexure device
|
||||
var validDevice = false;
|
||||
|
||||
// Go through each type of the host, make valid if 'openflexure' appears
|
||||
data.type.forEach(element => {
|
||||
console.log(element);
|
||||
if (element.name === "openflexure") {
|
||||
validDevice = true;
|
||||
}
|
||||
});
|
||||
|
||||
var hostData = {
|
||||
hostname: data.addresses[0],
|
||||
name: `${data.host} on ${data.networkInterface}`,
|
||||
port: data.port
|
||||
};
|
||||
|
||||
if (typeof data.port !== "undefined" && validDevice === true) {
|
||||
this.$set(this.foundHosts, hostData.hostname, hostData);
|
||||
}
|
||||
|
||||
console.log(this.foundHosts);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
connectToHost: function(host) {
|
||||
console.log(host);
|
||||
// Set the global form values
|
||||
this.hostname = host.hostname;
|
||||
this.port = host.port;
|
||||
|
||||
// Commit the hostname and port to store
|
||||
this.$store.commit("resetState");
|
||||
this.$store.commit("changeHost", [host.hostname, host.port]);
|
||||
this.$store.commit("changeWaiting", true);
|
||||
// Try to get list of available routes
|
||||
axios
|
||||
.get(`${this.$store.getters.baseUri}/routes`)
|
||||
.then(response => {
|
||||
console.log(response.data);
|
||||
// If the /api/v2 route is available
|
||||
if (Object.keys(response.data).includes("/api/v2/")) {
|
||||
console.log("API v2 available");
|
||||
// Tell Vuex store that we're connected
|
||||
this.$store.commit("setConnected");
|
||||
// Check client and server match
|
||||
this.checkServerVersion();
|
||||
} else {
|
||||
// Error and no-connect if API v2 is missing
|
||||
var ApiVersionError = `Your microscope is running an old API version.\
|
||||
You must update your microscope software to continue.\
|
||||
<br><br>
|
||||
For API upgrades, burning the latest Raspbian-OpenFlexure to your SD card is recommended.\
|
||||
<br><br>
|
||||
<b>Downloads and instructions can be found <a target="_blank" href="https://openflexure.org/projects/microscope/install">here</a></b>`;
|
||||
this.modalDialog("API upgrade required", ApiVersionError);
|
||||
this.$store.commit("setError");
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
this.$store.commit("setError");
|
||||
this.modalError(error); // Let mixin handle error
|
||||
});
|
||||
},
|
||||
|
||||
handleSubmit: function() {
|
||||
// Split host and port if needed
|
||||
if (this.hostname.includes(":")) {
|
||||
this.port = this.computedPort;
|
||||
this.hostname = this.hostname.split(":")[0];
|
||||
}
|
||||
|
||||
// Handle auto-local-connect
|
||||
var hostname;
|
||||
if (this.localMode) {
|
||||
hostname = "localhost";
|
||||
} else {
|
||||
hostname = this.hostname;
|
||||
}
|
||||
|
||||
var selectedHost = {
|
||||
hostname: hostname,
|
||||
port: this.port
|
||||
};
|
||||
|
||||
this.connectToHost(selectedHost);
|
||||
},
|
||||
|
||||
handleConnectButton: function(host) {
|
||||
this.computedLocalMode = false;
|
||||
this.connectToHost(host);
|
||||
},
|
||||
|
||||
checkServerVersion: function() {
|
||||
var versionUri = `${this.$store.getters.baseUri}/api/v2/instrument/configuration/application/version`;
|
||||
axios
|
||||
.get(versionUri)
|
||||
.then(response => {
|
||||
var serverVersion = response.data;
|
||||
var clientVersion = process.env.PACKAGE.version;
|
||||
var clientVersionMajor = clientVersion.substring(0, 3);
|
||||
console.log(clientVersionMajor);
|
||||
|
||||
if (serverVersion != undefined) {
|
||||
var serverVersionMajor = serverVersion.substring(0, 3);
|
||||
}
|
||||
console.log(serverVersionMajor);
|
||||
|
||||
if (
|
||||
serverVersion == undefined ||
|
||||
serverVersionMajor != clientVersionMajor
|
||||
) {
|
||||
var versionWarning = `Client and microscope versions do not match.\
|
||||
Please update your microscope software.\
|
||||
<b>Client version:</b> ${clientVersion}<br> \
|
||||
<b>Server version:</b> ${serverVersion}<br><br>`;
|
||||
if (serverVersion < 1.1) {
|
||||
versionWarning =
|
||||
versionWarning +
|
||||
"You will need to install a newer server version on a clean SD card.";
|
||||
} else {
|
||||
versionWarning =
|
||||
versionWarning +
|
||||
"Run <b><tt>ofm update</tt></b> and then <b><tt>ofm upgrade</tt></b> on your microscope.";
|
||||
}
|
||||
this.modalDialog("Version mismatch", versionWarning);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
this.modalError(error); // Let mixin handle error
|
||||
});
|
||||
},
|
||||
|
||||
setLocalMode: function(state) {
|
||||
this.$store.commit("changeSetting", ["trackWindow", state]);
|
||||
this.$store.commit("changeSetting", ["disableStream", state]);
|
||||
this.$store.commit("changeSetting", ["autoGpuPreview", state]);
|
||||
},
|
||||
|
||||
delSavedHost: function(host) {
|
||||
console.log(host);
|
||||
var index = this.savedHosts.indexOf(host);
|
||||
if (index > -1) {
|
||||
this.savedHosts.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
saveHost: function() {
|
||||
// URI to get hostname directly from settings
|
||||
var hostnameUri = `${this.$store.getters.baseUri}/api/v2/instrument/settings/name`;
|
||||
axios
|
||||
.get(hostnameUri)
|
||||
.then(response => {
|
||||
// Get device name from response
|
||||
var deviceName = response.data;
|
||||
// We use unshift instead of push to add the entry to the beginning of the array
|
||||
this.savedHosts.unshift({
|
||||
name: deviceName,
|
||||
hostname: this.$store.state.host,
|
||||
port: this.$store.state.port
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
this.modalError(error); // Let mixin handle error
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less"></style>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// Load settings store from main process
|
||||
const { store } = require("electron").remote.require("./store");
|
||||
|
||||
// Load extra modules we'll be using
|
||||
const { Titlebar, Color } = require("custom-electron-titlebar");
|
||||
|
||||
// Only show custom menubar if current window has no frame
|
||||
if (store.get("drawCustomTitleBar") == true) {
|
||||
new Titlebar({
|
||||
backgroundColor: Color.fromHex("#c5247f"),
|
||||
icon: "./titleicon.svg"
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Loaded main.app.js for electron-renderer functionality");
|
||||
16
src/main.js
|
|
@ -76,7 +76,15 @@ Vue.mixin({
|
|||
},
|
||||
|
||||
modalError: function(error) {
|
||||
console.log(error);
|
||||
var errormsg = this.getErrorMessage(error);
|
||||
this.$store.commit("setErrorMessage", errormsg);
|
||||
UIkit.notification({
|
||||
message: `${errormsg}`,
|
||||
status: "danger"
|
||||
});
|
||||
},
|
||||
|
||||
getErrorMessage: function(error) {
|
||||
var errormsg = "";
|
||||
|
||||
// If a response was obtained
|
||||
|
|
@ -100,11 +108,7 @@ Vue.mixin({
|
|||
errormsg = `${error.message}`;
|
||||
console.log(errormsg);
|
||||
}
|
||||
this.$store.commit("setError", errormsg);
|
||||
UIkit.notification({
|
||||
message: `${errormsg}`,
|
||||
status: "danger"
|
||||
});
|
||||
return errormsg;
|
||||
},
|
||||
|
||||
showModalElement: function(element) {
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
function isElectron() {
|
||||
// Renderer process
|
||||
if (
|
||||
typeof window !== "undefined" &&
|
||||
typeof window.process === "object" &&
|
||||
window.process.type === "renderer"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Main process
|
||||
if (
|
||||
typeof process !== "undefined" &&
|
||||
typeof process.versions === "object" &&
|
||||
!!process.versions.electron
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Detect the user agent when the `nodeIntegration` option is set to true
|
||||
if (
|
||||
typeof navigator === "object" &&
|
||||
typeof navigator.userAgent === "string" &&
|
||||
navigator.userAgent.indexOf("Electron") >= 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export default isElectron;
|
||||
15
src/store.js
|
|
@ -5,8 +5,7 @@ Vue.use(Vuex);
|
|||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
host: "",
|
||||
port: 5000,
|
||||
origin: window.location.origin,
|
||||
available: false,
|
||||
waiting: false,
|
||||
error: "",
|
||||
|
|
@ -20,9 +19,8 @@ export default new Vuex.Store({
|
|||
},
|
||||
|
||||
mutations: {
|
||||
changeHost(state, [host, port]) {
|
||||
state.host = host;
|
||||
state.port = port;
|
||||
changeOrigin(state, origin) {
|
||||
state.origin = origin;
|
||||
},
|
||||
changeWaiting(state, waiting) {
|
||||
state.waiting = waiting;
|
||||
|
|
@ -39,8 +37,7 @@ export default new Vuex.Store({
|
|||
state.waiting = false;
|
||||
state.available = true;
|
||||
},
|
||||
setError(state, msg) {
|
||||
state.waiting = false;
|
||||
setErrorMessage(state, msg) {
|
||||
state.error = msg;
|
||||
},
|
||||
addStream(state, id) {
|
||||
|
|
@ -54,8 +51,8 @@ export default new Vuex.Store({
|
|||
actions: {},
|
||||
|
||||
getters: {
|
||||
uriV2: state => `http://${state.host}:${state.port}/api/v2`,
|
||||
baseUri: state => `http://${state.host}:${state.port}`,
|
||||
uriV2: state => `${state.origin}/api/v2`,
|
||||
baseUri: state => state.origin,
|
||||
ready: state => state.available
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,32 +1,15 @@
|
|||
var webpack = require("webpack");
|
||||
|
||||
module.exports = {
|
||||
configureWebpack: config => {
|
||||
(config.target = process.env.VUE_APP_TARGET || "web"),
|
||||
(config.entry =
|
||||
process.env.VUE_APP_TARGET == "electron-renderer"
|
||||
? {
|
||||
main: "./src/main.js",
|
||||
app: "./src/main.app.js"
|
||||
}
|
||||
: {
|
||||
main: "./src/main.js"
|
||||
}),
|
||||
config.plugins.push(
|
||||
new webpack.DefinePlugin({
|
||||
"process.env": {
|
||||
PACKAGE: JSON.stringify(require("./package.json"))
|
||||
}
|
||||
})
|
||||
);
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
"process.env": {
|
||||
PACKAGE: JSON.stringify(require("./package.json"))
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
outputDir: (function() {
|
||||
if (process.env.VUE_APP_TARGET == "electron-renderer") {
|
||||
return "./app/dist";
|
||||
} else {
|
||||
return "./dist";
|
||||
}
|
||||
})(),
|
||||
|
||||
publicPath: ""
|
||||
};
|
||||
|
|
|
|||