OSDN Git Service

v1.7.9
authorAoichaan0513 <aoichaan0513@gmail.com>
Sun, 2 Jun 2019 18:38:01 +0000 (03:38 +0900)
committerAoichaan0513 <aoichaan0513@gmail.com>
Sun, 2 Jun 2019 18:38:01 +0000 (03:38 +0900)
・アイコンを変更
・OS側が通知機能に対応している場合、Webページの権限の要求とダウンロード完了のお知らせを通知にて表示
・その他バグ・不具合の修正

14 files changed:
app/electron/Application.js
app/electron/WindowManager.js
app/package.json
app/src/BrowserWindow.js
app/static/app/icon.ico
app/static/app/icon.png
app/static/app/icon_old.ico [new file with mode: 0644]
app/static/app/icon_old.png [new file with mode: 0644]
build-linux.js
build-mac.js
build-win.js
package.json
static/icon.ico
static/icon_old.ico [new file with mode: 0644]

index 6b3f2ce..a79fb45 100644 (file)
@@ -4,6 +4,10 @@ const fs = require('fs');
 const url = require('url');
 const os = require('os');
 
+const pkg = require(`${app.getAppPath()}/package.json`);
+const protocolStr = 'flast';
+const fileProtocolStr = `${protocolStr}-file`;
+
 const { autoUpdater } = require('electron-updater');
 
 const { extensionsMain } = require('electron-extensions');
@@ -12,9 +16,6 @@ const config = require('./Config');
 const WindowManager = require('./WindowManager');
 const windowManager = new WindowManager();
 
-const protocolStr = 'flast';
-const fileProtocolStr = `${protocolStr}-file`;
-
 let loginCallback;
 let mainWindow;
 let subWindow;
