Compare commits

...

28 Commits
v0.1 ... master

Author SHA1 Message Date
Damillora 2dba9271a9 fix icon on non-Mac 2017-07-07 14:57:43 +07:00
Damillora 73608d17e1 tweak menu behavior on non-Mac 2017-07-07 14:53:35 +07:00
Damillora 718bae29ab add checks for macOS 2017-07-07 14:44:26 +07:00
Damillora ef12775d84 add million live help 2017-07-04 02:32:21 +07:00
Damillora 18878a20d6 more fix on menus 2017-07-04 02:02:17 +07:00
Damillora 766edbc6c4 fix menu 2017-07-04 01:59:09 +07:00
Damillora f8e0069f77 version bump to 0.3.0 2017-07-04 01:30:22 +07:00
Damillora 8ae84034a8 add file menu for non-mac 2017-07-04 00:25:03 +07:00
Damillora 47a633b65b remove logout from menu 2017-07-04 00:23:45 +07:00
Damillora 03ec4ea171 add project homepage menu in help 2017-07-04 00:19:28 +07:00
Damillora 88445acaee add help menu 2017-07-04 00:16:49 +07:00
Damillora d60baa4da0 handle blur in preference window 2017-07-04 00:07:12 +07:00
Damillora c285f5bee1 just the main window 2017-07-04 00:06:51 +07:00
Damillora 6a53c26cc5 darwin lol 2017-07-04 00:02:52 +07:00
Damillora 74045a0414 burb 2017-07-03 23:58:41 +07:00
Damillora 236c5339ef version bump to 0.3 development 2017-07-03 23:57:04 +07:00
Damillora ed3f79d627 preferences window 2017-07-03 23:56:29 +07:00
Damillora 66a371a0cf add empty preferences windows 2017-07-03 22:55:37 +07:00
Damillora 69d122ea53 add navigation menu and clear cookies function 2017-07-03 19:42:07 +07:00
Damillora 339d65385d menu refactor and addition 2017-07-03 18:55:37 +07:00
Damillora 68a352120d add electron-debug 2017-07-03 18:55:23 +07:00
Damillora 49be67aae6 add reload menu in macOS dock 2017-07-03 16:59:53 +07:00
Damillora 65dccf3729 escape names 2017-07-03 15:16:23 +07:00
Damillora cb91866365 fix package.sh 2017-07-03 15:13:43 +07:00
Damillora 725ee35eef oops version 2017-07-03 15:06:08 +07:00
Damillora 812d1df6bc change app name 2017-07-03 15:05:24 +07:00
Damillora b371589dec make mac app quit on close 2017-07-02 23:21:01 +07:00
Damillora 886fe15abf License 2017-07-02 22:21:22 +07:00
10 changed files with 501 additions and 86 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
node_modules
out
npm-debug.log

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2013-2017 Damillora
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

186
dock.js Normal file
View File

