aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Raes <contact@remyraes.com>2022-01-12 16:49:02 +0100
committerGitHub <noreply@github.com>2022-01-12 16:49:02 +0100
commitab71fa02bc751da44dee7d4118feaa13f28dee67 (patch)
tree35f5c15ea502cc3c7de01011f1b9a61b5286d339
parent9a135bfc554ccfddf64e71725b98bc4317d14732 (diff)
downloadViper-ab71fa02bc751da44dee7d4118feaa13f28dee67.tar.gz
Viper-ab71fa02bc751da44dee7d4118feaa13f28dee67.zip
feat: New UI (#26)
* [chore] removing setsize mechanism * [feat] adding new html skeleton * [feat] adding games icon buttons * [feat] all icon buttons have same size * [fix] games container width varies between 95 and 120px * [feat] displaying bg image * [feat] each game has its own background image * [feat] adding content skeleton * [feat] window has no frame anymore * [feat] buttons show related content only * [feat] displaying viper release notes * [feat] game icons are vertically centered * [feat] background is a bit grayed out * [feat] adding some items to games menus * [feat] displaying games logos * [feat] adding content menu active item indicator * [fix] centering active item indicator * [feat] not displaying viper credits by default * [feat] viper categories can be browsed through via menu * [feat] adjusting hovering style of menu items * [feat] adding play button styles * [feat] adding missing vp sections * [feat] adding link styles * [fix] scaling down northstar logo * [feat] adding ns sections * [feat] fetching northstar release notes * [fix] release notes containers are scrollable * [feat] removing space between menu and some sections * [feat] loading vp+ns versions into interface * [chore] pushing version to 0.10.0 * [feat] play buttons launch games * [refactor] renaming vp releases fetching method * [feat] displaying an option to update northstar * [feat] message is displayed if ns is up-to-date * [feat] displaying ns download progress * [refactor] removing ns-updating and ns-updated events * [feat] adding UI translations * [fix] correctly displaying vp release notes * [refactor] removing useless code * [feat] adding Imply to credits for viper logo * [feat] loading titanfall version from gameversion.txt file * [feat] centering viper main section * [feat] adding custom scrollbars to release notes sections * [feat] disabling images drag * [feat] all external links are opened in default browser * [feat] formatting release notes with markdown converter * [feat] translating UI items * fixed backgrounds not being same size This would cause weird transitions. * new.css is now main.css, fixed colors and fonts * page indicator is now prettier We no longer use a character to render a circle, and it's no longer a circle, instead it's a line, we also now have a nice transition on it, both for fading in and out. * removed simplebar in favor of ::-webkit-scrollbar Almost everything we did with simplerbar could be done with native WebKit scollbar CSS, hence why we switched to it. * fixed uneven nav button margin * fixed formatting Single quotes to double quotes, spaces to tabs, etc etc... I also removed simplerbar properly... * removed unneeded consts Elements set with ID's can by default be referred to with their ID, aka: const element = document.getElementById("element"); Is useless as "element" will automatically refer to that element if theres no variable that overwrites it. * use release name over tag_name "Release vX.X.X" frankly looks better than "vX.X.X" * playBtn's now look nicer Slight transition on hover and click. * added pointer cursors to nav buttons and playBtn's Along with transitions to the nav buttons, because they look very good. * [fix] viper main section appears correctly on viper logo clicked * different opacity for inactive pages * removed "Roboto Mono", added normal "Roboto" * removed old HTML * fixed formatting in launcher.js * redesigned contentContainer's, and a lot more I also swapped around the Vanilla logo and Northstar logo to have the same size and the "Titanfall 2" text is in the same place on both images, allowing seamless transition when changing pages. I also completely redesigned displayContent(), it's now page() and doesn't revolve around a switch case. I'll likely do a similar thing with showVpSection() and showNsSection(), uniting them into one function that doesn't use switch cases. * added close button * fix game icons not being found * removed excess icons from assets folder * [feat] adding a br to french releases key * [feat] centering menu items * [feat] implementing requests cache for NS release notes * [feat] implementing cache for VP release notes * changed ttf2 to tf2 Along with that, I also renamed the northstar2.jpeg bg to just northstar.jpg, as all other background are .jpg * [fix] adjusting containers * [fix] adding some space between menu and content Since we have lots of space to use now, let's use it! This extra-space does not apply to release notes sections, which already takes all available screen space. * [feat] adding code style * [fix] window is draggable thanks to a drag bar on its top * [fix] drag bar height * [fix] all window is draggable * [fix] not disabling game buttons on ns update * [fix] disabled buttons cannot be clicked * [fix] displaying ns update downloading state on UI * [fix] typos * general improvements to the UI Launch buttons now have a nice gradient, a shadow and a better hover animation. The Titanfall logos are now also centered no matter the window size, so if in the future we decide to allow resizing the window that won't be a problem, or if you force the window to do it through some trickery, it'll also still show correctly. I also changed the default font weight to 500, some pieces of text looked very thin. * unified information and credits section * mods section should more or less look good now Still not complete done, I still wanna implement a drag and drop install, along with selecting whether you're installing a zip or folder. And also a warning when toggling or removing required mods... But generally this is the design I will go with. * added warnings for toggling/removing core mods * [feat] adding missing translations * [fix] typo in gui.mods.disabledtag french translation * re-added download progress * added section transitions * switched to npm module for markdown parsing * correcting some formatting, nothing special * active page button is now more obvious Co-authored-by: 0neGal <mail@0negal.com>
-rw-r--r--package-lock.json56
-rw-r--r--package.json1
-rw-r--r--src/app/fonts/Roboto-Black.ttfbin0 -> 168060 bytes
-rw-r--r--src/app/fonts/Roboto-BlackItalic.ttfbin0 -> 174108 bytes
-rw-r--r--src/app/fonts/Roboto-Bold.ttfbin0 -> 167336 bytes
-rw-r--r--src/app/fonts/Roboto-BoldItalic.ttfbin0 -> 171508 bytes
-rw-r--r--src/app/fonts/Roboto-Italic.ttfbin0 -> 170504 bytes
-rw-r--r--src/app/fonts/Roboto-Light.ttfbin0 -> 167000 bytes
-rw-r--r--src/app/fonts/Roboto-LightItalic.ttfbin0 -> 173172 bytes
-rw-r--r--src/app/fonts/Roboto-Medium.ttfbin0 -> 168644 bytes
-rw-r--r--src/app/fonts/Roboto-MediumItalic.ttfbin0 -> 173416 bytes
-rw-r--r--src/app/fonts/Roboto-Regular.ttfbin0 -> 168260 bytes
-rw-r--r--src/app/fonts/Roboto-Thin.ttfbin0 -> 168488 bytes
-rw-r--r--src/app/fonts/Roboto-ThinItalic.ttfbin0 -> 172860 bytes
-rw-r--r--src/app/fonts/import.css83
-rw-r--r--src/app/icons/close.pngbin0 -> 2661 bytes
-rw-r--r--src/app/icons/northstar.pngbin0 -> 135670 bytes
-rw-r--r--src/app/icons/titanfall2.pngbin0 -> 26922 bytes
-rw-r--r--src/app/icons/viper.pngbin0 -> 137107 bytes
-rw-r--r--src/app/index.html111
-rw-r--r--src/app/launcher.js105
-rw-r--r--src/app/main.css427
-rw-r--r--src/app/main.js71
-rw-r--r--src/app/roboto.ttfbin87008 -> 0 bytes
-rw-r--r--src/assets/bg/northstar.jpgbin0 -> 103397 bytes
-rw-r--r--src/assets/bg/tf2.jpgbin0 -> 132623 bytes
-rw-r--r--src/assets/bg/viper.jpgbin0 -> 133337 bytes
-rw-r--r--src/assets/ns.pngbin0 -> 20619 bytes
-rw-r--r--src/assets/vanilla.pngbin0 -> 9139 bytes
-rw-r--r--src/index.js32
-rw-r--r--src/lang/en.json26
-rw-r--r--src/lang/fr.json28
-rw-r--r--src/requests.js78
-rw-r--r--src/utils.js43
34 files changed, 891 insertions, 170 deletions
diff --git a/package-lock.json b/package-lock.json
index d02e4c7..5e3168f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,17 +1,18 @@
{
"name": "viper",
- "version": "0.9.1",
+ "version": "0.9.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "viper",
- "version": "0.9.1",
+ "version": "0.9.2",
"license": "GPL-3.0-or-later",
"dependencies": {
"copy-dir": "^1.3.0",
"electron-updater": "^4.6.1",
"follow-redirects": "^1.14.6",
+ "markdown": "^0.5.0",
"marked-man": "^0.7.0",
"unzipper": "^0.10.11"
},
@@ -297,6 +298,11 @@
"integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==",
"dev": true
},
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -2371,6 +2377,20 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/markdown": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz",
+ "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=",
+ "dependencies": {
+ "nopt": "~2.1.1"
+ },
+ "bin": {
+ "md2html": "bin/md2html.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
@@ -2488,6 +2508,17 @@
"dev": true,
"optional": true
},
+ "node_modules/nopt": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
+ "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ }
+ },
"node_modules/normalize-url": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
@@ -3687,6 +3718,11 @@
"integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==",
"dev": true
},
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -5294,6 +5330,14 @@
"semver": "^6.0.0"
}
},
+ "markdown": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz",
+ "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=",
+ "requires": {
+ "nopt": "~2.1.1"
+ }
+ },
"marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
@@ -5376,6 +5420,14 @@
"dev": true,
"optional": true
},
+ "nopt": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
+ "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
+ "requires": {
+ "abbrev": "1"
+ }
+ },
"normalize-url": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
diff --git a/package.json b/package.json
index 942efd6..78dcb36 100644
--- a/package.json
+++ b/package.json
@@ -51,6 +51,7 @@
"copy-dir": "^1.3.0",
"electron-updater": "^4.6.1",
"follow-redirects": "^1.14.6",
+ "markdown": "^0.5.0",
"marked-man": "^0.7.0",
"unzipper": "^0.10.11"
},
diff --git a/src/app/fonts/Roboto-Black.ttf b/src/app/fonts/Roboto-Black.ttf
new file mode 100644
index 0000000..43a00e0
--- /dev/null
+++ b/src/app/fonts/Roboto-Black.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-BlackItalic.ttf b/src/app/fonts/Roboto-BlackItalic.ttf
new file mode 100644
index 0000000..5082cdc
--- /dev/null
+++ b/src/app/fonts/Roboto-BlackItalic.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-Bold.ttf b/src/app/fonts/Roboto-Bold.ttf
new file mode 100644
index 0000000..3742457
--- /dev/null
+++ b/src/app/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-BoldItalic.ttf b/src/app/fonts/Roboto-BoldItalic.ttf
new file mode 100644
index 0000000..e85e7fb
--- /dev/null
+++ b/src/app/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-Italic.ttf b/src/app/fonts/Roboto-Italic.ttf
new file mode 100644
index 0000000..c9df607
--- /dev/null
+++ b/src/app/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-Light.ttf b/src/app/fonts/Roboto-Light.ttf
new file mode 100644
index 0000000..0e97751
--- /dev/null
+++ b/src/app/fonts/Roboto-Light.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-LightItalic.ttf b/src/app/fonts/Roboto-LightItalic.ttf
new file mode 100644
index 0000000..3ad14fa
--- /dev/null
+++ b/src/app/fonts/Roboto-LightItalic.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-Medium.ttf b/src/app/fonts/Roboto-Medium.ttf
new file mode 100644
index 0000000..e89b0b7
--- /dev/null
+++ b/src/app/fonts/Roboto-Medium.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-MediumItalic.ttf b/src/app/fonts/Roboto-MediumItalic.ttf
new file mode 100644
index 0000000..a5a41d3
--- /dev/null
+++ b/src/app/fonts/Roboto-MediumItalic.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-Regular.ttf b/src/app/fonts/Roboto-Regular.ttf
new file mode 100644
index 0000000..3d6861b
--- /dev/null
+++ b/src/app/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-Thin.ttf b/src/app/fonts/Roboto-Thin.ttf
new file mode 100644
index 0000000..7d084ae
--- /dev/null
+++ b/src/app/fonts/Roboto-Thin.ttf
Binary files differ
diff --git a/src/app/fonts/Roboto-ThinItalic.ttf b/src/app/fonts/Roboto-ThinItalic.ttf
new file mode 100644
index 0000000..c173389
--- /dev/null
+++ b/src/app/fonts/Roboto-ThinItalic.ttf
Binary files differ
diff --git a/src/app/fonts/import.css b/src/app/fonts/import.css
new file mode 100644
index 0000000..c6b677a
--- /dev/null
+++ b/src/app/fonts/import.css
@@ -0,0 +1,83 @@
+@font-face {
+ font-weight: 100;
+ font-style: italic;
+ font-family: "Roboto";
+ src: url("Roboto-ThinItalic.ttf");
+}
+
+@font-face {
+ font-weight: 300;
+ font-style: italic;
+ font-family: "Roboto";
+ src: url("Roboto-Italic.ttf");
+}
+
+@font-face {
+ font-weight: 400;
+ font-style: italic;
+ font-family: "Roboto";
+ src: url("Roboto-Italic.ttf");
+}
+
+@font-face {
+ font-weight: 500;
+ font-style: italic;
+ font-family: "Roboto";
+ src: url("Roboto-MediumItalic.ttf");
+}
+
+@font-face {
+ font-weight: 700;
+ font-style: italic;
+ font-family: "Roboto";
+ src: url("Roboto-BoldItalic.ttf");
+}
+
+@font-face {
+ font-weight: 900;
+ font-style: italic;
+ font-family: "Roboto";
+ src: url("Roboto-BlackItalic.ttf");
+}
+
+@font-face {
+ font-weight: 100;
+ font-style: normal;
+ font-family: "Roboto";
+ src: url("Roboto-Thin.ttf");
+}
+
+@font-face {
+ font-weight: 300;
+ font-style: normal;
+ font-family: "Roboto";
+ src: url("Roboto-Light.ttf");
+}
+
+@font-face {
+ font-weight: 400;
+ font-style: normal;
+ font-family: "Roboto";
+ src: url("Roboto-Regular.ttf");
+}
+
+@font-face {
+ font-weight: 500;
+ font-style: normal;
+ font-family: "Roboto";
+ src: url("Roboto-Medium.ttf");
+}
+
+@font-face {
+ font-weight: 700;
+ font-style: normal;
+ font-family: "Roboto";
+ src: url("Roboto-Bold.ttf");
+}
+
+@font-face {
+ font-weight: 900;
+ font-style: normal;
+ font-family: "Roboto";
+ src: url("Roboto-Black.ttf");
+}
diff --git a/src/app/icons/close.png b/src/app/icons/close.png
new file mode 100644
index 0000000..d6c162f
--- /dev/null
+++ b/src/app/icons/close.png
Binary files differ
diff --git a/src/app/icons/northstar.png b/src/app/icons/northstar.png
new file mode 100644
index 0000000..f13ae27
--- /dev/null
+++ b/src/app/icons/northstar.png
Binary files differ
diff --git a/src/app/icons/titanfall2.png b/src/app/icons/titanfall2.png
new file mode 100644
index 0000000..f1caa0e
--- /dev/null
+++ b/src/app/icons/titanfall2.png
Binary files differ
diff --git a/src/app/icons/viper.png b/src/app/icons/viper.png
new file mode 100644
index 0000000..281f3dd
--- /dev/null
+++ b/src/app/icons/viper.png
Binary files differ
diff --git a/src/app/index.html b/src/app/index.html
index d9db79b..8ebffff 100644
--- a/src/app/index.html
+++ b/src/app/index.html
@@ -1,46 +1,103 @@
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
+ <link rel="stylesheet" href="fonts/import.css">
<link rel="stylesheet" href="main.css">
+ <meta charset="utf-8">
</head>
<body>
- <div class="lines">
- <div class="line">
- <div class="text">
- <div class="text" id="welcome">%%gui.welcome%%</div>
- <div class="versions">
- <div id="vpversion"></div>
- <div id="nsversion"></div>
+ <div id="bgHolder"></div>
+
+ <div id="close" onclick="ipcRenderer.send('exit')"></div>
+
+ <nav class="gamesContainer">
+ <button id="vpBtn" onclick="page(0)"></button>
+ <button id="nsBtn" onclick="page(1)"></button>
+ <button id="tfBtn" onclick="page(2)"></button>
+ </nav>
+
+ <div class="mainContainer">
+ <div id="vpContent" class="contentContainer">
+ <ul class="contentMenu">
+ <li id="vpMainBtn" active onclick="showVpSection('main')">%%viper.menu.main%%</li>
+ <li id="vpReleaseBtn" onclick="showVpSection('release')">%%viper.menu.release%%</li>
+ <li id="vpInfoBtn" onclick="showVpSection('info')">%%viper.menu.info%%</li>
+ </ul>
+ <div class="contentBody">
+ <div id="vpMain" class="section">
+ <img src="icons/viper.png"/>
+ <div class="inline" style="margin-top: 20px;">
+ <div id="vpversion"></div> |
+ <a id="setpath" href="#" onclick="setpath()">%%gui.setpath%%</a>
+ </div>
+ </div>
+ <div id="vpReleaseNotes" class="hidden section"></div>
+ <div id="vpInfo" class="hidden section">
+ <h2>%%viper.menu.info.links%%</h2>
+ <ul>
+ <li>%%viper.info.discord%% <a href="https://northstar.tf/discord">northstar.tf/discord</a></li>
+ <li>%%viper.info.issues%% <a href="https://github.com/0neGal/viper/issues">github.com/0neGal/viper/issues</a></li>
+ </ul>
+ <h2>%%viper.menu.info.credits%%</h2>
+ <ul>
+ <li>"Titanfall|2 + Northstar" logo: <a href="https://www.steamgriddb.com/logo/47851">Aftonstjarma</a></li>
+ <li>Viper logo: Imply#9781</li>
+ </ul>
</div>
- </div>
- <div class="buttons">
- <button id="exit" onclick="exit()">%%gui.exit%%</button>
- <button id="updateBtn" onclick="update()">%%gui.update%%</button>
- <button id="setpath" onclick="setpath()">%%gui.setpath%%</button>
</div>
</div>
- <div class="line">
- <div class="text">%%gui.launch%%:</div>
- <div class="buttons">
- <button id="vanilla" onclick="launchVanilla()">%%gui.launchvanilla%%</button>
- <button id="northstar" onclick="launch()">%%gui.launchnorthstar%%</button>
+
+ <div id="nsContent" class="contentContainer">
+ <ul class="contentMenu">
+ <li id="nsMainBtn" active onclick="showNsSection('main')">%%ns.menu.main%%</li>
+ <li id="nsModsBtn" onclick="showNsSection('mods')">%%ns.menu.mods%%</li>
+ <li id="nsReleaseBtn" onclick="showNsSection('release')">%%ns.menu.release%%</li>
+ </ul>
+ <div class="contentBody">
+ <div id="nsMain" class="section">
+ <div class="img"><img src="../assets/ns.png"></div>
+ <div class="playBtnContainer">
+ <button id="playNsBtn" class="playBtn" onclick="launch()">%%gui.launch%%</button>
+ <div class="inline">
+ <div id="nsversion"></div>
+ <a id="update" href="#" onclick="update()">(%%gui.update.check%%)</a>
+ </div>
+ </div>
+ </div>
+ <div id="nsMods" class="hidden section">
+ <div id="modsdiv">
+ </div>
+ <div class="line">
+ <div class="text" id="modcount">%%gui.mods%%</div>
+ <div class="buttons modbtns">
+ <button id="removemod" onclick="selected().remove()">%%gui.mods.remove%%</button>
+ <button id="removeall" onclick="selected(true).remove()">%%gui.mods.removeall%%</button>
+ <button id="togglemod" onclick="selected().toggle()">%%gui.mods.toggle%%</button>
+ <button id="toggleall" onclick="selected(true).toggle(true)">%%gui.mods.toggleall%%</button>
+ <button id="installmod" onclick="installmod()">%%gui.mods.install%%</button>
+ </div>
+ </div>
+ </div>
+ <div id="nsRelease" class="hidden section"></div>
</div>
</div>
- <div id="modsdiv">
- </div>
- <div class="line">
- <div class="text" id="modcount">%%gui.mods%%</div>
- <div class="buttons modbtns">
- <button id="removemod" onclick="selected().remove()">%%gui.mods.remove%%</button>
- <button id="removeall" onclick="selected(true).remove()">%%gui.mods.removeall%%</button>
- <button id="togglemod" onclick="selected().toggle()">%%gui.mods.toggle%%</button>
- <button id="toggleall" onclick="selected(true).toggle(true)">%%gui.mods.toggleall%%</button>
- <button id="installmod" onclick="installmod()">%%gui.mods.install%%</button>
+
+ <div id="tfContent" class="contentContainer">
+ <ul class="contentMenu"><li style="opacity:0.0">filler</li></ul>
+ <div class="contentBody">
+ <div class="section">
+ <div class="img"><img src="../assets/vanilla.png"></div>
+ <div class="playBtnContainer">
+ <button class="playBtn" onclick="launchVanilla()">%%gui.launch%%</button>
+ <div id="tf2Version"></div>
+ </div>
+ </div>
</div>
</div>
</div>
<script src="lang.js"></script>
<script src="main.js"></script>
+ <script src="launcher.js"></script>
</body>
</html>
diff --git a/src/app/launcher.js b/src/app/launcher.js
new file mode 100644
index 0000000..9e09938
--- /dev/null
+++ b/src/app/launcher.js
@@ -0,0 +1,105 @@
+const markdown = require("markdown").markdown.toHTML;
+
+function page(page) {
+ let pages = document.querySelectorAll(".mainContainer .contentContainer")
+ let btns = document.querySelectorAll(".gamesContainer button")
+
+ for (let i = 0; i < pages.length; i++) {
+ pages[i].classList.add("hidden");
+ }
+
+ for (let i = 0; i < btns.length; i++) {
+ btns[i].classList.add("inactive");
+ }
+
+ pages[page].classList.remove("hidden");
+ btns[page].classList.remove("inactive");
+ bgHolder.setAttribute("bg", page);
+}; page(0)
+
+
+ipcRenderer.on("vp-notes", (event, response) => {
+ let content = "";
+
+ for (const release of response) {
+ content += "# " + release.name + "\n\n"
+ + release.body.replaceAll("\r\n", "\n") + "\n\n\n";
+ }
+
+ vpReleaseNotes.innerHTML = markdown(content);
+});
+async function loadVpReleases() {
+ ipcRenderer.send("get-vp-notes");
+}; loadVpReleases();
+
+
+ipcRenderer.on("ns-notes", (event, response) => {
+ let content = "";
+
+ for (let release of response) {
+ content += "# " + release.name + "\n\n"
+ + release.body.replaceAll("\r\n", "\nhtmlbreak") + "\n\n\n";
+ }
+
+ nsRelease.innerHTML = markdown(content).replaceAll("htmlbreak", "<br>");
+});
+
+async function loadNsReleases() {
+ ipcRenderer.send("get-ns-notes");
+}; loadNsReleases();
+
+// TODO: We gotta make this more automatic instead of switch statements
+// it's both not pretty, but adding more sections requires way too much
+// effort, compared to how it should be.
+function showVpSection(section) {
+ if (!["main", "release", "info", "credits"].includes(section)) throw new Error("unknown vp section");
+ vpMainBtn.removeAttribute("active");
+ vpReleaseBtn.removeAttribute("active");
+ vpInfoBtn.removeAttribute("active");
+
+ vpMain.classList.add("hidden");
+ vpReleaseNotes.classList.add("hidden");
+ vpInfo.classList.add("hidden");
+
+ switch(section) {
+ case "main":
+ vpMainBtn.setAttribute("active", "");
+ vpMain.classList.remove("hidden");
+ break;
+ case "release":
+ vpReleaseBtn.setAttribute("active", "");
+ vpReleaseNotes.classList.remove("hidden");
+ break;
+ case "info":
+ vpInfoBtn.setAttribute("active", "");
+ vpInfo.classList.remove("hidden");
+ break;
+ }
+}
+
+function showNsSection(section) {
+ if (!["main", "release", "mods"].includes(section)) throw new Error("unknown ns section");
+ nsMainBtn.removeAttribute("active");
+ nsModsBtn.removeAttribute("active");
+ nsReleaseBtn.removeAttribute("active");
+
+ nsMain.classList.add("hidden");
+ nsMods.classList.add("hidden");
+ nsRelease.classList.add("hidden");
+
+ switch(section) {
+ case "main":
+ nsMainBtn.setAttribute("active", "");
+ nsMain.classList.remove("hidden");
+ break;
+ case "mods":
+ nsModsBtn.setAttribute("active", "");
+ nsMods.style.display = "block";
+ nsMods.classList.remove("hidden");
+ break;
+ case "release":
+ nsReleaseBtn.setAttribute("active", "");
+ nsRelease.classList.remove("hidden");
+ break;
+ }
+}
diff --git a/src/app/main.css b/src/app/main.css
index 69b10ad..30f462e 100644
--- a/src/app/main.css
+++ b/src/app/main.css
@@ -1,116 +1,391 @@
:root {
- --padding: 15px;
- --disabled: #656E7F;
- --foreground: #DDE2EB;
- --background: #4C515B;
- --boxbackground: #666E7F;
- --subforeground: #AFAFAF;
- --btnforeground: var(--foreground);
-
--red: #C7777F;
--blue: #81A1C1;
- --yellow: #ECD19A;
+ --orange: #D59783;
+
+ --padding: 25px;
+
+ --bg: rgba(0, 0, 0, 0.5);
+ --selbg: rgba(80, 80, 80, 0.5);
+ --redbg: linear-gradient(45deg, var(--red), #FA4343);
+ --bluebg: linear-gradient(45deg, var(--blue), #7380ED);
+
}
-@media (prefers-color-scheme: light) {
- :root {
- --background: #FFFFFF;
- --foreground: #4C566A;
- --boxbackground: #EEF0F4;
- --btnforeground: var(--background);
- }
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ border-radius: 10px;
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 10px;
+ background: var(--red);
}
-@font-face {
- font-family: "Roboto Mono";
- src: url("roboto.ttf");
+.playBtn, .gamesContainer button, #close {
+ cursor: pointer;
}
-::-webkit-scrollbar {display: none}
+#close {
+ z-index: 1;
+ width: 25px;
+ opacity: 0.6;
+ height: 25px;
+ position: fixed;
+ top: var(--padding);
+ right: var(--padding);
+ background-size: contain;
+ transition: 0.25s ease-in-out;
+ background-image: url("icons/close.png");
+}
-body, button, input {
- font-size: 18px;
- font-weight: 700;
+#close:hover {opacity: 1.0}
+#close:active {transform: scale(0.98)}
+
+body {
+ margin: 0;
overflow: hidden;
- -webkit-app-region: drag;
- color: var(--foreground);
- text-transform: uppercase;
- background: var(--background);
- font-family: "Roboto Mono", monospace;
+ user-select: none;
+ font-family: "Roboto", sans-serif;
}
-nobr {white-space: nowrap}
+button {outline: none}
+b, strong {font-weight: 700}
+body, input, button {font-weight: 500}
-.versions {
- height: 15px;
- font-size: 12px;
- color: var(--subforeground);
+button {
+ border: none;
+ color: white;
+ outline: none;
+ font-weight: 700;
+ padding: 5px 10px;
+ border-radius: 5px;
+ transition: 0.2s ease-in-out;
}
-.line {
+button:hover {filter: brightness(110%)}
+button:active {filter: brightness(90%)}
+
+img {pointer-events: none}
+
+#bgHolder {
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ pointer-events: none;
+ position: fixed;
+ transform: scale(1.1);
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ transition: background-image 0.5s ease-in-out;
+ filter: brightness(0.4) blur(2px) grayscale(0.6);
+}
+
+#bgHolder[bg="0"] {background-image: url("../assets/bg/viper.jpg")}
+#bgHolder[bg="1"] {background-image: url("../assets/bg/northstar.jpg")}
+#bgHolder[bg="2"] {background-image: url("../assets/bg/tf2.jpg")}
+
+.gamesContainer {
+ width: 10%;
+ height: 100%;
+ min-width: 95px;
+ max-width: 120px;
+
+ float: left;
display: flex;
- margin-top: var(--padding);
+ flex-wrap: wrap;
+ align-content: center;
}
-#modsdiv {
- padding: 1px;
- height: 125px;
- overflow-y: scroll;
- border-radius: var(--padding);
- background: var(--boxbackground);
- margin: calc(var(--padding) / 3) var(--padding);
+.mainContainer {
+ height: 100%;
+ flex-grow: 1;
+ display: flex;
+ position: relative;
}
-.mod {
- margin: calc(var(--padding) / 3);
- border-radius: calc(var(--padding) / 2) !important;
+
+/* nav bar buttons */
+.gamesContainer button {
+ background-size: 90%;
+ background-position: center;
+ background-repeat: no-repeat;
+
+ border: none;
+ transition: 0.3s ease-in-out;
+ background-color: transparent;
+
+
+ margin: 20px;
+ position: relative;
+ box-sizing: border-box;
+ flex-basis: calc(100% - 10px);
}
-.mod.selected {background: var(--background)}
+.gamesContainer button.inactive {
+ opacity: 0.5;
+ transform: scale(0.9);
+}
-.mod .disabled {
- color: var(--red);
- position: relative;
- left: var(--padding);
+.gamesContainer button::before {
+ content: "";
+ display: block;
+ padding-top: 100%;
}
-.buttons {
- text-align: right;
- margin-left: auto;
- user-select: none;
- margin-right: calc(var(--padding) / 1.9);
+.gamesContainer button .content {
+ width: 100%;
+ height: 100%;
+ top: 0; left: 0;
+ position: absolute;
}
-.text {max-width: 38vw}
-.buttons {max-width: 55vw}
+#vpBtn {background-image: url("icons/viper.png")}
+#nsBtn {background-image: url("icons/northstar.png")}
+#tfBtn {
+ background-image: url("icons/titanfall2.png");
+ background-size: 69%; /* nice */
+}
-button, .text, .mod {
- border: none;
- outline: none;
- user-select: none;
+.contentContainer {
+ width: 90%;
+ color: white;
+ flex-grow: 1;
+ opacity: 1.0;
+ margin-left: 5%;
+ position: absolute;
+ transition: 0.15s ease-in-out;
+}
+
+.contentContainer.hidden {
+ opacity: 0.0;
+ pointer-events: none;
+}
+
+.contentMenu {
+ padding: 0;
+ flex-grow: 1;
+ display: flex;
+ font-size: 20px;
+ list-style: none;
+ margin-bottom: 0;
+ align-items: center;
+ justify-content: center;
+ margin-top: var(--padding);
+}
+
+/* some sections do not need space between them and menu */
+#nsMain, #nsRelease, #vpReleaseNotes, .playBtnContainer {
+ margin-top: 0 !important;
+}
+
+.contentMenu li {
+ opacity: 0.6;
+ margin: 0 26px;
+ cursor: pointer;
+ font-weight: 700;
+ text-align: center;
+ height: fit-content;
+ transition: opacity 0.3s ease-in-out;
+}
+
+.contentMenu li:last-child {margin-right: 0px}
+.contentMenu li:first-child {margin-left: 0px}
+
+.contentMenu li:hover {opacity: 0.7}
+
+.contentMenu li[active] {
+ opacity: 1.0;
+ pointer-events: none;
+}
+
+.contentMenu li::after {
+ top: 10px;
+ width: 30px;
+ height: 5px;
+ opacity: 0.0;
+ content: " ";
+ display: block;
+ text-align: center;
+ position: relative;
border-radius: 50px;
+ background: var(--red);
+ left: calc(50% - 15px);
transition: 0.2s ease-in-out;
- padding: calc(var(--padding) / 3) var(--padding);
}
-#welcome {padding: 0px}
+.contentMenu li[active]::after {
+ top: 5px;
+ opacity: 1.0;
+}
-button {
- color: var(--btnforeground);
- -webkit-app-region: no-drag;
- margin-bottom: calc(var(--padding) / 1.5);
+.section {
+ opacity: 1.0;
+ position: fixed;
+ right: calc(var(--padding) * 2);
+ left: calc(100px + var(--padding));
+ transition: opacity 0.15s ease-in-out;
}
-button:hover {opacity: 0.9}
-button:active {
- opacity: 0.7;
- transform: scale(0.95);
+.section.hidden {
+ opacity: 0.0;
+ pointer-events: none;
}
+.contentBody img {max-width: 100%}
+.contentBody .img {text-align: center}
-#setpath {background: #5E81AC}
-#vanilla, #exit {background: #656E7F}
-#updateBtn, #installmod {background: var(--blue)}
-#togglemod, #toggleall {background: var(--yellow)}
+.contentBody .section > :first-child:not(.img) {
+ margin-top: 35px;
+}
+
+.contentContainer .playBtnContainer {
+ text-align: center;
+}
+
+.contentContainer .playBtn {
+ width: 27%;
+ height: 11%;
+ border: none;
+ color: white;
+ padding: 20px;
+ font-size: 24px;
+ font-weight: bold;
+ margin-top: 100px;
+ margin-bottom: 10px;
+ border-radius: 10px;
+ background: var(--redbg);
+ transition: 0.3s ease-in-out;
+ filter: drop-shadow(0px 8px 5px rgba(0, 0, 0, 0.1));
+}
+
+.contentContainer .playBtn:hover {
+ transform: scale(1.05);
+ filter: drop-shadow(0px 5px 15px rgba(0, 0, 0, 0.3)) brightness(110%);
+}
+
+.contentContainer .playBtn:active {
+ opacity: 0.7;transform: scale(0.98);
+ filter: drop-shadow(0px 5px 10px rgba(0, 0, 0, 0.4));
+}
+
+.contentContainer #nsMain .playBtn {
+ background: var(--bluebg);
+}
+
+a {
+ color: var(--red);
+ text-decoration: none;
+ transition: filter 0.2s ease-in;
+}
+
+a:hover {
+ filter: brightness(80%);
+}
+
+#nsContent .contentMenu {
+ margin-bottom: 0;
+}
+
+.contentBody .img img {
+ transform: scale(0.85);
+}
+
+.contentBody .img {
+ width: 100%;
+ text-align: center;
+}
+
+#nsRelease, #vpReleaseNotes {
+ height: 80vh;
+ overflow-y: scroll;
+ flex-direction: column;
+ margin-top: 10px !important;
+}
+
+.inline * {
+ display: inline-block;
+}
+
+#vpMain {
+ margin-top: 140px;
+ text-align: center;
+}
+
+#vpMain img {
+ width: 20%;
+}
+
+#vpVersion {
+ font-size: 16px;
+}
+
+.simplebar-scrollbar:before {
+ background: var(--red) !important;
+}
+
+#installmod {background: var(--blue)}
+#togglemod, #toggleall {background: var(--orange)}
#northstar, #removeall, #removemod {background: var(--red)}
-button:disabled {background: var(--disabled) !important; opacity: 0.5}
+button:disabled {
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+code {
+ font-size: 16px;
+ padding: 2px 5px;
+ border-radius: 3px;
+ background-color: #00000070;
+}
+
+#nsMods .line {
+ display: flex;
+ align-items: center;
+ margin-top: calc(var(--padding) / 2);
+}
+
+#modsdiv {
+ height: 50vh;
+ border-radius: 5px;
+ background: var(--bg);
+ backdrop-filter: blur(15px);
+ padding: calc(var(--padding) / 4);
+}
+
+#modsdiv .mod {
+ display: flex;
+ border-radius: 5px;
+ transition: 0.1s ease-in-out;
+ margin: calc(var(--padding) / 3);
+ padding: calc(var(--padding) / 3);
+}
+
+#modsdiv .mod.selected {
+ background: var(--selbg);
+}
+
+#modsdiv .mod .disabled, .modbtns {
+ margin-left: auto;
+}
+
+.modbtns button {
+ margin-left: calc(var(--padding) / 3);
+}
+
+/* drag control */
+
+#bgHolder {
+ user-select: none;
+ -webkit-app-region: drag;
+}
+
+a, button, .contentMenu, #close, #nsRelease, #vpReleaseNotes, .mod {
+ -webkit-app-region: no-drag;
+}
diff --git a/src/app/main.js b/src/app/main.js
index c365cf4..893572a 100644
--- a/src/app/main.js
+++ b/src/app/main.js
@@ -1,6 +1,6 @@
const fs = require("fs");
const path = require("path");
-const { ipcRenderer } = require("electron");
+const { ipcRenderer, shell } = require("electron");
const lang = require("../lang");
let shouldInstallNorthstar = false;
@@ -36,10 +36,9 @@ if (fs.existsSync("viper.json")) {
function exit() {ipcRenderer.send("exit")}
function update() {ipcRenderer.send("update")}
-/**
- * Reports to the main thread about game path status.
- * @param {boolean} value is game path loaded
- */
+// Reports to the main process about game path status.
+// @param {boolean} value is game path loaded
+
function setpath(value = false) {
ipcRenderer.send("setpath", value);
}
@@ -56,16 +55,26 @@ function launchVanilla() {ipcRenderer.send("launchVanilla")}
function log(msg) {
console.log(msg);
- welcome.innerHTML = msg;
+ // welcome.innerHTML = msg;
}
function setButtons(state) {
- let buttons = document.querySelectorAll("button");
+ playNsBtn.disabled = !state;
+}
- for (let i = 0; i < buttons.length; i++) {
- buttons[i].disabled = !state;
+ipcRenderer.on("ns-update-event", (event, key) => {
+ document.getElementById("update").innerText = `(${lang(key)})`;
+ console.log(key);
+ switch(key) {
+ case "cli.update.uptodate.short":
+ setButtons(true);
+ playNsBtn.innerText = lang("gui.launch");
+ break;
+ default:
+ setButtons(false);
+ break;
}
-}
+});
let lastselected = "";
function select(entry) {
@@ -100,7 +109,12 @@ function selected(all) {
return {
remove: () => {
- if (selected == "allmods") {
+
+ if (selected.match(/^Northstar\./)) {
+ if (! confirm(lang("gui.mods.required.confirm"))) {
+ return;
+ }
+ } else if (selected == "allmods") {
if (! confirm(lang("gui.mods.removeall.confirm"))) {
return;
}
@@ -109,6 +123,16 @@ function selected(all) {
ipcRenderer.send("removemod", selected)
},
toggle: () => {
+ if (selected.match(/^Northstar\./)) {
+ if (! confirm(lang("gui.mods.required.confirm"))) {
+ return;
+ }
+ } else if (selected == "allmods") {
+ if (! confirm(lang("gui.mods.toggleall.confirm"))) {
+ return;
+ }
+ }
+
ipcRenderer.send("togglemod", selected)
}
}
@@ -118,13 +142,6 @@ function installmod() {
ipcRenderer.send("installmod")
}
-ipcRenderer.on("ns-updated", () => {
- setButtons(true);
- northstar.disabled = false;
- updateBtn.innerText = lang("gui.update");
-})
-ipcRenderer.on("ns-updating", () => {setButtons(false)})
-
ipcRenderer.on("newpath", (event, newpath) => {
settings.gamepath = newpath;
})
@@ -153,8 +170,9 @@ ipcRenderer.on("mods", (event, mods) => {
})
ipcRenderer.on("version", (event, versions) => {
- vpversion.innerText = lang("gui.versions.viper") + ": " + versions.vp;
- nsversion.innerText = lang("gui.versions.northstar") + ": " + versions.ns;
+ vpversion.innerText = versions.vp;
+ nsversion.innerText = versions.ns;
+ tf2Version.innerText = versions.tf2;
if (versions.ns == "unknown") {
let buttons = document.querySelectorAll(".modbtns button");
@@ -164,9 +182,8 @@ ipcRenderer.on("version", (event, versions) => {
}
// Since Northstar is not installed, we cannot launch it
- northstar.disabled = true;
shouldInstallNorthstar = true;
- updateBtn.innerText = lang("gui.installnorthstar");
+ playNsBtn.innerText = lang("gui.installnorthstar");
}
}); ipcRenderer.send("getversion");
@@ -187,6 +204,10 @@ ipcRenderer.on("wrongpath", () => {
});
setlang();
-setInterval(() => {
- ipcRenderer.send("setsize", document.querySelector(".lines").offsetHeight + 20);
-}, 150);
+
+document.body.addEventListener("click", event => {
+ if (event.target.tagName.toLowerCase() === "a" && event.target.protocol != "file:") {
+ event.preventDefault();
+ shell.openExternal(event.target.href);
+ }
+});
diff --git a/src/app/roboto.ttf b/src/app/roboto.ttf
deleted file mode 100644
index 900fce6..0000000
--- a/src/app/roboto.ttf
+++ /dev/null
Binary files differ
diff --git a/src/assets/bg/northstar.jpg b/src/assets/bg/northstar.jpg
new file mode 100644
index 0000000..01e7e55
--- /dev/null
+++ b/src/assets/bg/northstar.jpg
Binary files differ
diff --git a/src/assets/bg/tf2.jpg b/src/assets/bg/tf2.jpg
new file mode 100644
index 0000000..b6e8f2f
--- /dev/null
+++ b/src/assets/bg/tf2.jpg
Binary files differ
diff --git a/src/assets/bg/viper.jpg b/src/assets/bg/viper.jpg
new file mode 100644
index 0000000..8b1d5ad
--- /dev/null
+++ b/src/assets/bg/viper.jpg
Binary files differ
diff --git a/src/assets/ns.png b/src/assets/ns.png
new file mode 100644
index 0000000..a3bbf94
--- /dev/null
+++ b/src/assets/ns.png
Binary files differ
diff --git a/src/assets/vanilla.png b/src/assets/vanilla.png
new file mode 100644
index 0000000..a6ed688
--- /dev/null
+++ b/src/assets/vanilla.png
Binary files differ
diff --git a/src/index.js b/src/index.js
index 1b594ad..333b1c9 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,23 +1,24 @@
const fs = require("fs");
const path = require("path");
const { autoUpdater } = require("electron-updater");
-const { app, ipcMain, BrowserWindow } = require("electron");
+const { app, ipcMain, BrowserWindow, dialog } = require("electron");
const Emitter = require("events");
const events = new Emitter();
const utils = require("./utils");
const cli = require("./cli");
+const requests = require("./requests");
function start() {
- let width = 600;
win = new BrowserWindow({
- width: width,
- height: 115,
+ width: 1000,
+ height: 600,
show: false,
title: "Viper",
resizable: false,
titleBarStyle: "hidden",
+ frame: false,
icon: path.join(__dirname, "assets/icons/512x512.png"),
webPreferences: {
nodeIntegration: true,
@@ -31,17 +32,12 @@ function start() {
win.loadFile(__dirname + "/app/index.html");
ipcMain.on("exit", () => {process.exit(0)})
- ipcMain.on("setsize", (event, height) => {
- win.setSize(width, height);
- })
-
- ipcMain.on("ns-updated", () => {win.webContents.send("ns-updated")})
- ipcMain.on("ns-updating", () => {win.webContents.send("ns-updating")})
- ipcMain.on("winLog", (event, ...args) => {win.webContents.send("log", ...args)})
- ipcMain.on("winAlert", (event, ...args) => {win.webContents.send("alert", ...args)})
- ipcMain.on("guigetmods", (event, ...args) => {win.webContents.send("mods", utils.mods.list())})
+ ipcMain.on("winLog", (event, ...args) => {win.webContents.send("log", ...args)});
+ ipcMain.on("winAlert", (event, ...args) => {win.webContents.send("alert", ...args)});
+ ipcMain.on("ns-update-event", (event) => win.webContents.send("ns-update-event", event));
+ ipcMain.on("guigetmods", (event, ...args) => {win.webContents.send("mods", utils.mods.list())});
- win.webContents.once("dom-ready", () => {
+ win.webContents.on("dom-ready", () => {
win.webContents.send("mods", utils.mods.list());
});
@@ -99,6 +95,7 @@ ipcMain.on("newpath", (event, newpath) => {
function _sendVersionsInfo() {
win.webContents.send("version", {
ns: utils.getNSVersion(),
+ tf2: utils.getTF2Version(),
vp: "v" + require("../package.json").version
});
}
@@ -149,3 +146,10 @@ if (cli.hasArgs()) {
start();
})
}
+
+ipcMain.on("get-ns-notes", async () => {
+ win.webContents.send("ns-notes", await requests.getNsReleaseNotes());
+});
+ipcMain.on("get-vp-notes", async () => {
+ win.webContents.send("vp-notes", await requests.getVpReleaseNotes());
+});
diff --git a/src/lang/en.json b/src/lang/en.json
index bb5cf09..c2b6f98 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -13,11 +13,12 @@
"cli.setpath.noarg": "No argument provided for --setpath",
"cli.update.current": "Current version:",
- "cli.update.downloading": "Downloading",
+ "cli.update.downloading": "Downloading...",
"cli.update.checking": "Checking for updates...",
"cli.update.downloaddone": "Download done! Extracting...",
"cli.update.finished": "Installation/Update finished!",
"cli.update.uptodate": "Latest version (%s) is already installed, skipping update.",
+ "cli.update.uptodate.short": "Up-to-date",
"cli.autoupdates.checking": "Checking for Northstar updates...",
"cli.autoupdates.available": "Northstar update available!",
@@ -43,6 +44,7 @@
"gui.update": "Update",
"gui.setpath": "Game Path",
+ "gui.update.check": "Check for updates",
"gui.mods": "Mods",
"gui.mods.count": "Mods Installed:",
"gui.mods.disabledtag": "Disabled",
@@ -52,7 +54,9 @@
"gui.mods.remove": "Remove Mod",
"gui.mods.removeall": "Remove All",
"gui.mods.nothingselected": "You've not selected a mod.",
- "gui.mods.removeall.confirm": "Removing all mods will usually require you to reinstall Northstar, are you sure?",
+ "gui.mods.toggleall.confirm": "Toggling all mods could disable mods required for Northstar to function. Are you sure?",
+ "gui.mods.removeall.confirm": "Removing all mods will usually require you to reinstall Northstar. Are you sure?",
+ "gui.mods.required.confirm": "You've selected a core mod, Northstar may not function without it. Are you sure?",
"gui.mods.notamod": "Not a mod!",
"gui.mods.extracting": "Extracting mod...",
"gui.mods.installing": "Installing mod...",
@@ -74,13 +78,25 @@
"gui.selectpath": "Please select the path!",
"gui.gamepath.must": "The game path must be set to start Viper.",
- "gui.gamepath.wrong": "This folder is not a valid game path.",
+ "gui.gamepath.wrong": "This folder is not a valid game path.",
+ "viper.menu.main": "Viper",
+ "viper.menu.release": "Release Notes",
+ "viper.menu.info": "Extras",
+ "viper.menu.info.links": "Links",
+ "viper.menu.info.credits": "Credits",
+
+ "viper.info.discord": "Join Discord:",
+ "viper.info.issues": "Report issues with Viper:",
+
+ "ns.menu.main": "Northstar Launcher",
+ "ns.menu.mods": "Mods",
+ "ns.menu.release": "Release Notes",
- "general.launching": "Launching",
"general.mods.enabled": "Enabled mods:",
"general.mods.disabled": "Disabled mods:",
"general.mods.installed": "Installed mods:",
"general.missingpath": "Game path is not set!",
- "general.notinstalled": "Northstar is not installed!"
+ "general.notinstalled": "Northstar is not installed!",
+ "general.launching": "Launching"
}
diff --git a/src/lang/fr.json b/src/lang/fr.json
index 0eb083c..59a3090 100644
--- a/src/lang/fr.json
+++ b/src/lang/fr.json
@@ -13,11 +13,12 @@
"cli.setpath.noarg": "Aucun argument donné à --setpath",
"cli.update.current": "Version actuelle :",
- "cli.update.downloading": "Téléchargement en cours ",
- "cli.update.checking": "Vérification des mises à jour ...",
+ "cli.update.downloading": "Téléchargement en cours...",
+ "cli.update.checking": "Vérification des mises à jour...",
"cli.update.downloaddone": "Téléchargement terminé ! Extraction des fichiers...",
"cli.update.finished": "Mise à jour terminée !",
"cli.update.uptodate": "La dernière version (%s) est déjà installée.",
+ "cli.update.uptodate.short": "Votre client est à jour",
"cli.autoupdates.checking": "Vérifications des mises à jour de Northstar...",
"cli.autoupdates.available": "Une mise à jour de Northstar est disponible !",
@@ -43,16 +44,19 @@
"gui.update": "Mise à jour",
"gui.setpath": "Chemin du jeu",
+ "gui.update.check": "Vérifier les mises à jour",
"gui.mods": "Mods",
"gui.mods.count": "Mods installés :",
- "gui.mods.disabledtag": "Désactivés",
+ "gui.mods.disabledtag": "Désactivé",
"gui.mods.install": "Installer le mod",
"gui.mods.toggle": "Activer/désactiver le mod",
"gui.mods.toggleall": "Activer/désactiver tous les mods",
"gui.mods.remove": "Supprimer le mod",
"gui.mods.removeall": "Tout supprimer",
"gui.mods.nothingselected": "Aucun mod n'est sélectionné.",
+ "gui.mods.toggleall.confirm": "Cette action pourrait désactiver des mods nécessaires au bon fonctionnement de Northstar. Souhaitez-vous faire cela ?",
"gui.mods.removeall.confirm": "Supprimer tous les mods vous forcera à réinstaller Northstar, souhaitez-vous faire cela ?",
+ "gui.mods.required.confirm": "Vous avez sélectionné un mod de base, Northstar peut ne pas fonctionner sans celui-ci. Souhaitez-vous faire cela ?",
"gui.mods.notamod": "Ceci n'est pas un mod !",
"gui.mods.extracting": "Extraction du mod...",
"gui.mods.installing": "Installation du mod...",
@@ -74,13 +78,25 @@
"gui.selectpath": "Veuillez sélectionner le dossier où se trouve le client Titanfall 2.",
"gui.gamepath.must": "Vous devez sélectionner le chemin du dossier du jeu Titanfall 2 pour pouvoir lancer Viper.",
- "gui.gamepath.wrong": "Ce dossier ne contient pas le jeu Titanfall 2, et n'est donc pas valide.",
+ "gui.gamepath.wrong": "Ce dossier ne contient pas le jeu Titanfall 2, et n'est donc pas valide.",
+ "viper.menu.main": "Viper",
+ "viper.menu.release": "Notes de mises à jour",
+ "viper.menu.info": "Informations",
+ "viper.menu.info.links": "Liens utiles",
+ "viper.menu.info.credits": "Remerciements",
+
+ "viper.info.discord": "Rejoingnez le serveur Discord :",
+ "viper.info.issues": "Un problème avec Viper ? Créez un ticket ici :",
+
+ "ns.menu.main": "Lanceur Northstar",
+ "ns.menu.mods": "Mods",
+ "ns.menu.release": "Notes de mises à jour",
- "general.launching": "Lancement",
"general.mods.enabled": "Mods activés :",
"general.mods.disabled": "Mods désactivés :",
"general.mods.installed": "Mods installés :",
"general.missingpath": "Le chemin du client n'est pas défini !",
- "general.notinstalled": "Northstar n'est pas installé !"
+ "general.notinstalled": "Northstar n'est pas installé !",
+ "general.launching": "Lancement"
}
diff --git a/src/requests.js b/src/requests.js
index 06c5577..5452b0d 100644
--- a/src/requests.js
+++ b/src/requests.js
@@ -7,6 +7,8 @@ const { https } = require("follow-redirects");
// all requests results are stored in this file
const cachePath = path.join(app.getPath("cache"), "requests.json");
const NORTHSTAR_LATEST_RELEASE_KEY = "nsLatestRelease";
+const NORTHSTAR_RELEASE_NOTES_KEY = "nsReleaseNotes";
+const VIPER_RELEASE_NOTES_KEY = "vpReleaseNotes";
function _saveCache(data) {
@@ -30,7 +32,6 @@ async function getLatestNsVersion() {
let cache = _getRequestsCache();
if (cache[NORTHSTAR_LATEST_RELEASE_KEY] && (Date.now() - cache[NORTHSTAR_LATEST_RELEASE_KEY]["time"]) < 5 * 60 * 1000) {
- console.log(`returning ${NORTHSTAR_LATEST_RELEASE_KEY} data from cache`);
resolve( cache[NORTHSTAR_LATEST_RELEASE_KEY]["body"]["tag_name"] );
} else {
https.get({
@@ -70,8 +71,81 @@ function getLatestNsVersionLink() {
return cache[NORTHSTAR_LATEST_RELEASE_KEY]["body"].assets[0].browser_download_url;
}
+async function getNsReleaseNotes() {
+ return new Promise(resolve => {
+ let cache = _getRequestsCache();
+
+ if (cache[NORTHSTAR_RELEASE_NOTES_KEY] && (Date.now() - cache[NORTHSTAR_RELEASE_NOTES_KEY]["time"]) < 5 * 60 * 1000) {
+ resolve( cache[NORTHSTAR_RELEASE_NOTES_KEY]["body"] );
+ } else {
+ https.get({
+ host: "api.github.com",
+ port: 443,
+ path: "/repos/R2Northstar/Northstar/releases",
+ method: "GET",
+ headers: { "User-Agent": "viper" }
+ },
+
+ response => {
+ response.setEncoding("utf8");
+ let responseData = "";
+
+ response.on("data", data => {
+ responseData += data;
+ });
+
+ response.on("end", _ => {
+ cache[NORTHSTAR_RELEASE_NOTES_KEY] = {
+ "time": Date.now(),
+ "body": JSON.parse(responseData)
+ };
+ _saveCache(cache);
+ resolve( cache[NORTHSTAR_RELEASE_NOTES_KEY]["body"] );
+ });
+ });
+ }
+ });
+}
+
+async function getVpReleaseNotes() {
+ return new Promise(resolve => {
+ let cache = _getRequestsCache();
+
+ if (cache[VIPER_RELEASE_NOTES_KEY] && (Date.now() - cache[VIPER_RELEASE_NOTES_KEY]["time"]) < 5 * 60 * 1000) {
+ resolve( cache[VIPER_RELEASE_NOTES_KEY]["body"] );
+ } else {
+ https.get({
+ host: "api.github.com",
+ port: 443,
+ path: "/repos/0negal/viper/releases",
+ method: "GET",
+ headers: { "User-Agent": "viper" }
+ },
+
+ response => {
+ response.setEncoding("utf8");
+ let responseData = "";
+
+ response.on("data", data => {
+ responseData += data;
+ });
+
+ response.on("end", _ => {
+ cache[VIPER_RELEASE_NOTES_KEY] = {
+ "time": Date.now(),
+ "body": JSON.parse(responseData)
+ };
+ _saveCache(cache);
+ resolve( cache[VIPER_RELEASE_NOTES_KEY]["body"] );
+ });
+ });
+ }
+ });
+}
module.exports = {
getLatestNsVersion,
- getLatestNsVersionLink
+ getLatestNsVersionLink,
+ getNsReleaseNotes,
+ getVpReleaseNotes
};
diff --git a/src/utils.js b/src/utils.js
index 87499ae..17091b4 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -136,6 +136,21 @@ function getNSVersion() {
}
}
+
+/**
+ * Loads up Titanfall|2 version from gameversion.txt file.
+ * TODO This file is present on Origin install, should check if it's present with
+ * Steam install as well.
+ */
+function getTF2Version() {
+ var versionFilePath = path.join(settings.gamepath, "gameversion.txt");
+ if (fs.existsSync(versionFilePath)) {
+ return fs.readFileSync(versionFilePath, "utf8");
+ } else {
+ return "unknown";
+ }
+}
+
async function update() {
for (let i = 0; i < settings.excludes.length; i++) {
let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
@@ -144,14 +159,14 @@ async function update() {
}
}
- ipcMain.emit("ns-updating");
+ ipcMain.emit("ns-update-event", "cli.update.checking");
console.log(lang("cli.update.checking"));
var version = getNSVersion();
const latestAvailableVersion = await requests.getLatestNsVersion();
if (version === latestAvailableVersion) {
- ipcMain.emit("ns-updated");
+ ipcMain.emit("ns-update-event", "cli.update.uptodate.short");
console.log(lang("cli.update.uptodate"), version);
winLog(lang("gui.update.uptodate"));
@@ -159,9 +174,9 @@ async function update() {
} else {
if (version != "unknown") {
console.log(lang("cli.update.current"), version);
- }; console.log(lang("cli.update.downloading") + ":", latestAvailableVersion);
-
- winLog(lang("gui.update.downloading"));
+ };
+ console.log(lang("cli.update.downloading") + ":", latestAvailableVersion);
+ ipcMain.emit("ns-update-event", "cli.update.downloading");
}
https.get(requests.getLatestNsVersionLink(), (res) => {
@@ -171,17 +186,18 @@ async function update() {
let received = 0;
res.on("data", (chunk) => {
received += chunk.length;
- winLog(lang("gui.update.downloading") + " " + (received / 1024 / 1024).toFixed(1) + "mb");
+ ipcMain.emit("ns-update-event", lang("gui.update.downloading") + " " + (received / 1024 / 1024).toFixed(1) + "mb");
})
stream.on("finish", () => {
stream.close();
winLog(lang("gui.update.extracting"));
+ ipcMain.emit("ns-update-event", "gui.update.extracting");
console.log(lang("cli.update.downloaddone"));
fs.createReadStream(settings.zip).pipe(unzip.Extract({path: settings.gamepath}))
.on("finish", () => {
- fs.writeFileSync(path.join(settings.gamepath, "ns_version.txt"), latestAvailableVersion);
- ipcMain.emit("getversion");
+ fs.writeFileSync(path.join(settings.gamepath, "ns_version.txt"), latestAvailableVersion);
+ ipcMain.emit("getversion");
for (let i = 0; i < settings.excludes.length; i++) {
let exclude = path.join(settings.gamepath + "/" + settings.excludes[i]);
@@ -190,11 +206,11 @@ async function update() {
}
}
- ipcMain.emit("guigetmods");
- ipcMain.emit("ns-updated");
- winLog(lang("gui.update.finished"));
- console.log(lang("cli.update.finished"));
- cli.exit();
+ ipcMain.emit("guigetmods");
+ ipcMain.emit("ns-update-event", "cli.update.uptodate.short");
+ winLog(lang("gui.update.finished"));
+ console.log(lang("cli.update.finished"));
+ cli.exit();
})
})
})
@@ -487,6 +503,7 @@ module.exports = {
updatevp,
settings,
getNSVersion,
+ getTF2Version,
isGameRunning,
setlang: (lang) => {
settings.lang = lang;