@@ -61,6 +62,7 @@ module.exports = class Application {
         app.on('ready', () => {
             process.env.GOOGLE_API_KEY = config.googleAPIKey;
 
+            app.setAppUserModelId(pkg.flast_package_id);
             session.defaultSession.setUserAgent(session.defaultSession.getUserAgent().replace(/ Electron\/[0-9\.]*/g, ''));
 
             autoUpdater.checkForUpdatesAndNotify();
index 5bfa5ca..8a9f15e 100644 (file)
@@ -62,6 +62,7 @@ const config = new Config({
         },
         adBlocker: true,
         window: {
+            isCloseConfirm: true,
             isCustomTitlebar: true,
             isMaximized: false,
             bounds: {
@@ -109,9 +110,9 @@ let views = [];
 
 getBaseWindow = (width = 1100, height = 680, minWidth = 320, minHeight = 200, x, y, frame = false) => {
     return new BrowserWindow({
-        width, height, minWidth, minHeight, x, y, 'titleBarStyle': 'hidden', frame, fullscreenable: true,
+        width, height, minWidth, minHeight, x, y, titleBarStyle: 'hidden', frame, fullscreenable: true,
+        icon: `${__dirname}/static/app/icon.png`,
         show: false,
-        icon: path.join(app.getAppPath(), 'static', 'app', 'icon.png'),
         webPreferences: {
             nodeIntegration: true,
             webviewTag: true,
@@ -186,7 +187,9 @@ loadSessionAndProtocolWithPrivateMode = (windowId) => {
 setPermissionRequestHandler = (ses, isPrivate = false) => {
     if (!isPrivate) {
         ses.setPermissionRequestHandler((webContents, permission, callback) => {
-            db.pageSettings.findOne({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, (err, doc) => {
+            const url = parse(webContents.getURL());
+
+            db.pageSettings.findOne({ origin: `${url.protocol}//${url.hostname}` }, (err, doc) => {
                 if (doc != undefined) {
                     if (permission == 'media' && doc.media != undefined && doc.media > -1)
                         return callback(doc.media === 0);
@@ -203,54 +206,129 @@ setPermissionRequestHandler = (ses, isPrivate = false) => {
                     if (permission == 'openExternal' && doc.openExternal != undefined && doc.openExternal > -1)
                         return callback(doc.openExternal === 0);
                 } else {
+                    if (Notification.isSupported()) {
+                        const notify = new Notification({
+                            title: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+                            body: '詳細はここをクリックしてください。',
+                            silent: true
+                        });
+
+                        notify.show();
+
+                        notify.on('click', (e) => {
+                            dialog.showMessageBox({
+                                type: 'info',
+                                title: '権限の要求',
+                                message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+                                detail: `要求内容: ${permission}`,
+                                checkboxLabel: 'このサイトでは今後も同じ処理をする',
+                                checkboxChecked: false,
+                                noLink: true,
+                                buttons: ['はい / Yes', 'いいえ / No'],
+                                defaultId: 0,
+                                cancelId: 1
+                            }, (res, checked) => {
+                                console.log(res, checked);
+                                if (checked) {
+                                    if (permission == 'media')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, media: res }, { upsert: true });
+                                    if (permission == 'geolocation')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, geolocation: res }, { upsert: true });
+                                    if (permission == 'notifications')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, notifications: res }, { upsert: true });
+                                    if (permission == 'midiSysex')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, midiSysex: res }, { upsert: true });
+                                    if (permission == 'pointerLock')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, pointerLock: res }, { upsert: true });
+                                    if (permission == 'fullscreen')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, fullscreen: res }, { upsert: true });
+                                    if (permission == 'openExternal')
+                                        db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, openExternal: res }, { upsert: true });
+                                }
+                                return callback(res === 0);
+                            });
+                        });
+                        notify.on('close', (e) => {
+                            return callback(false);
+                        });
+                    } else {
+                        dialog.showMessageBox({
+                            type: 'info',
+                            title: '権限の要求',
+                            message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+                            detail: `要求内容: ${permission}`,
+                            checkboxLabel: 'このサイトでは今後も同じ処理をする',
+                            checkboxChecked: false,
+                            noLink: true,
+                            buttons: ['はい / Yes', 'いいえ / No'],
+                            defaultId: 0,
+                            cancelId: 1
+                        }, (res, checked) => {
+                            if (checked) {
+                                if (permission == 'media')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, media: res }, { upsert: true });
+                                if (permission == 'geolocation')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, geolocation: res }, { upsert: true });
+                                if (permission == 'notifications')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, notifications: res }, { upsert: true });
+                                if (permission == 'midiSysex')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, midiSysex: res }, { upsert: true });
+                                if (permission == 'pointerLock')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, pointerLock: res }, { upsert: true });
+                                if (permission == 'fullscreen')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, fullscreen: res }, { upsert: true });
+                                if (permission == 'openExternal')
+                                    db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, openExternal: res }, { upsert: true });
+                            }
+                            return callback(res === 0);
+                        });
+                    }
+                }
+            });
+        });
+    } else {
+        ses.setPermissionRequestHandler((webContents, permission, callback) => {
+            const url = parse(webContents.getURL());
+            if (Notification.isSupported()) {
+                const notify = new Notification({
+                    title: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+                    body: '詳細はここをクリックしてください。(プライベート モード)',
+                    silent: true
+                });
+
+                notify.show();
+
+                notify.on('click', (e) => {
                     dialog.showMessageBox({
                         type: 'info',
                         title: '権限の要求',
-                        message: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname} が権限を要求しています。`,
+                        message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
                         detail: `要求内容: ${permission}`,
-                        checkboxLabel: 'このサイトでは今後も同じ処理をする',
-                        checkboxChecked: false,
                         noLink: true,
-                        buttons: ['Yes', 'No'],
+                        buttons: ['はい / Yes', 'いいえ / No'],
                         defaultId: 0,
                         cancelId: 1
-                    }, (res, checked) => {
-                        console.log(res, checked);
-                        if (checked) {
-                            if (permission == 'media')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, media: res }, { upsert: true });
-                            if (permission == 'geolocation')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, geolocation: res }, { upsert: true });
-                            if (permission == 'notifications')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, notifications: res }, { upsert: true });
-                            if (permission == 'midiSysex')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, midiSysex: res }, { upsert: true });
-                            if (permission == 'pointerLock')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, pointerLock: res }, { upsert: true });
-                            if (permission == 'fullscreen')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, fullscreen: res }, { upsert: true });
-                            if (permission == 'openExternal')
-                                db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, openExternal: res }, { upsert: true });
-                        }
+                    }, (res) => {
                         return callback(res === 0);
                     });
-                }
-            });
-        });
-    } else {
-        ses.setPermissionRequestHandler((webContents, permission, callback) => {
-            dialog.showMessageBox({
-                type: 'info',
-                title: '権限の要求',
-                message: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname} が権限を要求しています。`,
-                detail: `要求内容: ${permission}`,
-                noLink: true,
-                buttons: ['Yes', 'No'],
-                defaultId: 0,
-                cancelId: 1
-            }, (res) => {
-                return callback(res === 0);
-            });
+                });
+                notify.on('close', (e) => {
+                    return callback(false);
+                });
+            } else {
+                dialog.showMessageBox({
+                    type: 'info',
+                    title: '権限の要求',
+                    message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+                    detail: `要求内容: ${permission}`,
+                    noLink: true,
+                    buttons: ['はい / Yes', 'いいえ / No'],
+                    defaultId: 0,
+                    cancelId: 1
+                }, (res) => {
+                    return callback(res === 0);
+                });
+            }
         });
     }
 }
