OSDN Git Service

v1.7.6
authorAoichaan0513 <aoichaan0513@gmail.com>
Sat, 1 Jun 2019 13:19:13 +0000 (22:19 +0900)
committerAoichaan0513 <aoichaan0513@gmail.com>
Sat, 1 Jun 2019 13:19:13 +0000 (22:19 +0900)
・自動アップデートに対応
・スタートページの改善
・URLバーをクリックですべて選択するように修正
・その他バグ・不具合の修正

24 files changed:
app/electron/AdBlocker.js
app/electron/Application.js
app/electron/Preload.js
app/electron/WindowManager.js
app/package.json
app/pages/bookmarks.html
app/pages/home.html
app/pages/settings.html
app/src/BrowserWindow.js
app/src/Components/Toolbar.jsx
app/src/Components/ToolbarButton.jsx
app/src/Components/ToolbarTextBox.jsx
app/src/Resources/dark/arrow_downward.svg [new file with mode: 0644]
app/src/Resources/dark/arrow_upward.svg [new file with mode: 0644]
app/src/Resources/inactive/arrow_back.svg [new file with mode: 0644]
app/src/Resources/inactive/arrow_downward.svg [new file with mode: 0644]
app/src/Resources/inactive/arrow_forward.svg [new file with mode: 0644]
app/src/Resources/inactive/arrow_upward.svg [new file with mode: 0644]
app/src/Resources/light/arrow_downward.svg [new file with mode: 0644]
app/src/Resources/light/arrow_upward.svg [new file with mode: 0644]
build-linux.js
build-mac.js
build-win.js
package.json

index 80d69e6..61a2625 100644 (file)
@@ -1,5 +1,5 @@
 const { app } = require('electron');
-const { FiltersEngine } = require('@cliqz/adblocker');
+const { FiltersEngine, makeRequest } = require('@cliqz/adblocker');
 const Axios = require('axios');
 const fs = require('fs');
 const path = require('path');
@@ -7,6 +7,9 @@ const tldts = require('tldts');
 
 const lists = require('./Lists.json');
 