@ -0,0 +1,186 @@
const { app, Menu } = require('electron');
const ipc = require('electron').ipcMain;
const options = {userAgent: 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F27E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36'};
module.exports.navitemplate = function(win){
const template = [
{
label: "Main",
submenu: [
{
label: "My Page",
click(){ win.loadURL("http://imas.gree-apps.net/app/index.php/mypage",options)}
},
{
label: "Eigyo",click() {win.loadURL("http://imas.gree-apps.net/app/index.php/eigyo?from=mypage_main_button",options) }
},
{
label: "Lesson",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/lesson",options)}
},
{
label: "Gasha",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/gasha",options)}
},
{
label: "Event",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/event",options)}
},
{
label: "Live Battle",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/livebattle",options)}
},
{
label: "Theater",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/theater",options)}
}
]
},
{
label: "Card",
submenu: [
{
label: "Deck",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/deck",options)}
},
{
label: "Card Inventory",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/cardinventory",options)}
},
{
label: "Card Folder",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/cardfolder",options)}
},
{
label: "Potential Skill",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/potential_skill",options)}
},
{
label: "Bazaar",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/bazaar",options)}
},
{
label: "Trade",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/trade",options)}
}
]
},
{
label: "Idol",
submenu: [
{
label: "Unit",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/unit",options)}
},
{
label: "Idol List",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/idol",options)}
},
{
label: "Album",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/album",options)}
},
{
label: "Ranking",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/ranking",options)}
},
{
label: "Voice Drama",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/voice_drama/top",options)}
},
{
label: "Audio Room",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/audio_room",options)}
}
]
},
{
label: "Item",
submenu:
[
{
label: "Shop",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/shop",options)}
},
{
label: "Item",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/item",options)}
},
{
label: "Present Box",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/present",options)}
},
{
label: "Exchange",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/exchange",options)}
}
]
},
{
label: "Friend",
submenu: [
{
label: "Friend List",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/friend",options)}
},
{
label: "Lounge",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/lounge",options)}
},
{
label: "Producer Title",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/title",options)}
},
{
label: "Convention Center",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/convention_center",options)}
},
{
label: "Invite",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/invite",options)}
},
{
label: "Wishlist",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/wantlist",options)}
}
]
},
{
label: "Other",
submenu:
[
{
label: "Memories",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/memories",options)}
},
{
label: "Drama Theater",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/short_story",options)}
},
{
label: "My Data",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/mypage/mydata",options)}
},
{
label: "Million Live! Settings",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/config",options)}
},
{
label: "Help",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/help",options)}
},
{
label: "Return to Splash Page",
click() { win.loadURL("http://pf.gree.net/58737",options)}
}
]
}
]
return template;
}
module.exports.setdock = function(win) {
const dockMenu = Menu.buildFromTemplate(module.exports.navitemplate(win))
if(process.platform == 'darwin' ) app.dock.setMenu(dockMenu);
}

110
main.js
View File

@ -1,95 +1,25 @@
const {app, Menu, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
const themenu = require('./menu')
const setdock = require('./dock')
const ipc = require('electron').ipcMain;
require('electron-debug')();
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
const template = [
{
label: 'Edit',
submenu: [
{role: 'undo'},
{role: 'redo'},
{type: 'separator'},
{role: 'cut'},
{role: 'copy'},
{role: 'paste'},
{role: 'pasteandmatchstyle'},
{role: 'delete'},
{role: 'selectall'}
]
},
{
label: 'View',
submenu: [
{role: 'reload'},
{role: 'forcereload'},
{type: 'separator'},
{role: 'resetzoom'},
{role: 'zoomin'},
{role: 'zoomout'},
{type: 'separator'},
{role: 'togglefullscreen'}
]
},
{
role: 'window',
submenu: [
{role: 'minimize'},
{role: 'close'}
]
},
]
if (process.platform === 'darwin') {
template.unshift({
label: app.getName(),
submenu: [
{role: 'about'},
{type: 'separator'},
{role: 'services', submenu: []},
{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'}
]
}
const options = {userAgent: 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F27E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36'};
function createWindow () {
// Create the browser window.
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
win = new BrowserWindow({width: 480, height: 600,icon: path.join(__dirname, 'ic_launcher.png')})
win = new BrowserWindow({width: 480, height: 600,icon: path.join(__dirname, 'icon.png')})
setdock.setdock(win)
if(process.platform == 'darwin') { Menu.setApplicationMenu(themenu(win)); }
else { win.setMenu(themenu(win));
}
// and load the index.html of the app.
win.loadURL('http://pf.gree.net/58737',{userAgent: 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F27E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36'});
win.loadURL('http://pf.gree.net/58737',options);
// Open the DevTools.
// Emitted when the window is closed.
@ -106,11 +36,23 @@ function createWindow () {
// 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', () => {
// On macOS it is common for applications and their menu bar
ipc.on('log-out',function(){
console.log("logging out");
win.webContents.session.clearStorageData({storages: "cookies"});win.loadURL("http://pf.gree.net/58737",options);
});
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})

125
menu.js Normal file
View File

@ -0,0 +1,125 @@
const { app, Menu,shell } = require('electron');
const navi = require('./dock');
const prefman = require('./preferencemanager');
const ipc = require('electron').ipcMain;
const options = {userAgent: 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F27E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36'};
module.exports = function(win){
const template = [
{
label: 'Edit',
submenu: [
{role: 'undo'},
{role: 'redo'},
{type: 'separator'},
{role: 'cut'},
{role: 'copy'},
{role: 'paste'},
{role: 'pasteandmatchstyle'},
{role: 'delete'},
{role: 'selectall'}
]
},
{
label: 'View',
submenu: [
{role: 'reload'},
{role: 'forcereload'},
{type: 'separator'},
{role: 'resetzoom'},
{role: 'zoomin'},
{role: 'zoomout'},
{type: 'separator'},
{role: 'togglefullscreen'}
]
},
{
label: 'Go',
submenu: navi.navitemplate(win)
},
{
role: 'window',
submenu: [
{role: 'minimize'},
{role: 'close'}
]
},
{
label: 'Help',
role: 'help',
submenu: [
{
label: "Million Live! Help",
click() { win.loadURL("http://imas.gree-apps.net/app/index.php/help",options)}
},
{
label: "Project Homepage",
click(){shell.openExternal("https://github.com/Damillora/MillionHopes")}
},
{
label: 'About Million Hopes',
click() {
prefman.showAbout();
},
visible: process.platform !== 'darwin'
}
]
}
]
if (process.platform === 'darwin') {
template.unshift({
label: app.getName(),
submenu: [
{label: 'About Million Hopes',click(){prefman.showAbout()}},
{type: 'separator'},
{label: 'Preferences',click(){prefman.showPreferences()}},
{type: 'separator'},
{role: 'services', submenu: []},
{type: 'separator'},
{role: 'hide'},
{role: 'hideothers'},
{role: 'unhide'},
{type: 'separator'},
{role: 'quit'}
]
})
// Edit menu
template[2].submenu.push(
{type: 'separator'},
{
label: 'Speech',
submenu: [
{role: 'startspeaking'},
{role: 'stopspeaking'}
]
}
)
// Window menu
template[4].submenu = [
{role: 'close'},
{role: 'minimize'},
{role: 'zoom'},
{type: 'separator'},
{role: 'front'}
]
} else
{
template.unshift({
label: "File",
submenu: [
{label: 'Preferences',click(){prefman.showPreferences()}},
{type: 'separator'},
{label: 'Exit', click(){ app.quit() }},
],
visible: process.platform !== 'darwin'
})
}
const themenu = Menu.buildFromTemplate(template);
return themenu;
}

View File

@ -1,9 +1,15 @@
{
"name": "MillionHopes",
"version": "0.1.0",
"productName": "Million Hopes",
"version": "0.3.1",
"description": "A thin wrapper for the game THE IDOLM@STER: Million Live!, using Electron.",
"main": "main.js",
"devDependencies": {
"electron": "^1.6.11"
},
"dependencies": {
"electron-debug": "^1.2.0",
"electron-settings": "^3.1.1",
"photonkit": "^0.1.2"
}
}

View File

@ -1,2 +1,8 @@
# Mac OS X
electron-packager . "MillionHopes" --all --overwrite --icon icon.icns --out out
electron-packager . --all --overwrite --icon icon.icns --out out
cd out
rm *.zip
for f in Million\ Hopes-*
do
zip -r "$f.zip" "$f"
done

41
preferencemanager.js Normal file
View File

@ -0,0 +1,41 @@
const {app, Menu, BrowserWindow} = require('electron')
const url = require('url')
const path = require('path')
let preferencesWindow;
require('electron-debug')();
function showPreferences_int(){
if(!preferencesWindow){
preferencesWindow = new BrowserWindow({width: 800, height: 600})
if (process.platform !== 'darwin') preferencesWindow.setMenu(null);
preferencesWindow.loadURL(url.format({
pathname: path.join(__dirname, 'preferences.html'),
protocol: 'file:',
slashes: true
}))
preferencesWindow.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
preferencesWindow = null
})
preferencesWindow.on('blur',() => {
preferencesWindow.close();
})
}
}
module.exports.showPreferences = function(){
showPreferences_int();
preferencesWindow.webContents.on('did-finish-load', function() {
preferencesWindow.webContents.executeJavaScript("document.getElementById('mh-pane-general').click();");
});
}
module.exports.showAbout = function(){
showPreferences_int();
preferencesWindow.webContents.on('did-finish-load', function() {
preferencesWindow.webContents.executeJavaScript("document.getElementById('mh-pane-about').click();");
});
}

57
preferences.html Normal file
View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<title>Million Hopes Preferences</title>
<!-- Stylesheets -->
<link rel="stylesheet" href="./node_modules/photonkit/dist/css/photon.css">
</head>
<body>
<!-- Wrap your entire app inside .window -->
<div class="window">
<!-- .toolbar-header sits at the top of your app -->
<!-- Your app's content goes inside .window-content -->
<div class="window-content">
<div class="padded-more">
<div class="pane-group">
<div class="pane-sm sidebar">
<nav class="nav-group">
<h5 class="nav-group-title">Preferences</h5>
<a id="mh-pane-general" class="nav-group-item active" onclick="genericpane_click(event,'mh-pref-general')">
General
</a>
<a id="mh-pane-account" class="nav-group-item" onclick="genericpane_click(event,'mh-pref-account')">
Account
</a>
<a id="mh-pane-about" class="nav-group-item" onclick="genericpane_click(event,'mh-pref-about')">
About
</a>
</nav>
</div>
<div class="pane padded-more">
<div id="mh-pref-general" class="mh-prefs">
<h5>General preferences</h5>
There aren't any configurable options currently in this tab.
</div>
<div id="mh-pref-account" class="mh-prefs">
<h5>Log out</h5>
<p>Logs you out of Million Live!</p>
<button class="btn btn-default" id="mh-account-logout">Log out</a>
</div>
<div id="mh-pref-about" class="mh-prefs">
<h5>About</h5>
<h3>Million Hopes <script>document.write(require('electron').remote.app.getVersion())</script></h3>
<i>""</i>
<p>A client for the game THE IDOLM@STER: Million Live!, using Electron.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="preferences.js"></script>
</body>
</html>

29
preferences.js Normal file
View File

@ -0,0 +1,29 @@
const ipc = require('electron').ipcRenderer;
function logout_click(){
ipc.send('log-out');
}
function genericpane_click(evt,prefname){
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("mh-prefs");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("nav-group-item");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("active");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(prefname).style.display = "block";
document.getElementById(prefname.replace("pref","pane")).classList.add("active");
const asyncMsgBtn = document.getElementById('mh-account-logout');
asyncMsgBtn.addEventListener('click', function () {
ipc.send('log-out')
})
}