@@ -346,6 +424,8 @@ module.exports = class WindowManager {
             });
 
             config.clear();
+            db.pageSettings.remove({}, { multi: true });
+
             db.historys.remove({}, { multi: true });
             db.downloads.remove({}, { multi: true });
             db.bookmarks.remove({}, { multi: true });
@@ -713,9 +793,9 @@ module.exports = class WindowManager {
             this.updateNavigationState(windowId, view);
         });
         view.webContents.on('did-fail-load', (e, code, description, url, isMainFrame, processId, routingId) => {
-            if (view.isDestroyed()) return;
+            if (view.isDestroyed() || !isMainFrame) return;
 
-            dialog.showMessageBox({message: `${code}: ${description}`});
+            dialog.showMessageBox({ message: `${code}: ${description}` });
         });
 
         view.webContents.on('did-start-navigation', (e) => {
@@ -975,12 +1055,15 @@ module.exports = class WindowManager {
 
         view.webContents.on('before-input-event', (e, input) => {
             if (view.isDestroyed()) return;
+            console.log((input.control || (platform.isDarwin && input.meta)) || input.alt)
+            window.webContents.setIgnoreMenuShortcuts(true);
 
-            if (input.control || (platform.isDarwin && input.meta)) {
-                console.log(input.control, input.alt, input.shift, input.key);
-
+            if (input.control) {
                 if (input.shift && input.key == 'I') {
                     e.preventDefault();
+                    window.webContents.setIgnoreMenuShortcuts(true);
+                    view.webContents.setIgnoreMenuShortcuts(true);
+
                     if (view.webContents.isDevToolsOpened()) {
                         view.webContents.devToolsWebContents.focus();
                     } else {
@@ -988,24 +1071,40 @@ module.exports = class WindowManager {
                     }
                 } else if (input.shift && input.key == 'R') {
                     e.preventDefault();
+                    window.webContents.setIgnoreMenuShortcuts(true);
+                    view.webContents.setIgnoreMenuShortcuts(true);
+
                     view.webContents.reloadIgnoringCache();
                 } else if (input.key == 'T') {
                     e.preventDefault();
-                    this.addView(windowId, config.get('homePage.defaultPage'), true)
+                    window.webContents.setIgnoreMenuShortcuts(true);
+                    // view.webContents.setIgnoreMenuShortcuts(true);
+
+                    console.log('test');
+                    this.addView(windowId, config.get('homePage.defaultPage'), true);
                 }
             } else if (input.alt) {
                 if (input.key == 'ArrowLeft') {
                     e.preventDefault();
+                    // window.webContents.setIgnoreMenuShortcuts(true);
+                    view.webContents.setIgnoreMenuShortcuts(true);
+
                     if (view.webContents.canGoBack())
                         view.webContents.goBack();
                 } else if (input.key == 'ArrowRight') {
                     e.preventDefault();
+                    // window.webContents.setIgnoreMenuShortcuts(true);
+                    view.webContents.setIgnoreMenuShortcuts(true);
+
                     if (view.webContents.canGoForward())
                         view.webContents.goForward();
                 }
             } else {
                 if (input.key == 'F11') {
                     e.preventDefault();
+                    window.webContents.setIgnoreMenuShortcuts(true);
+                    view.webContents.setIgnoreMenuShortcuts(true);
+
                     window.setFullScreen(!window.isFullScreen());
                     this.fixBounds(windowId, (floatingWindows.indexOf(windowId) != -1));
                 }
@@ -1021,6 +1120,14 @@ module.exports = class WindowManager {
 
             item.once('done', (e, state) => {
                 db.downloads.update({ id: str }, { $set: { name: item.getFilename(), url: item.getURL(), type: item.getMimeType(), size: item.getTotalBytes(), path: item.getSavePath(), status: state } });
+
+                if (!Notification.isSupported()) return;
+                const notify = new Notification({
+                    title: 'ダウンロード完了',
+                    body: `${item.getFilename()} のダウンロードが完了しました。`
+                });
+
+                notify.show();
             });
         });
 
index 719f1e7..2a4e3cb 100644 (file)
@@ -1,8 +1,9 @@
 {
        "name": "Flast",
        "description": "Cross-platform browser based on Chromium.",
-       "version": "1.7.6",
+       "version": "1.7.9",
        "flast_channel": "Stable",
+       "flast_package_id": "org.aoichaan0513.Flast",
        "private": true,
        "main": "electron/Starter.js",
        "homepage": "./",
@@ -35,6 +36,7 @@
                "electron-store": "3.2.0",
                "electron-updater": "^4.0.6",
                "nedb": "^1.8.0",
+               "node-notifier": "^5.4.0",
                "react": "16.8.6",
                "react-dom": "16.8.6",
                "react-router": "5.0.0",
index 00a6dc2..b3fe7b2 100644 (file)
@@ -74,12 +74,13 @@ import 'tippy.js/themes/translucent.css';
 
 import isURL from './Utils/isURL';
 
-const protocolStr = 'flast';
-const fileProtocolStr = `${protocolStr}-file`;
-
 const { remote, ipcRenderer, shell } = window.require('electron');
 const { app, systemPreferences, Menu, MenuItem, dialog } = remote;
 
+const pkg = window.require(`${app.getAppPath()}/package.json`);
+const protocolStr = 'flast';
+const fileProtocolStr = `${protocolStr}-file`;
+
 const platform = window.require('electron-platform');
 const { parse, format } = window.require('url');
 const path = window.require('path');
@@ -407,7 +408,7 @@ 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 ? (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}>
+                                               <Tippy content={this.state.isTrusted ? (parse(this.state.barText).protocol == 'flast:' ? `保護された ${pkg.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>
@@ -531,16 +532,25 @@ class BrowserWindow extends Component {
 
        closeWindow = () => {
                if (this.state.tabs.length > 1) {
-                       const dlg = dialog.showMessageBox(remote.getCurrentWindow(), {
-                               type: 'info',
-                               buttons: ['Yes', 'No'],
-                               title: 'アプリ終了確認',
-                               message: `${this.state.tabs.length}個のタブを閉じようとしています。`,
-                               detail: `${this.state.tabs.length}個のタブを閉じてアプリを終了しようとしています。\n複数のタブを閉じてアプリを終了してもよろしいでしょうか?`,
-                               defaultId: 0,
-                               cancelId: 1
-                       });
-                       if (dlg === 0) {
+                       if (config.get('window.isCloseConfirm')) {
+                               dialog.showMessageBox(remote.getCurrentWindow(), {
+                                       type: 'info',
+                                       title: 'アプリ終了確認',
+                                       message: `${this.state.tabs.length}個のタブを閉じようとしています。`,
+                                       detail: `${this.state.tabs.length}個のタブを閉じてアプリを終了しようとしています。\n複数のタブを閉じてアプリを終了してもよろしいでしょうか?`,
+                                       checkboxLabel: '今後は確認しない',
+                                       checkboxChecked: false,
+                                       noLink: true,
+                                       buttons: ['はい / Yes', 'いいえ / No'],
+                                       defaultId: 0,
+                                       cancelId: 1
+                               }, (res, checked) => {
+                                       if (checked)
+                                               config.set('window.isCloseConfirm', false);
+                                       if (res === 0)
+                                               remote.getCurrentWindow().close();
+                               });
+                       } else {
                                remote.getCurrentWindow().close();
                        }
                } else {
index c5fd9ba..b892061 100644 (file)
Binary files a/app/static/app/icon.ico and b/app/static/app/icon.ico differ
index 8ecc01e..34afcbd 100644 (file)
Binary files a/app/static/app/icon.png and b/app/static/app/icon.png differ
diff --git a/app/static/app/icon_old.ico b/app/static/app/icon_old.ico
new file mode 100644 (file)
index 0000000..c5fd9ba
Binary files /dev/null and b/app/static/app/icon_old.ico differ
diff --git a/app/static/app/icon_old.png b/app/static/app/icon_old.png
new file mode 100644 (file)
index 0000000..8ecc01e
Binary files /dev/null and b/app/static/app/icon_old.png differ
index 0bcf167..f5d9b1b 100644 (file)
@@ -5,7 +5,7 @@ const pkg = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
 builder.build({
     platform: 'linux',
     config: {
-        'appId': `org.aoichaan0513.${pkg.name}`,
+        'appId': pkg.flast_package_id,
         'productName': pkg.name,
         'copyright': `Copyright 2019 ${pkg.author.name}. All rights reserved.`,
         'asar': true,
index fd51685..b06ebcb 100644 (file)
@@ -5,7 +5,7 @@ const pkg = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
 builder.build({
     platform: 'mac',
     config: {
-        'appId': `org.aoichaan0513.${pkg.name}`,
+        'appId': pkg.flast_package_id,
         'productName': pkg.name,
         'copyright': `Copyright 2019 ${pkg.author.name}. All rights reserved.`,
         'asar': true,
index 586a4e8..639dcb7 100644 (file)
@@ -5,7 +5,7 @@ const pkg = JSON.parse(fs.readFileSync('./app/package.json', 'utf8'));
 builder.build({
     platform: 'win',
     config: {
-        'appId': `org.aoichaan0513.${pkg.name}`,
+        'appId': pkg.flast_package_id,
         'productName': pkg.name,
         'copyright': `Copyright 2019 ${pkg.author.name}. All rights reserved.`,
         'asar': true,
index db3bf44..99aef5f 100644 (file)
@@ -1,8 +1,9 @@
 {
        "name": "Flast",
        "description": "Cross-platform browser based on Chromium.",
-       "version": "1.7.6",
+       "version": "1.7.9",
        "flast_channel": "Stable",
+       "flast_package_id": "org.aoichaan0513.Flast",
        "private": true,
        "author": {
                "name": "Aoichaan0513",
index c5fd9ba..b892061 100644 (file)
Binary files a/static/icon.ico and b/static/icon.ico differ
diff --git a/static/icon_old.ico b/static/icon_old.ico
new file mode 100644 (file)
index 0000000..c5fd9ba
Binary files /dev/null and b/static/icon_old.ico differ