+const Config = require('electron-store');
+const config = new Config();
+
 let engine;
 
 if (!fs.existsSync(path.join(app.getPath('userData'), 'Files'))) {
@@ -76,6 +79,28 @@ module.exports.isEnabled = () => {
        return engine != undefined;
 }
 
+module.exports.runAdblockService = (window, windowId, id, session) => {
+       session.webRequest.onBeforeRequest({ urls: ['<all_urls>'] }, async (details, callback) => {
+               if (engine && config.get('adBlocker')) {
+                       const { match, redirect } = engine.match(makeRequest({ type: details.resourceType, url: details.url }, tldts.parse));
+
+                       if (match || redirect) {
+                               window.webContents.send(`blocked-ad-${windowId}`, { id });
+
+                               if (redirect) {
+                                       callback({ redirectURL: redirect });
+                               } else {
+                                       callback({ cancel: true });
+                               }
+
+                               return;
+                       }
+               }
+
+               callback({ cancel: false });
+       });
+}
+
 module.exports.removeAds = (url, webContents) => {
        if (engine == undefined) return;
        const { styles, scripts } = engine.getCosmeticsFilters({
index 86e6ec7..6b3f2ce 100644 (file)
@@ -4,6 +4,8 @@ const fs = require('fs');
 const url = require('url');
 const os = require('os');
 
+const { autoUpdater } = require('electron-updater');
+
 const { extensionsMain } = require('electron-extensions');
 const config = require('./Config');
 
@@ -32,17 +34,36 @@ getBaseWindow = (width = 1100, height = 680, minWidth = 320, minHeight = 600, x,
 
 module.exports = class Application {
     loadWindow = () => {
-        // app.disableHardwareAcceleration();
         protocol.registerSchemesAsPrivileged([
             { scheme: protocolStr, privileges: { standard: true, bypassCSP: true, secure: true } },
             { scheme: fileProtocolStr, privileges: { standard: false, bypassCSP: true, secure: true } }
         ]);
 
+        autoUpdater.on('checking-for-update', () => {
+            console.log('Checking for update...')
+        })
+        autoUpdater.on('update-available', (info) => {
+            console.log('Update available.');
+        })
+        autoUpdater.on('update-not-available', (info) => {
+            console.log('Update not available.');
+        })
+        autoUpdater.on('error', (err) => {
+            console.log('Error in auto-updater. ' + err);
+        })
+        autoUpdater.on('download-progress', (progressObj) => {
+            console.log('Download speed: ' + progressObj.bytesPerSecond + ' - Downloaded ' + progressObj.percent + '% (' + progressObj.transferred + "/" + progressObj.total + ')');
+        })
+        autoUpdater.on('update-downloaded', (info) => {
+            console.log('Update downloaded.');
+        });
+
         app.on('ready', () => {
             process.env.GOOGLE_API_KEY = config.googleAPIKey;
-            
+
             session.defaultSession.setUserAgent(session.defaultSession.getUserAgent().replace(/ Electron\/[0-9\.]*/g, ''));
 
+            autoUpdater.checkForUpdatesAndNotify();
             Menu.setApplicationMenu(null);
 
             windowManager.addWindow();
@@ -69,7 +90,7 @@ module.exports = class Application {
             subWindow.setMinimizable(false);
             subWindow.setMaximizable(false);
             const startUrl = process.env.ELECTRON_START_URL || url.format({
-                pathname: path.join(__dirname, '/../build/index.html'), // 警告:このファイルを移動する場合ここの相対パスの指定に注意してください
+                pathname: path.join(__dirname, '/../build/index.html'),
                 protocol: 'file:',
                 slashes: true,
                 hash: '/authentication',
index 7029278..25cd8a7 100644 (file)
@@ -123,6 +123,12 @@ global.getAppVersion = () => {
     return package.version;
 }
 
+global.getAppChannel = () => {
+    if (!(location.protocol !== `${protocolStr}://` || location.protocol !== `${fileProtocolStr}://`)) return;
+
+    return package.flast_channel;
+}
+
 /*
 // ====================================================================== //
 // ====================================================================== //
index b84a0b0..5bfa5ca 100644 (file)
@@ -39,7 +39,7 @@ const config = new Config({
                     url: 'https://search.goo.ne.jp/web.jsp?MT=%s'
                 },
                 {
-                    name: 'Baido',
+                    name: 'Baidu',
                     url: 'https://www.baidu.com/s?wd=%s'
                 },
                 {
@@ -102,11 +102,10 @@ db.apps = new Datastore({
     timestampData: true
 });
 
-const { loadFilters, updateFilters, removeAds } = require('./AdBlocker');
+const { loadFilters, updateFilters, runAdblockService, removeAds } = require('./AdBlocker');
 
 let floatingWindows = [];
 let views = [];
-let tabCount = 0;
 
 getBaseWindow = (width = 1100, height = 680, minWidth = 320, minHeight = 200, x, y, frame = false) => {
     return new BrowserWindow({
@@ -382,15 +381,6 @@ module.exports = class WindowManager {
             this.windows.delete(id);
         });
 
-        /*
-        ['resize', 'move'].forEach(ev => {
-            window.on(ev, () => {
-                config.set('window.isMaximized', window.isMaximized());
-                config.set('window.bounds', window.getBounds());
-            })
-        });
-        */
-
         window.on('close', (e) => {
             delete views[id];
 
@@ -458,14 +448,14 @@ module.exports = class WindowManager {
             for (var i = 0; i < views[id].length; i++) {
                 const url = views[id][i].view.webContents.getURL();
 
-                datas.push({ id: views[id][i].id, title: views[id][i].view.webContents.getTitle(), url: url, icon: this.getFavicon(url) });
+                datas.push({ id: views[id][i].view.webContents.id, title: views[id][i].view.webContents.getTitle(), url: url, icon: this.getFavicon(url) });
             }
             e.sender.send(`browserview-get-${id}`, { views: datas });
         });
 
         ipcMain.on(`browserview-goBack-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     if (webContents.canGoBack())
                         webContents.goBack();
@@ -475,7 +465,7 @@ module.exports = class WindowManager {
 
         ipcMain.on(`browserview-goForward-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     if (webContents.canGoForward())
                         webContents.goForward();
@@ -485,7 +475,7 @@ module.exports = class WindowManager {
 
         ipcMain.on(`browserview-reload-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     webContents.reload();
                 }
@@ -494,7 +484,7 @@ module.exports = class WindowManager {
 
         ipcMain.on(`browserview-stop-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     webContents.stop();
                 }
@@ -503,7 +493,7 @@ module.exports = class WindowManager {
 
         ipcMain.on(`browserview-goHome-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     webContents.loadURL(config.get('homePage.defaultPage'));
                 }
@@ -512,7 +502,7 @@ module.exports = class WindowManager {
 
         ipcMain.on(`browserview-loadURL-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     webContents.loadURL(args.url);
                 }
@@ -521,7 +511,7 @@ module.exports = class WindowManager {
 
         ipcMain.on(`browserview-loadFile-${id}`, (e, args) => {
             views[id].filter(function (view, i) {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let webContents = views[id][i].view.webContents;
                     webContents.loadFile(args.url);
                 }
@@ -530,27 +520,27 @@ module.exports = class WindowManager {
 
         ipcMain.on(`data-bookmark-add-${id}`, (e, args) => {
             views[id].filter((view, i) => {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let v = views[id][i].view;
                     db.bookmarks.insert({ title: v.webContents.getTitle(), url: v.webContents.getURL(), isPrivate: args.isPrivate });
-                    this.updateBookmarkState(id, args.id, v);
+                    this.updateBookmarkState(id, v);
                 }
             });
         });
 
         ipcMain.on(`data-bookmark-remove-${id}`, (e, args) => {
             views[id].filter((view, i) => {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let v = views[id][i].view;
                     db.bookmarks.remove({ url: v.webContents.getURL(), isPrivate: args.isPrivate }, {});
-                    this.updateBookmarkState(id, args.id, v);
+                    this.updateBookmarkState(id, v);
                 }
             });
         });
 
         ipcMain.on(`data-bookmark-has-${id}`, (e, args) => {
             views[id].filter((view, i) => {
-                if (view.id == args.id) {
+                if (view.view.webContents.id == args.id) {
                     let v = views[id][i].view;
                     db.bookmarks.find({ url: v.webContents.getURL(), isPrivate: args.isPrivate }, (err, docs) => {
                         e.sender.send(`data-bookmark-has-${id}`, { isBookmarked: (docs.length > 0 ? true : false) });
@@ -565,20 +555,20 @@ module.exports = class WindowManager {
         return url.startsWith(`${protocolStr}://`) || url.startsWith(`${fileProtocolStr}://`) ? undefined : `https://www.google.com/s2/favicons?domain=${parsed.protocol}//${parsed.hostname}`;
     }
 
-    updateNavigationState = (windowId, id, view) => {
-        const window = this.windows.get(windowId);
-        window.webContents.send(`update-navigation-state-${windowId}`, {
-            id: id,
+    updateNavigationState = (id, view) => {
+        const window = this.windows.get(id);
+        window.webContents.send(`update-navigation-state-${id}`, {
+            id: view.webContents.id,
             canGoBack: view.webContents.canGoBack(),
             canGoForward: view.webContents.canGoForward(),
         });
     }
 
-    updateBookmarkState = (windowId, id, view) => {
-        const window = this.windows.get(windowId);
-        db.bookmarks.find({ url: view.webContents.getURL(), isPrivate: (String(windowId).startsWith('private')) }, (err, docs) => {
+    updateBookmarkState = (id, view) => {
+        const window = this.windows.get(id);
+        db.bookmarks.find({ url: view.webContents.getURL(), isPrivate: (String(id).startsWith('private')) }, (err, docs) => {
             const url = view.webContents.getURL();
-            window.webContents.send(`browserview-load-${windowId}`, { id: id, title: view.webContents.getTitle(), url: url, icon: this.getFavicon(url), isBookmarked: (docs.length > 0 ? true : false) });
+            window.webContents.send(`browserview-load-${id}`, { id: view.webContents.id, title: view.webContents.getTitle(), url: url, icon: this.getFavicon(url), isBookmarked: (docs.length > 0 ? true : false) });
         });
     }
 
@@ -626,18 +616,17 @@ module.exports = class WindowManager {
         view.setAutoResize({ width: true, height: true });
     }
 
-    addView = (windowId, url, isActive) => {
-        if (String(windowId).startsWith('private')) {
-            loadSessionAndProtocolWithPrivateMode(windowId);
+    addView = (id, url, isActive) => {
+        if (String(id).startsWith('private')) {
+            loadSessionAndProtocolWithPrivateMode(id);
         }
 
-        const id = tabCount++;
-        this.addTab(windowId, id, url, isActive);
+        this.addTab(id, url, isActive);
     }
 
     removeView = (windowId, id) => {
         views[windowId].filter((view, i) => {
-            if (view.id == id) {
+            if (view.view.webContents.id == id) {
                 const index = i;
 
                 if (index + 1 < views[windowId].length) {
@@ -655,7 +644,7 @@ module.exports = class WindowManager {
     selectView = (windowId, id) => {
         const window = this.windows.get(windowId);
         views[windowId].filter((view, i) => {
-            if (id == view.id) {
+            if (id == view.view.webContents.id) {
                 window.setBrowserView(views[windowId][i].view);
                 window.setTitle(views[windowId][i].view.webContents.getTitle());
                 window.webContents.send(`browserview-set-${windowId}`, { id: id });
@@ -679,15 +668,13 @@ module.exports = class WindowManager {
         for (var i = 0; i < views[windowId].length; i++) {
             const url = views[windowId][i].view.webContents.getURL();
 
-            datas.push({ id: views[windowId][i].id, title: views[windowId][i].view.webContents.getTitle(), url: url, icon: this.getFavicon(url) });
+            datas.push({ id: views[windowId][i].view.webContents.id, title: views[windowId][i].view.webContents.getTitle(), url: url, icon: this.getFavicon(url) });
         }
         const window = this.windows.get(windowId);
         window.webContents.send(`browserview-get-${windowId}`, { views: datas });
     }
 
-    addTab = (windowId, id, url = config.get('homePage.defaultPage'), isActive = true) => {
-        const window = this.windows.get(windowId);
-
+    addTab = (windowId, url = config.get('homePage.defaultPage'), isActive = true) => {
         const view = new BrowserView({
             webPreferences: {
                 nodeIntegration: false,
@@ -701,6 +688,11 @@ module.exports = class WindowManager {
             }
         });
 
+        const window = this.windows.get(windowId);
+        const id = view.webContents.id;
+
+        runAdblockService(window, windowId, id, view.webContents.session);
+
         view.webContents.on('did-start-loading', () => {
             if (view.isDestroyed()) return;
 
@@ -716,9 +708,14 @@ module.exports = class WindowManager {
             if (view.isDestroyed()) return;
 
             window.setTitle(`${view.webContents.getTitle()} - ${pkg.name}`);
-            this.updateBookmarkState(windowId, id, view);
+            this.updateBookmarkState(windowId, view);
+
+            this.updateNavigationState(windowId, view);
+        });
+        view.webContents.on('did-fail-load', (e, code, description, url, isMainFrame, processId, routingId) => {
+            if (view.isDestroyed()) return;
 
-            this.updateNavigationState(windowId, id, view);
+            dialog.showMessageBox({message: `${code}: ${description}`});
         });
 
         view.webContents.on('did-start-navigation', (e) => {
@@ -729,19 +726,19 @@ module.exports = class WindowManager {
             if (config.get('adBlocker') && !(view.webContents.getURL().startsWith(`${protocolStr}://`) || view.webContents.getURL().startsWith(`${fileProtocolStr}://`)))
                 removeAds(url, view.webContents);
 
-            this.updateNavigationState(windowId, id, view);
+            this.updateNavigationState(windowId, view);
         });
 
         view.webContents.on('page-title-updated', (e) => {
             if (view.isDestroyed()) return;
 
             window.setTitle(`${view.webContents.getTitle()} - ${pkg.name}`);
-            this.updateBookmarkState(windowId, id, view);
+            this.updateBookmarkState(windowId, view);
 
             if (!String(windowId).startsWith('private') && !(view.webContents.getURL().startsWith(`${protocolStr}://`) || view.webContents.getURL().startsWith(`${fileProtocolStr}://`)))
                 db.historys.insert({ title: view.webContents.getTitle(), url: view.webContents.getURL() });
 
-            this.updateNavigationState(windowId, id, view);
+            this.updateNavigationState(windowId, view);
         });
 
         view.webContents.on('page-favicon-updated', (e, favicons) => {
@@ -753,7 +750,7 @@ module.exports = class WindowManager {
                 window.webContents.send(`browserview-load-${windowId}`, { id: id, title: view.webContents.getTitle(), url: url, icon: this.getFavicon(url), isBookmarked: (docs.length > 0 ? true : false) });
             });
 
-            this.updateNavigationState(windowId, id, view);
+            this.updateNavigationState(windowId, view);
         });
 
         view.webContents.on('did-change-theme-color', (e, color) => {
index 8db6437..719f1e7 100644 (file)
@@ -1,7 +1,8 @@
 {
        "name": "Flast",
        "description": "Cross-platform browser based on Chromium.",
-       "version": "1.6.9",
+       "version": "1.7.6",
+       "flast_channel": "Stable",
        "private": true,
        "main": "electron/Starter.js",
        "homepage": "./",
@@ -32,6 +33,7 @@
                "electron-packager": "13.1.1",
                "electron-platform": "^1.2.0",
                "electron-store": "3.2.0",
+               "electron-updater": "^4.0.6",
                "nedb": "^1.8.0",
                "react": "16.8.6",
                "react-dom": "16.8.6",
index 697144b..670663b 100644 (file)
                                     <div class="panel-heading">プライベート ブックマーク</div>
                                     <div class="panel-body">
                                         <div class="table-responsive">
-                                            <table class="table table-striped table-hover table-style" id="privMarkList">
+                                            <table class="table table-striped table-hover table-style" id="privMarksList">
                                                 <thead>
                                                     <tr>
                                                         <th class="table-icon"></th>
                         <div class="panel-heading">ブックマーク</div>
                         <div class="panel-body">
                             <div class="table-responsive">
-                                <table class="table table-striped table-hover table-style" id="markList">
+                                <table class="table table-striped table-hover table-style" id="marksList">
                                     <thead>
                                         <tr>
                                             <th class="table-icon"></th>
             if (navigator.userAgent.indexOf('PrivMode') != -1) {
                 getBookmarks(true).then((data) => {
                     data.forEach((item, i) => {
-                        $('#markList').append(
+                        $('#privMarksList').append(
                             $('<tr></tr>')
                                 .append($('<td class="table-icon"></td>').append($(`<img src="http://www.google.com/s2/favicons?domain=${new URL(item.url).origin}" />`)))
                                 .append($('<td class="table-title"></td>').append($(`<a href="${item.url}"></a>`).text(item.title)))
                     });
                     getBookmarks(false).then((data) => {
                         data.forEach((item, i) => {
-                            $('#markList').append(
+                            $('#marksList').append(
                                 $('<tr></tr>')
                                     .append($('<td class="table-icon"></td>').append($(`<img src="http://www.google.com/s2/favicons?domain=${new URL(item.url).origin}" />`)))
                                     .append($('<td class="table-title"></td>').append($(`<a href="${item.url}"></a>`).text(item.title)))
             } else {
                 getBookmarks(false).then((data) => {
                     data.forEach((item, i) => {
-                        $('#markList').append(
+                        $('#marksList').append(
                             $('<tr></tr>')
                                 .append($('<td class="table-icon"></td>').append($(`<img src="http://www.google.com/s2/favicons?domain=${new URL(item.url).origin}" />`)))
                                 .append($('<td class="table-title"></td>').append($(`<a href="${item.url}"></a>`).text(item.title)))
index a446231..da338db 100644 (file)
                             </div>
                         </div>
                     </div>
-                    <div class="panel panel-default" id="normal">
+                    <div class="panel panel-default">
                         <div class="panel-heading">
-                            最近の履歴
-                            <a href="flast://history" target="_blank" class="text-muted"
+                            アプリ
+                            <a href="flast://bookmarks" target="_blank" class="text-muted"
                                 style="float: right;">すべての履歴を表示</a>
                         </div>
                         <div class="panel-body">
                             <div class="table-responsive">
-                                <table class="table table-striped table-hover table-style" id="historyList">
+                                <table class="table table-striped table-hover table-style" id="appsList">
                                     <thead>
                                         <tr>
                                             <th class="table-icon"></th>
                             </div>
                         </div>
                     </div>
-                    <div class="panel panel-default" id="normal">
+                    <div class="panel panel-default">
                         <div class="panel-heading">
-                            最近の履歴
-                            <a href="flast://history" target="_blank" class="text-muted"
-                                style="float: right;">すべての履歴を表示</a>
+                            最近追加したブックマーク
+                            <a href="flast://bookmarks" target="_blank" class="text-muted"
+                                style="float: right;">すべてのブックマークを表示</a>
                         </div>
                         <div class="panel-body">
                             <div class="table-responsive">
-                                <table class="table table-striped table-hover table-style" id="historyList">
+                                <table class="table table-striped table-hover table-style" id="marksList">
                                     <thead>
                                         <tr>
                                             <th class="table-icon"></th>
                                             <th class="table-title">タイトル</th>
                                             <th class="table-url">URL</th>
-                                            <th class="table-date">閲覧日時</th>
+                                            <th class="table-date">追加日時</th>
                                         </tr>
                                     </thead>
                                     <tbody>
                     v++;
                 });
             });
+            getBookmarks(false).then((data) => {
+                let v = 0;
+                data.forEach((item, i) => {
+                    if (v > 9) return;
+                    $('#marksList').append(
+                        $('<tr></tr>')
+                            .append($('<td class="table-icon"></td>').append($(`<img src="http://www.google.com/s2/favicons?domain=${new URL(item.url).origin}" />`)))
+                            .append($('<td class="table-title"></td>').append($(`<a href="${item.url}"></a>`).text(item.title)))
+                            .append($(`<td class="table-url" title="${item.url}"></td>`).text(item.url))
+                            .append($('<td></td>').text(moment(item.createdAt).format('YYYY/MM/DD HH:mm')))
+                    );
+                    v++;
+                });
+            });
 
-            var now = new Date();
-            var start = new Date(now.getFullYear(), 0, 0);
-            var diff = now - start;
-            var oneDay = 1000 * 60 * 60 * 24;
-            var day = Math.floor(diff / oneDay);
-            if (day > 100 && day) {
-                day = day.toString().slice(1, 3);
-                day = parseInt(day);
-            }
+            if (navigator.userAgent.indexOf('PrivMode') == -1) {
+                var now = new Date();
+                var start = new Date(now.getFullYear(), 0, 0);
+                var diff = now - start;
+                var oneDay = 1000 * 60 * 60 * 24;
+                var day = Math.floor(diff / oneDay);
+                if (day > 100 && day) {
+                    day = day.toString().slice(1, 3);
+                    day = parseInt(day);
+                }
 
-            // Set background image
+                $('.test').css({
+                    'background': `linear-gradient(to bottom, #00000000 65%, #FFF), url(flast-file:///photos/${day}.jpg)`,
+                    'background-repeat': 'no-repeat',
+                    'background-size': 'cover'
+                });
 
-            // Set background image
-            $('.test').css({
-                'background': `linear-gradient(to bottom, #00000000 65%, #FFF), url(flast-file:///photos/${day}.jpg)`,
-                'background-repeat': 'no-repeat', 
-                'background-size': 'cover'
-            });
+                if (navigator.geolocation) {
+                    navigator.geolocation.getCurrentPosition((position) => {
+                        const positionData = position.coords;
 
-            //現在位置の取得ができるかどうか
-            if (navigator.geolocation) {
-                navigator.geolocation.getCurrentPosition((position) => {
-                    const positionData = position.coords;
+                        const lat = positionData.latitude;
+                        const lon = positionData.longitude;
+                        $('.location').text('現在の位置(' + Math.floor(lat * 100) / 100 + ',' + Math.floor(lon * 100) / 100 + ')');
 
-                    const lat = positionData.latitude;
-                    const lon = positionData.longitude;
-                    $('.location').text('現在の位置(' + Math.floor(lat * 100) / 100 + ',' + Math.floor(lon * 100) / 100 + ')');
 
+                        //現在の天気データを呼び出し
+                        $.ajax({
+                            url: 'http://api.openweathermap.org/data/2.5/weather',
+                            dataType: 'jsonp',
+                            data: `lat=${lat}&lon=${lon}&appid=${APIKEY}`,
+                            //天気データ呼び出し成功時の挙動
+                            success: function (data) {
+                                $('.location').text(data.name);
 
-                    //現在の天気データを呼び出し
-                    $.ajax({
-                        url: 'http://api.openweathermap.org/data/2.5/weather',
-                        dataType: 'jsonp',
-                        data: `lat=${lat}&lon=${lon}&appid=${APIKEY}`,
-                        //天気データ呼び出し成功時の挙動
-                        success: function (data) {
-                            console.log(data);
-                            if (data.weather[0].main === "Clear") {
-                                $('body').css('background-image', 'url(Sunny.jpg)');
-                                $('.dayWeather').text("晴れ");
-                            } else if (data.weather[0].main === "Rain") {
-                                $('body').css('background-image', 'url(Rain.jpg)');
-                                $('.dayWeather').text("雨");
-                            } else if (data.weather[0].main === "Clouds") {
-                                $('body').css('background-image', 'url(Cloudy.jpg)');
-                                $('.dayWeather').text("くもり");
-                            } else if (data.weather[0].main === "Snow") {
-                                $('body').css('background-image', 'url(Snowy.jpg)');
-                                $('.dayWeather').text("雪");
+                                if (data.weather[0].main === "Clear") {
+                                    $('body').css('background-image', 'url(Sunny.jpg)');
+                                    $('.dayWeather').text("晴れ");
+                                } else if (data.weather[0].main === "Rain") {
+                                    $('body').css('background-image', 'url(Rain.jpg)');
+                                    $('.dayWeather').text("雨");
+                                } else if (data.weather[0].main === "Clouds") {
+                                    $('body').css('background-image', 'url(Cloudy.jpg)');
+                                    $('.dayWeather').text("くもり");
+                                } else if (data.weather[0].main === "Snow") {
+                                    $('body').css('background-image', 'url(Snowy.jpg)');
+                                    $('.dayWeather').text("雪");
+                                }
+
+                                //各データの表示
+                                $('.nowTemp').text(Math.floor((data.main.temp - 273.15) * 10) / 10);
+                                $('.dayWeatherIcon').attr('src', 'http://openweathermap.org/img/w/' + data.weather[0].icon + '.png ');
                             }
+                        });
+                    }, (error) => {
+                        $('.location').text('東京');
 
-                            //各データの表示
-                            $('.nowTemp').text(Math.floor((data.main.temp - 273.15) * 10) / 10);
-                            $('.dayWeatherIcon').attr('src', 'http://openweathermap.org/img/w/' + data.weather[0].icon + '.png ');
-                        }
+                        TokyoWeather();
                     });
-                }, (error) => {
+                } else {
                     $('.location').text('東京');
 
                     TokyoWeather();
-                });
+                }
             } else {
                 $('.location').text('東京');
 
index fa6d490..22994aa 100644 (file)
                                             <p class="text-muted">
                                                 <script>document.write(getAppDescription());</script><br>
                                                 バージョン:
-                                                <script>document.write(getAppVersion());</script> (Stable)
+                                                <script>document.write(getAppVersion());</script> (<script>document.write(getAppChannel());</script>)
                                                 (73.0.36831.121)
                                             </p>
                                         </p>
                 location.href = '#';
             });
 
-            $('#startPageUrl').on('input', function () {
+            $('#startPageUrl').on('keydown', function (e) {
+                if (e.key != 'Enter') return;
+
                 const text = $(this).val();
 
                 if (isURL(text) && !text.includes('://')) {
                     setStartPage(text);
+                    $(this).val(text);
                     $('#startPageIcon').prop('src', `http://www.google.com/s2/favicons?domain=${new URL(getSearchEngine().url).origin}`);
-                } else if (!this.state.barText.includes('://')) {
+                } else if (!text.includes('://')) {
                     setStartPage('flast://home');
-                    $('#startPageIcon').prop('src', `http://www.google.com/s2/favicons?domain=${new URL(getSearchEngine().url).origin}`);
+                    $(this).val('flast://home');
+                    $('#startPageIcon').prop('src', `http://www.google.com/s2/favicons?domain=${new URL('flast://home').origin}`);
                 } else {
                     setStartPage(text);
+                    $(this).val(text);
                     $('#startPageIcon').prop('src', `http://www.google.com/s2/favicons?domain=${new URL(getSearchEngine().url).origin}`);
                 }
             });
 
             $('#adBlock').on('change', function () {
                 setAdBlocker($(this).prop('checked'));
+                location.href = '#';
             });
 
             $('#customTitlebar').on('change', function () {
index 2b3ac59..00a6dc2 100644 (file)
@@ -1,6 +1,5 @@
 import React, { Component } from 'react';
 import { findDOMNode } from 'react-dom';
-import Tooltip from 'react-tooltip';
 import Tippy from '@tippy.js/react';
 
 import Window from './Components/Window';
@@ -13,7 +12,7 @@ import { TabContainer, Tab, TabIcon, TabTitle, TabCloseButton } from './Componen
 import TabButton from './Components/TabButton';
 import TabContent from './Components/TabContent';
 import Toolbar from './Components/Toolbar';
-import ToolbarButton from './Components/ToolbarButton';
+import { ToolbarButton, ToolbarButtonBadge } from './Components/ToolbarButton';
 import ToolbarDivider from './Components/ToolbarDivider';
 import { ToolbarTextBoxWrapper, ToolbarTextBox } from './Components/ToolbarTextBox';
 import BookmarkBar from './Components/BookmarkBar';
@@ -28,8 +27,8 @@ import DarkForwardIcon from './Resources/dark/arrow_forward.svg';
 import LightBackIcon from './Resources/light/arrow_back.svg';
 import LightForwardIcon from './Resources/light/arrow_forward.svg';
 
-import BackInActiveIcon from './Resources/arrow_back_inactive.svg';
-import ForwardInActiveIcon from './Resources/arrow_forward_inactive.svg';
+import BackInActiveIcon from './Resources/inactive/arrow_back.svg';
+import ForwardInActiveIcon from './Resources/inactive/arrow_forward.svg';
 
 import DarkReloadIcon from './Resources/dark/reload.svg';
 import DarkHomeIcon from './Resources/dark/home.svg';
@@ -68,6 +67,11 @@ import DarkCloseIcon from './Resources/dark/close.svg';
 import LightAddIcon from './Resources/light/add.svg';
 import LightCloseIcon from './Resources/light/close.svg';
 
+import 'tippy.js/themes/light.css';
+import 'tippy.js/themes/light-border.css';
+import 'tippy.js/themes/google.css';
+import 'tippy.js/themes/translucent.css';
+
 import isURL from './Utils/isURL';
 
 const protocolStr = 'flast';
@@ -77,6 +81,7 @@ const { remote, ipcRenderer, shell } = window.require('electron');
 const { app, systemPreferences, Menu, MenuItem, dialog } = remote;
 
 const platform = window.require('electron-platform');
+const { parse, format } = window.require('url');
 const path = window.require('path');
 const process = window.require('process');
 
@@ -86,6 +91,9 @@ const config = new Config();
 class BrowserView extends Component {
        constructor(props) {
                super(props);
+
+               this.blockCount = 0;
+
                this.state = {
                        barText: '',
                        findText: '',
@@ -158,6 +166,7 @@ class BrowserView extends Component {
                ipcRenderer.on(`browserview-start-loading-${this.props.windowId}`, (e, args) => {
                        if (args.id == this.props.index) {
                                this.setState({ isLoading: true });
+                               this.blockCount = 0;
                        }
                });
 
@@ -175,6 +184,12 @@ class BrowserView extends Component {
                        }
                });
 
+               ipcRenderer.on(`blocked-ad-${this.props.windowId}`, (e, args) => {
+                       if (args.id == this.props.index) {
+                               this.blockCount++
+                       }
+               });
+
                ipcRenderer.on(`update-navigation-state-${this.props.windowId}`, (e, args) => {
                        if (args.id == this.props.index) {
                                this.setState({ canGoBack: args.canGoBack, canGoForward: args.canGoForward });
@@ -392,18 +407,24 @@ class BrowserView extends Component {
                                        <ToolbarButton isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightHomeIcon, DarkHomeIcon)} size={24}
                                                isShowing={config.get('design.homeButton')} isRight={false} isMarginLeft={false} isEnabled={true} title="ホームページに移動" onClick={() => { this.goHome(); }} />
                                        <ToolbarTextBoxWrapper isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} buttonCount={config.get('design.homeButton') ? 6 : 5}>
-                                               <Tippy content={`このページは${this.state.isTrusted ? '安全です。' : '安全ではありません。'}`} placement="right" arrow={true}>
+                                               <Tippy content={this.state.isTrusted ? (parse(this.state.barText).protocol == 'flast:' ? `保護された ${process.env.npm_package_name} ページを表示しています` : 'このサイトへの接続は保護されています') : 'このサイトへの接続は保護されていません'} theme={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private') ? 'dark' : 'light'} placement="right" arrow={true}>
                                                        <ToolbarButton src={this.state.isTrusted ? this.isDarkModeOrPrivateMode.bind(this, LightSecureIcon, DarkSecureIcon) : this.isDarkModeOrPrivateMode.bind(this, LightInSecureIcon, DarkInSecureIcon)} size={12}
                                                                isShowing={true} isRight={false} isMarginLeft={true} isEnabled={true} title="このページの情報" />
                                                </Tippy>
                                                <ToolbarTextBox value={this.state.barText} onChange={(e) => { this.setState({ barText: e.target.value }); }} onKeyDown={this.handleKeyDown} onClick={(e) => { e.target.select(); }} onContextMenu={this.handleContextMenu} />
-                                               <Tippy ref="markTooltip" content={!this.state.isBookmarked ? `${this.props.windowId.startsWith('private') ? 'プライベート ' : ''}ブックマークから削除しました。` : `${this.props.windowId.startsWith('private') ? 'プライベート ' : ''}ブックマークに追加しました。`} placement="left" arrow={true} trigger="manual">
+                                               <Tippy ref="markTooltip" content={!this.state.isBookmarked ? `${this.props.windowId.startsWith('private') ? 'プライベート ' : ''}ブックマークから削除しました` : `${this.props.windowId.startsWith('private') ? 'プライベート ' : ''}ブックマークに追加しました`} theme={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private') ? 'dark' : 'light'} placement="left" arrow={true} trigger="manual">
                                                        <ToolbarButton isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} src={this.state.isBookmarked ? this.isDarkModeOrPrivateMode.bind(this, LightStarFilledIcon, DarkStarFilledIcon) : this.isDarkModeOrPrivateMode.bind(this, LightStarIcon, DarkStarIcon)} size={12}
                                                                isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={this.state.isBookmarked ? 'ブックマークから削除' : 'ブックマークに追加'} onClick={() => { this.bookMark(); }} />
                                                </Tippy>
                                        </ToolbarTextBoxWrapper>
+                                       {config.get('adBlocker') &&
+                                               <ToolbarButton isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightShieldIcon, DarkShieldIcon)} size={24}
+                                                       isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={`${this.blockCount}個の広告をブロックしました`}>
+                                                       {this.blockCount > 0 && <ToolbarButtonBadge>{this.blockCount}</ToolbarButtonBadge>}
+                                               </ToolbarButton>
+                                       }
                                        <ToolbarButton isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightFeedbackIcon, DarkFeedbackIcon)} size={24}
-                                               isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title="フィードバックの送信" />
+                                               isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title="フィードバックの送信" onClick={() => { this.props.addTab('https://join.slack.com/t/serene-develop/shared_invite/enQtNjQwOTQwOTExMTM5LTg1OTNiNGFkNzU5NDEwYTJmNTY5MDk2MzI2YTU4NmYxZWRlMjMwMGY3MmUzMDM5N2QwZjUyZjNiNTczMjkyNWE'); }} />
                                        <ToolbarDivider isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} />
                                        <ToolbarButton isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} src={this.props.windowId.startsWith('private') ? this.isDarkModeOrPrivateMode.bind(this, LightShieldIcon, DarkShieldIcon) : this.isDarkModeOrPrivateMode.bind(this, LightAccountIcon, DarkAccountIcon)} size={24}
                                                isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={this.props.windowId.startsWith('private') ? 'プライベートモード' : process.env.USERNAME} onClick={() => { this.userMenu(); }} />
index c6bfa1d..186adf9 100644 (file)
@@ -4,6 +4,7 @@ const Toolbar = styled.div`
   width: 100%;
   height: 40px;
   display: flex;
+  align-content: space-around;
   background: ${props => !props.isDarkModeOrPrivateMode ? '#f9f9fa' : '#353535'};
   border-bottom: ${props => !props.isBookmarkBar ? `solid 1px ${!props.isDarkModeOrPrivateMode ? '#e1e1e1' : '#8b8b8b'}` : 'none'};
   box-sizing: border-box;
index b49621e..26cdf01 100644 (file)
@@ -1,6 +1,6 @@
 import styled from 'styled-components';
 
-const ToolbarButton = styled.div`
+export const ToolbarButton = styled.div`
   background-color: initial;
   border: none;
   border-radius: 2px;
@@ -9,6 +9,8 @@ const ToolbarButton = styled.div`
   margin: 5px;
   margin-left: ${props => props.isMarginLeft ? '5px' : '0px'};
   padding: 3px;
+  position: relative;
+  flex-grow: 0;
   display: ${props => props.isShowing ? 'display' : 'none'};
   float: ${props => props.isRight ? 'right' : 'left'};
   background-image: url(${props => props.src});
@@ -17,10 +19,25 @@ const ToolbarButton = styled.div`
   background-repeat: no-repeat;
   transition: 0.2s background-color;
   outline: none;
-  box-sizing: border-box;
   &:hover {
     ${props => props.isEnabled && `background-color: ${!props.isDarkModeOrPrivateMode ? 'rgba(0, 0, 0, 0.06)' : 'rgba(130, 130, 130, 0.3)'};`}
   }
 `;
 
-export default ToolbarButton;
\ No newline at end of file
+export const ToolbarButtonBadge = styled.span`
+  width: 18px;
+  height: 18px;
+  padding: 5px;
+  position: absolute;
+  bottom: 6px;
+  right: 6px;
+  border-radius: 50%;
+  display: inline-block;
+  background-color: #999999;
+  font-size: 0.7em;
+  line-height: 1;
+  box-shadow: 0px 0px 3px #999;
+  text-align: center;
+  transform: translate(50%, 50%);color: white;
+  box-sizing: border-box;
+`;
\ No newline at end of file
index 4678d34..5e0b0c8 100644 (file)
@@ -9,7 +9,8 @@ export const ToolbarTextBoxWrapper = styled.div`
   outline: none;
   color: ${props => !props.isDarkModeOrPrivateMode ? 'black' : 'white'};
   font-size: 14.5px;
-  width: calc((100% - 40px * ${props => props.buttonCount}) - 25px);
+  /* width: calc((100% - 40px * ${props => props.buttonCount}) - 25px); */
+  flex-grow: 4;
   height: auto;
   margin: 5px;
   padding: 0px;
diff --git a/app/src/Resources/dark/arrow_downward.svg b/app/src/Resources/dark/arrow_downward.svg
new file mode 100644 (file)
index 0000000..7a45d20
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ffffff"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/></svg>
\ No newline at end of file
diff --git a/app/src/Resources/dark/arrow_upward.svg b/app/src/Resources/dark/arrow_upward.svg
new file mode 100644 (file)
index 0000000..8f94c4f
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ffffff"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg>
\ No newline at end of file
diff --git a/app/src/Resources/inactive/arrow_back.svg b/app/src/Resources/inactive/arrow_back.svg
new file mode 100644 (file)
index 0000000..3cab962
--- /dev/null
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#999999">
+  <path d="M0 0h24v24H0z" fill="none" />
+  <path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" />
+</svg>
diff --git a/app/src/Resources/inactive/arrow_downward.svg b/app/src/Resources/inactive/arrow_downward.svg
new file mode 100644 (file)
index 0000000..980d1d0
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#999999"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/></svg>
\ No newline at end of file
diff --git a/app/src/Resources/inactive/arrow_forward.svg b/app/src/Resources/inactive/arrow_forward.svg
new file mode 100644 (file)
index 0000000..c41e664
--- /dev/null
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#999999">
+  <path d="M0 0h24v24H0z" fill="none" />
+  <path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z" />
+</svg>
diff --git a/app/src/Resources/inactive/arrow_upward.svg b/app/src/Resources/inactive/arrow_upward.svg
new file mode 100644 (file)
index 0000000..6cb78e9
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#999999"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg>
\ No newline at end of file
diff --git a/app/src/Resources/light/arrow_downward.svg b/app/src/Resources/light/arrow_downward.svg
new file mode 100644 (file)
index 0000000..f27cba0
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/></svg>
\ No newline at end of file
diff --git a/app/src/Resources/light/arrow_upward.svg b/app/src/Resources/light/arrow_upward.svg
new file mode 100644 (file)
index 0000000..e986606
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg>
\ No newline at end of file
index f239bdc..0bcf167 100644 (file)
@@ -1,18 +1,23 @@
 const builder = require('electron-builder');
 const fs = require('fs');
-const packageJson = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
+const pkg = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
 
 builder.build({
     platform: 'linux',
     config: {
-        'appId': `org.aoichaan0513.${packageJson.name}`,
-        'productName': packageJson.name,
-        'copyright': `Copyright 2019 ${packageJson.author.name}. All rights reserved.`,
+        'appId': `org.aoichaan0513.${pkg.name}`,
+        'productName': pkg.name,
+        'copyright': `Copyright 2019 ${pkg.author.name}. All rights reserved.`,
         'asar': true,
+        'publish': {
+            'provider': 'generic',
+            'url': `http://aoichaan0513.xyz/flast/${process.platform}/${process.arch}/${pkg.flast_channel}`,
+            'channel': pkg.flast_channel
+        },
         'fileAssociations': [
             {
                 'name': 'Document',
-                'description': packageJson.name,
+                'description': pkg.name,
                 'role': 'Viewer',
                 'ext': 'html'
             }
index d76f64e..fd51685 100644 (file)
@@ -1,18 +1,23 @@
 const builder = require('electron-builder');
 const fs = require('fs');
-const packageJson = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
+const pkg = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
 
 builder.build({
     platform: 'mac',
     config: {
-        'appId': `org.aoichaan0513.${packageJson.name}`,
-        'productName': packageJson.name,
-        'copyright': `Copyright 2019 ${packageJson.author.name}. All rights reserved.`,
+        'appId': `org.aoichaan0513.${pkg.name}`,
+        'productName': pkg.name,
+        'copyright': `Copyright 2019 ${pkg.author.name}. All rights reserved.`,
         'asar': true,
+        'publish': {
+            'provider': 'generic',
+            'url': `http://aoichaan0513.xyz/flast/${process.platform}/${process.arch}/${pkg.flast_channel}`,
+            'channel': pkg.flast_channel
+        },
         'fileAssociations': [
             {
                 'name': 'Document',
-                'description': packageJson.name,
+                'description': pkg.name,
                 'role': 'Viewer',
                 'ext': 'html'
             }
index 349784d..586a4e8 100644 (file)
@@ -1,22 +1,27 @@
 const builder = require('electron-builder');
 const fs = require('fs');
-const packageJson = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
+const pkg = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
 
 builder.build({
     platform: 'win',
     config: {
-        'appId': `org.aoichaan0513.${packageJson.name}`,
-        'productName': packageJson.name,
-        'copyright': `Copyright 2019 ${packageJson.author.name}. All rights reserved.`,
+        'appId': `org.aoichaan0513.${pkg.name}`,
+        'productName': pkg.name,
+        'copyright': `Copyright 2019 ${pkg.author.name}. All rights reserved.`,
         'asar': true,
         'directories': {
             'output': 'dist',
             'buildResources': 'static'
         },
+        'publish': {
+            'provider': 'generic',
+            'url': `http://aoichaan0513.xyz/flast/${process.platform}/${process.arch}/${pkg.flast_channel}`,
+            'channel': pkg.flast_channel
+        },
         'fileAssociations': [
             {
                 'name': 'Document',
-                'description': packageJson.name,
+                'description': pkg.name,
                 'role': 'Viewer',
                 'ext': 'html'
             }
index c031522..db3bf44 100644 (file)
@@ -1,14 +1,17 @@
 {
        "name": "Flast",
        "description": "Cross-platform browser based on Chromium.",
-       "version": "1.6.9",
+       "version": "1.7.6",
+       "flast_channel": "Stable",
        "private": true,
        "author": {
                "name": "Aoichaan0513",
                "email": "aoichaan0513@gmail.com",
                "url": "http://aoichaan0513.xyz"
        },
-       "dependencies": {},
+       "dependencies": {
+               "electron-updater": "^4.0.6"
+       },
        "scripts": {
                "package:win": "node build-win",
                "package:mac": "node build-mac",