├── assets ├── icon.icns ├── icon.ico ├── icon.png ├── 256x256.png ├── loading.gif ├── close_white.png ├── exit_black.png ├── exit_white.png ├── fullscreen.png ├── status_bar.png ├── tray_black.png ├── tray_icon.png ├── tray_white.png ├── status_bar@2x.png ├── fullscreen-exit.png ├── settings_black.png ├── settings_white.png ├── tray_exit_black.png ├── tray_exit_white.png ├── tray_unread_black.png ├── tray_unread_white.png ├── tray_settings_black.png ├── tray_settings_white.png └── vertical-align-botto.png ├── .gitignore ├── src ├── handlers │ ├── message.js │ ├── update.js │ └── menu.js ├── common.js ├── windows │ ├── views │ │ ├── splash.html │ │ └── settings.html │ ├── styles │ │ ├── splash.css │ │ └── settings.css │ └── controllers │ │ ├── splash.js │ │ ├── settings.js │ │ ├── app_tray.js │ │ └── wechat.js ├── configuration.js ├── inject │ ├── badge_count.js │ ├── emoji_parser.js │ ├── share_menu.js │ ├── mention_menu.js │ ├── css.js │ ├── chat_historys.js │ ├── preload.js │ └── mini_frame.js ├── common_cn.js ├── common_en.js ├── lib │ └── easyIDB.js └── main.js ├── config.json ├── scripts ├── build-win32.bat ├── build-all.sh ├── tar-all.sh ├── qiniu.sh └── build.sh ├── electronic-wechat.desktop ├── ISSUE_TEMPLATE.md ├── .eslintrc ├── CONTRIBUTING.md ├── CSSSAMPLE.md ├── README.md ├── LICENSE.md ├── .travis.yml ├── package.json ├── .github └── workflows │ └── build.yml ├── CHANGELOG.md └── README_en.md /assets/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/icon.icns -------------------------------------------------------------------------------- /assets/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/icon.ico -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/256x256.png -------------------------------------------------------------------------------- /assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/loading.gif -------------------------------------------------------------------------------- /assets/close_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/close_white.png -------------------------------------------------------------------------------- /assets/exit_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/exit_black.png -------------------------------------------------------------------------------- /assets/exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/exit_white.png -------------------------------------------------------------------------------- /assets/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/fullscreen.png -------------------------------------------------------------------------------- /assets/status_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/status_bar.png -------------------------------------------------------------------------------- /assets/tray_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_black.png -------------------------------------------------------------------------------- /assets/tray_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_icon.png -------------------------------------------------------------------------------- /assets/tray_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_white.png -------------------------------------------------------------------------------- /assets/status_bar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/status_bar@2x.png -------------------------------------------------------------------------------- /assets/fullscreen-exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/fullscreen-exit.png -------------------------------------------------------------------------------- /assets/settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/settings_black.png -------------------------------------------------------------------------------- /assets/settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/settings_white.png -------------------------------------------------------------------------------- /assets/tray_exit_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_exit_black.png -------------------------------------------------------------------------------- /assets/tray_exit_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_exit_white.png -------------------------------------------------------------------------------- /assets/tray_unread_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_unread_black.png -------------------------------------------------------------------------------- /assets/tray_unread_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_unread_white.png -------------------------------------------------------------------------------- /assets/tray_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_settings_black.png -------------------------------------------------------------------------------- /assets/tray_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/tray_settings_white.png -------------------------------------------------------------------------------- /assets/vertical-align-botto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Riceneeder/electronic-wechat/HEAD/assets/vertical-align-botto.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /dist 3 | npm-debug.log* 4 | .idea 5 | install 6 | # Dependency directories 7 | node_modules 8 | 9 | *.sublime-project 10 | *.sublime-workspace 11 | yarn* 12 | package-lock.json -------------------------------------------------------------------------------- /src/handlers/message.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const qs = require('querystring'); 4 | const url = require('url'); 5 | 6 | class MessageHandler { 7 | handleRedirectMessage(origin) { 8 | return qs.parse(url.parse(origin).query).requrl || origin; 9 | } 10 | } 11 | 12 | module.exports = MessageHandler; 13 | -------------------------------------------------------------------------------- /src/common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const AppConfig = require('./configuration'); 4 | 5 | const lan = AppConfig.readSettings('language'); 6 | 7 | let Common; 8 | if (lan === 'zh-CN') { 9 | Common = require('./common_cn'); 10 | } else { 11 | Common = require('./common_en'); 12 | } 13 | 14 | module.exports = Common; 15 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "osx" : { 3 | "title": "Electronic Wechat", 4 | "background": "icon.png", 5 | "icon": "icon.icns", 6 | "icon-size": 80, 7 | "contents": [ 8 | { "x": 438, "y": 344, "type": "link", "path": "/Applications" }, 9 | { "x": 192, "y": 344, "type": "file" } 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /scripts/build-win32.bat: -------------------------------------------------------------------------------- 1 | set PLATFORM=%1% 2 | set ARCH=%2% 3 | set APP_NAME="Electronic WeChat" 4 | 5 | set ignore_list="dist|scripts|\.idea|.*\.md|.*\.yml|node_modules/nodejieba" 6 | 7 | electron-packager . "%APP_NAME%" --platform=%PLATFORM% --arch=%ARCH% --asar --icon=assets\icon.png --overwrite --out=.\dist --ignore=%ignore_list% 8 | -------------------------------------------------------------------------------- /electronic-wechat.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Electronic Wechat 3 | Comment=Unofficial WeChat client built with React, MobX and Electron. 4 | Exec=/opt/electronic-wechat-linux-x64/electronic-wechat %U 5 | Terminal=false 6 | Type=Application 7 | Icon=/opt/electronic-wechat-linux-x64/assets/icon.png 8 | Categories=Network;Utility;Chat; 9 | -------------------------------------------------------------------------------- /scripts/build-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! hash electron-packager 2>/dev/null; then 4 | RED='\033[0;31m' 5 | NC='\033[0m' 6 | echo "${RED}Error${NC}: you need to npm install electron-packager. Aborting." 7 | exit 1 8 | fi 9 | 10 | function build() { 11 | ./scripts/build.sh $@ 12 | } 13 | 14 | build darwin x64 15 | build linux arm64 16 | build linux x64 17 | # build win32 x64 18 | -------------------------------------------------------------------------------- /src/windows/views/splash.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Starting App 8 | 9 | 10 | 11 |
12 | 13 | Starting App 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /scripts/tar-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd dist 4 | 5 | echo 'Start compressing for Mac OS X.' 6 | tar zcf 'mac-osx.tar.gz' 'Electronic WeChat-darwin-x64' 7 | echo 'Compressing for Mac OS X succeed.' 8 | 9 | echo 'Start compressing for Linux x64.' 10 | tar zcf 'linux-x64.tar.gz' 'electronic-wechat-linux-x64' 11 | echo 'Compressing for Linux x64 succeed.' 12 | 13 | echo 'Start compressing for Linux ia32.' 14 | tar zcf 'linux-ia32.tar.gz' 'electronic-wechat-linux-ia32' 15 | echo 'Compressing for Linux ia32 succeed.' 16 | 17 | cd .. 18 | -------------------------------------------------------------------------------- /src/configuration.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function getUserHome() { 4 | return process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME']; 5 | } 6 | 7 | const nconf = require('nconf').file({ 8 | file: `${getUserHome()}/.ew.json`, 9 | }); 10 | 11 | function saveSettings(settingKey, settingValue) { 12 | nconf.set(settingKey, settingValue); 13 | nconf.save(); 14 | } 15 | 16 | function readSettings(settingKey) { 17 | nconf.load(); 18 | return nconf.get(settingKey); 19 | } 20 | 21 | module.exports = { 22 | saveSettings, 23 | readSettings, 24 | }; 25 | -------------------------------------------------------------------------------- /src/inject/badge_count.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Zhongyi on 4/12/16. 3 | */ 4 | 'use strict'; 5 | const { ipcRenderer } = require('electron'); 6 | 7 | class BadgeCount { 8 | static init() { 9 | setInterval(() => { 10 | let count = 0; 11 | $('.icon.web_wechat_reddot_middle').each(function () { 12 | count += parseInt(this.textContent, 10); 13 | }); 14 | if (count > 0) { 15 | ipcRenderer.send('badge-changed', count.toString()); 16 | } else { 17 | ipcRenderer.send('badge-changed', ''); 18 | } 19 | }, 1500); 20 | } 21 | } 22 | 23 | module.exports = BadgeCount; 24 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Description 2 | 3 | First of all, thanks for your attention to open an issue for this project. 4 | Please notice that if you are requesting a **feature**, then you should give a **brief description** of your request. 5 | If you are reporting a **bug**, please **follow the template** below. 6 | A bug report **without detailed information** required will have a **very low priority** and even be **ignored** (closed directly)! 7 | 8 | #### Specifications 9 | 10 | - Version of Electron (run `$ electron --version`): `v0.0.0` 11 | - OS: `` 12 | - Stack trace from the error message (if any) 13 | 14 | ``` 15 | 16 | ``` 17 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb/base", 4 | "rules": { 5 | "strict": "off", 6 | "max-len": "off", 7 | "prefer-template": "warn", 8 | "arrow-body-style": "off", 9 | "no-unused-vars": "warn", 10 | "no-undef": "off", 11 | "array-callback-return": "off", 12 | "no-confusing-arrow": "off", 13 | "consistent-return": "warn", 14 | "no-param-reassign": "off", 15 | "default-case": "off", 16 | "guard-for-in": "off", 17 | "no-restricted-syntax": "off", 18 | "no-underscore-dangle": "off", 19 | "new-cap": "warn", 20 | "no-console": "off", 21 | "global-require": "off", 22 | "class-methods-use-this": "warn" 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Electronic WeChat 2 | 3 | First of all, thanks for contributing to this project. It would be appreciated if you read through this contributing guide. 4 | 5 | ## Issues 6 | 7 | - Check if your issue is already [there](https://github.com/geeeeeeeeek/electronic-wechat/issues). 8 | 9 | - Check if your issue is `Electronic WeChat` related rather than upstream related. 10 | 11 | - Follow the guide in the issue template. 12 | 13 | ## Pull Requests 14 | 15 | PR are always welcomed. It's better if you put up an issue before firing a PR. **Remember**, the smaller your focus, the better chance to get merged. 16 | 17 | ## Be a collaborator! 18 | 19 | If you are excited about the project, and happen to have skills in Angular, Node, Electron, or else. Do not hesitate to contact me. Let's build together! 20 | -------------------------------------------------------------------------------- /CSSSAMPLE.md: -------------------------------------------------------------------------------- 1 | # 自定义CSS的一些例子 2 | 3 | 自定义的CSS会注入到里面一般来说优先级已经比较高了 4 | 如果不生效尝试加!important后缀 5 | 6 | ```css 7 | .test{ 8 | width:100px; 9 | width:100px!important; 10 | } 11 | ``` 12 | 13 | ### 1、添加聊天背景 14 | 15 | ```css 16 | .box{ 17 | background-image:url(file:///home/user/Pictures/welcome.png); 18 | background-size:60%; 19 | background-position:right; 20 | background-repeat:no-repeat; 21 | } 22 | ``` 23 | ![img](http://ww2.sinaimg.cn/large/007eZ24Wly1fx54uu32ymj30s80k7ajk) 24 | 25 | ### 2、改变气泡颜色 26 | 27 | ```css 28 | .bubble.bubble_default{ 29 | background-color: #97c9eb; 30 | } 31 | .bubble.left:after{ 32 | border-right-color: #97c9eb; 33 | } 34 | .bubble.bubble_primary{ 35 | background-color: #fcd3f3; 36 | } 37 | .bubble.bubble_primary.right:after{ 38 | border-left-color: #fcd3f3; 39 | } 40 | ``` 41 | ![img](http://ww2.sinaimg.cn/large/007eZ24Wgy1fx5klcpdq0j30ug0mmmy2) 42 | -------------------------------------------------------------------------------- /scripts/qiniu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "$(uname -s)" in 4 | 5 | Linux*) 6 | wget http://devtools.qiniu.com/qiniu-devtools-linux_amd64-current.tar.gz -O dist/qiniu-devtools.tar.gz 7 | ;; 8 | 9 | Darwin) 10 | wget http://devtools.qiniu.io/qiniu-devtools-darwin_amd64-current.tar.gz -O dist/qiniu-devtools.tar.gz 11 | ;; 12 | 13 | *) 14 | ;; 15 | 16 | esac 17 | 18 | mkdir dist/qiniu-devtools 19 | tar -xvf dist/qiniu-devtools.tar.gz -C dist/qiniu-devtools 20 | rm -rf /tmp/qiniu 21 | mkdir /tmp/qiniu 22 | cp dist/mac-osx.tar.gz /tmp/qiniu 23 | cp dist/linux-x64.tar.gz /tmp/qiniu 24 | cp dist/linux-ia32.tar.gz /tmp/qiniu 25 | 26 | echo '{ 27 | "src": "/tmp/qiniu", 28 | "dest": "qiniu:access_key='$QINIU_ACCESS_KEY'&secret_key='$QINIU_SECRET_KEY'&bucket=flymeos-cancro", 29 | "debug_level": 1 30 | }' > qiniu-config.json 31 | ./dist/qiniu-devtools/qrsync qiniu-config.json 32 | -------------------------------------------------------------------------------- /src/inject/emoji_parser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chenwl on 9/29/16. 3 | */ 4 | 5 | var emojione = require('emojione'); 6 | 7 | // 8 | const emojiSpanRegex = /<\/span>/g; 9 | 10 | function unicodeToString(point) { 11 | const offset = point - 0x10000; 12 | const lead = 0xd800 + (offset >> 10); 13 | const trail = 0xdc00 + (offset & 0x3ff); 14 | return String.fromCharCode(lead, trail); 15 | } 16 | 17 | class EmojiParser { 18 | static emojiSpanToString(str) { 19 | return str.replace(emojiSpanRegex, function(span, emojiHex) { 20 | const point = parseInt(emojiHex, 16); 21 | return unicodeToString(point); 22 | }); 23 | } 24 | 25 | static emojiToImage(str) { 26 | return emojione.unicodeToImage(EmojiParser.emojiSpanToString(str)); 27 | } 28 | } 29 | 30 | module.exports = EmojiParser; 31 | -------------------------------------------------------------------------------- /src/windows/styles/splash.css: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-user-select: none; 3 | cursor: default !important; 4 | -webkit-user-drag: none; 5 | } 6 | body { 7 | overflow: hidden; 8 | margin: 0; 9 | background: #ECEFF1; 10 | } 11 | #splash_container { 12 | margin: 10px 20px; 13 | } 14 | #splash_text { 15 | font-family: sans-serif; 16 | font-size: 40px; 17 | color: #666; 18 | vertical-align: top; 19 | line-height: 100px; 20 | animation: fadein 0.75s ease-out; 21 | } 22 | #splash_loading_img { 23 | width: 100px; 24 | margin: 15px -10px; 25 | display: inline-block; 26 | vertical-align: middle; 27 | animation: increase 0.5s ease-out; 28 | } 29 | @keyframes fadein { 30 | from { 31 | opacity: 0; 32 | } 33 | to { 34 | opacity: 1; 35 | } 36 | } 37 | @keyframes increase { 38 | from { 39 | opacity: 0; 40 | width: 0; 41 | margin: 52px 40px; 42 | } 43 | to { 44 | opacity: 1; 45 | width: 100px; 46 | margin: 15px -10px; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > 本仓库消极更新,但仍接受PR 2 | > 3 | > 使用可能会出现账号被警告甚至被封,请自行斟酌使用,原因见 https://bbs.deepin.org/post/247302 4 | 5 | logo 6 | 7 | # Electronic WeChat 8 | 9 | **Mac OS X 和 Linux 下更好用的微信客户端. 更多功能, 更少bug. 使用[Electron](https://github.com/atom/electron)构建.** 10 | 11 | > 本仓库fork自:[https://github.com/kooritea/electronic-wechat](https://github.com/kooritea/electronic-wechat) 12 | > 13 | > 原仓库:[https://github.com/geeeeeeeeek/wechat-electron](https://github.com/geeeeeeeeek/wechat-electron) 14 | 15 | # What`s new? 16 | 17 | * [X] 利用UOS请求头修复了登陆问题 18 | 19 | ## Arch 用户 20 | 21 | [https://aur.archlinux.org/packages/electronic-wechat-uos-bin](https://aur.archlinux.org/packages/electronic-wechat-uos-bin) 感谢[@Kimiblock](https://github.com/Kimiblock) 22 | 23 | ## 星火用户(已下架) 24 | 25 | 26 | Get it on Spark Store 27 | 28 | 29 | --- 30 | 31 | > 事物繁忙,PR welcome! 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Zhongyi Tong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/windows/controllers/splash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Zhongyi on May 1, 2016 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const path = require('path'); 8 | const { BrowserWindow } = require('electron'); 9 | 10 | const AppConfig = require('../../configuration'); 11 | 12 | const Common = require('../../common');; 13 | 14 | class SplashWindow { 15 | constructor() { 16 | this.splashWindow = new BrowserWindow({ 17 | width: Common.WINDOW_SIZE_LOADING.width, 18 | height: Common.WINDOW_SIZE_LOADING.height, 19 | title: Common.ELECTRONIC_WECHAT, 20 | resizable: false, 21 | center: true, 22 | show: true, 23 | frame: false, 24 | autoHideMenuBar: true, 25 | alwaysOnTop: true, 26 | icon: 'assets/icon.png', 27 | titleBarStyle: 'hidden', 28 | }); 29 | 30 | this.splashWindow.loadURL(`file://${path.join(__dirname, '/../views/splash.html')}`); 31 | this.isShown = false; 32 | } 33 | 34 | show() { 35 | this.splashWindow.show(); 36 | this.isShown = true; 37 | } 38 | 39 | hide() { 40 | this.splashWindow.hide(); 41 | this.isShown = false; 42 | } 43 | } 44 | 45 | module.exports = SplashWindow; 46 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! hash electron-packager 2>/dev/null; then 4 | RED='\033[0;31m' 5 | NC='\033[0m' 6 | echo "${RED}Error${NC}: you need to npm install electron-packager. Aborting." 7 | exit 1 8 | fi 9 | 10 | if [ "$#" -ne 2 ]; then 11 | echo -e "Usage: ./script/build.sh " 12 | echo -e " platform: darwin, linux, win32" 13 | echo -e " arch: ia32, x64" 14 | exit 1 15 | fi 16 | 17 | PLATFORM=$1 18 | ARCH=$2 19 | 20 | echo "Start packaging for $PLATFORM $ARCH." 21 | 22 | if [ $PLATFORM = "linux" ]; then 23 | APP_NAME="electronic-wechat" 24 | else 25 | APP_NAME="Electronic WeChat" 26 | fi 27 | 28 | ignore_list="dist|scripts|\.idea|.*\.md|.*\.yml|node_modules/nodejieba|install" 29 | 30 | electron-packager . "${APP_NAME}" --platform=$PLATFORM --arch=$ARCH --asar --icon=assets/icon.icns --overwrite --out=./dist --ignore=${ignore_list} 31 | 32 | if [ $? -eq 0 ]; then 33 | echo -e "$(tput setaf 2)Packaging for $PLATFORM $ARCH succeeded.$(tput sgr0)\n" 34 | fi 35 | 36 | if [ $PLATFORM = "darwin" ]; then 37 | ditto -rsrcFork ./dist/Electronic\ WeChat-darwin-x64/Electronic\ WeChat.app /Applications/Electronic\ WeChat.app 38 | echo "$(tput setaf 3)App copied to /Applications. You can open Electronic WeChat there or from Spotlight.$(tput sgr0)" 39 | fi 40 | 41 | cp ./electronic-wechat.desktop ./dist/electronic-wechat-linux-$ARCH/ 42 | mkdir ./dist/electronic-wechat-linux-$ARCH/assets 43 | cp ./assets/icon.png ./dist/electronic-wechat-linux-$ARCH/assets/icon.png 44 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: required 3 | node_js: 4 | - '5.2' 5 | branches: 6 | only: 7 | - master 8 | - production 9 | before_script: 10 | - npm install 11 | script: 12 | - ./scripts/build-all.sh 13 | - ./scripts/tar-all.sh 14 | deploy: 15 | provider: releases 16 | api_key: 17 | secure: ETudcaMBembv5mq5WcA0Zu5YCQt02A8sfMIYJ+XN0dTUCFRODYgyk8SiW3ndI4zLfhsc31KbYecSVfcrvYhPlkLucdhD0hY+v4mowrGaG6q3DUE4v9+qATOE5z51MPNTQO/suPNZpeFkSCKaWh6SY9oSd/tsD+YmbcpuD0//DMiFMpYqA8ueQ7yka4SmlZq8C48MsRbULAtyHNEVNJ4en9xdE9vFHZ45kM2A2IWYVikuCa5J6YoL7N2CyIFwtKMeF68d0vwidXUXEc7z1VOHwosG7V0vEfNRrIy4mft0tXyEYe/nM8GlYnirVRCy3xF4h4ssERXbLMuZSYGm+bg/pqReL+dvsN5oKszuo7IseZnE8QfmmhfbMB4dWf8Le5WXfFgJTG28lNvl2VwTTEW4Cj5qeJmfO524GydqRE+i3uQvW4c2tBTFmfpusPnaFqVXTPH7o54hT18hYvgaBvJQv6pyMNMLLXq0BbkzquTTWTwb8lSi8XiRr/fWkQreRZNofJc21ZUSI5YcuqZpzbz1fOLseC4QJ8YXQ9b2OU/LiFF3gvHTK6vSKMQmbOFg0zFXMi5FT1SzCi/mKduax/OR/H6lolVW83eXCG1Ni+sIrwUkp0d/UL6E1pVeJMibBrOEgriWIpD+AiVzNVyBdq/oDC6qG9IXRWzii9Ks6J9zH7k= 18 | file: 19 | - 'dist/mac-osx.tar.gz' 20 | - 'dist/linux-x64.tar.gz' 21 | - 'dist/linux-ia32.tar.gz' 22 | skip_cleanup: true 23 | on: 24 | repo: geeeeeeeeek/electronic-wechat 25 | branch: production 26 | notifications: 27 | webhooks: 28 | urls: 29 | - https://webhooks.gitter.im/e/d6bab2376f47ee992d78 30 | on_success: always # options: [always|never|change] default: always 31 | on_failure: always # options: [always|never|change] default: always 32 | on_start: always # options: [always|never|change] default: always 33 | after_deploy: 34 | - ./scripts/qiniu.sh 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electronic-wechat", 3 | "version": "2.3.2", 4 | "description": "An Electron application for WeChat", 5 | "main": "src/main.js", 6 | "scripts": { 7 | "start": "electron src/main.js", 8 | "build": "./scripts/build-all.sh", 9 | "build:osx": "./scripts/build.sh darwin x64", 10 | "build:osx64": "./scripts/build.sh darwin x64", 11 | "build:linux32": "./scripts/build.sh linux ia32", 12 | "build:linux": "./scripts/build.sh linux x64", 13 | "build:linux64": "./scripts/build.sh linux x64", 14 | "build:linuxarm64": "./scripts/build.sh linux arm64", 15 | "build:win": ".\\scripts\\build-win32.bat win32 ia32", 16 | "build:win32": ".\\scripts\\build-win32.bat win32 ia32", 17 | "build:win64": ".\\scripts\\build-win32.bat win32 x64" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/Riceneeder/electronic-wechat.git", 22 | "originalurl": "https://github.com/geeeeeeeeek/wechat-electron.git" 23 | }, 24 | "keywords": [ 25 | "Electron", 26 | "WeChat", 27 | "微信", 28 | "Web" 29 | ], 30 | "author": { 31 | "name": "Riceneeder", 32 | "originalauthor": "Zhongyi Tong", 33 | "email": "845541909@qq.com" 34 | }, 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/Riceneeder/electronic-wechat/issues", 38 | "originalurl": "https://github.com/geeeeeeeeek/wechat-electron/issues" 39 | }, 40 | "homepage": "https://github.com/Riceneeder/electronic-wechat/", 41 | "originalhomepage": "https://github.com/geeeeeeeeek/wechat-electron/", 42 | "dependencies": { 43 | "electron-localshortcut": "^3.1.0", 44 | "electron-packager": "^16.0.0", 45 | "emojione": "^4.5.0", 46 | "is-xfce": "^2.0.0", 47 | "nconf": "^0.10.0", 48 | "pinyin": "^2.8.0" 49 | }, 50 | "devDependencies": { 51 | "babel-eslint": "^8.2.3", 52 | "electron": "^20.1.4", 53 | "eslint": "^4.19.1", 54 | "eslint-config-airbnb": "^16.1.0", 55 | "eslint-plugin-import": "^2.2.0", 56 | "eslint-plugin-jsx-a11y": "^6.0.3", 57 | "eslint-plugin-react": "^7.7.0" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # main.yml 2 | 3 | # Workflow's name 4 | name: Build 5 | 6 | # Workflow's trigger 7 | on: 8 | push: 9 | tags: 10 | - 'v*.*.*' 11 | 12 | # Workflow's jobs 13 | jobs: 14 | # job's id 15 | release: 16 | # job's name 17 | name: build and release electron app 18 | 19 | # the type of machine to run the job on 20 | runs-on: ${{ matrix.os }} 21 | 22 | # create a build matrix for jobs 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | os: [ubuntu-18.04] 27 | 28 | # create steps 29 | steps: 30 | # step1: check out repository 31 | - name: Check out git repository 32 | uses: actions/checkout@v2 33 | 34 | # step2: install node env 35 | - name: Install Node.js 36 | uses: actions/setup-node@v2-beta 37 | 38 | # step3: npm install 39 | - name: npm install 40 | run: | 41 | npm install -g electron-installer-debian 42 | npm install 43 | # step4: build app 44 | - name: build Ubuntu app 45 | if: matrix.os == 'ubuntu-18.04' 46 | run: | 47 | npm run build:linuxarm64 48 | npm run build:linux 49 | # step5: cleanup artifacts in dist_electron 50 | - name: cleanup artifacts for Ubuntu 51 | if: matrix.os == 'ubuntu-18.04' 52 | run: | 53 | mkdir artifacts 54 | ls 55 | electron-installer-debian --src dist/electronic-wechat-linux-x64/ --dest dist/installers/ --arch amd64 56 | electron-installer-debian --src dist/electronic-wechat-linux-arm64/ --dest dist/installers/ --arch arm64 57 | mv dist/installers/*.deb artifacts || true 58 | # tar -cvf electronic-wechat-linux-arm64.tar dist/electronic-wechat-linux-arm64/ 59 | # tar -cvf electronic-wechat-linux-x64.tar dist/electronic-wechat-linux-x64/ 60 | # mv *.tar artifacts || true 61 | # step6: upload artifacts 62 | - name: upload artifacts 63 | uses: actions/upload-artifact@v2 64 | with: 65 | name: ${{ matrix.os }} 66 | path: artifacts 67 | 68 | # step7: create release 69 | - name: release 70 | uses: softprops/action-gh-release@v1 71 | if: startsWith(github.ref, 'refs/tags/') 72 | with: 73 | files: 'artifacts/**' 74 | env: 75 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 76 | -------------------------------------------------------------------------------- /src/windows/controllers/settings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Ji on 9/15/16. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const path = require('path'); 8 | const { BrowserWindow } = require('electron'); 9 | const electronLocalShortcut = require('electron-localshortcut'); 10 | 11 | const AppConfig = require('../../configuration'); 12 | 13 | const Common = require('../../common');; 14 | 15 | class SettingsWindow { 16 | constructor() { 17 | this.settingsWindow = null; 18 | this.createSettingsWindow(); 19 | } 20 | 21 | createSettingsWindow() { 22 | this.settingsWindow = new BrowserWindow({ 23 | title:Common.ELECTRONIC_SETINGS, 24 | width: Common.WINDOW_SIZE_SETTINGS.width, 25 | height: Common.WINDOW_SIZE_SETTINGS.height * 0.9, 26 | resizable: false, 27 | fullscreenable: false, 28 | show: false, 29 | frame: true, 30 | alwaysOnTop: true, 31 | icon: 'assets/icon.png', 32 | titleBarStyle: 'hidden', 33 | webPreferences: { 34 | nodeIntegration: true, 35 | contextIsolation: false, 36 | enableRemoteModule: true, 37 | }, 38 | }); 39 | 40 | this.initWindowEvents(); 41 | this.initSettingsWindowShortcut(); 42 | 43 | this.settingsWindow.loadURL(`file://${path.join(__dirname, '/../views/settings.html')}`); 44 | } 45 | 46 | initWindowEvents() { 47 | this.settingsWindow.on('close', () => { 48 | this.unregisterLocalShortCut(); 49 | this.settingsWindow = null; 50 | this.isShown = false; 51 | }); 52 | // debug 53 | // this.settingsWindow.once('ready-to-show', () => { 54 | // this.settingsWindow.show(); 55 | // this.settingsWindow.toggleDevTools(); 56 | // }); 57 | } 58 | 59 | show() { 60 | if (!this.settingsWindow) { 61 | this.createSettingsWindow(); 62 | } 63 | this.settingsWindow.show(); 64 | this.isShown = true; 65 | } 66 | 67 | hide() { 68 | this.settingsWindow.hide(); 69 | this.isShown = false; 70 | } 71 | 72 | registerLocalShortcut() { 73 | electronLocalShortcut.register(this.settingsWindow, 'Esc', () => { 74 | this.settingsWindow.close(); 75 | }); 76 | } 77 | 78 | unregisterLocalShortCut() { 79 | electronLocalShortcut.unregisterAll(this.settingsWindow); 80 | } 81 | 82 | initSettingsWindowShortcut() { 83 | this.registerLocalShortcut(); 84 | } 85 | } 86 | 87 | module.exports = SettingsWindow; 88 | -------------------------------------------------------------------------------- /src/inject/share_menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by oBlank on 3/31/16. 3 | */ 4 | 'use strict'; 5 | 6 | class ShareMenu { 7 | static inject() { 8 | const dropdownMenu = $('.reader_menu .dropdown_menu'); 9 | const dropdownMenuItem = $('.reader_menu .dropdown_menu > li'); 10 | if (dropdownMenuItem.length > ShareMenu.shareMenuItemsCount) return; 11 | 12 | ShareMenu.shareMenuItemsCount = dropdownMenuItem.length; 13 | const readItem = angular.element('.reader').scope().readItem; 14 | const menuHTML = ShareMenu.get({ url: readItem.Url, title: readItem.Title }); 15 | dropdownMenu.prepend(menuHTML); 16 | } 17 | 18 | static get(link) { 19 | if (!link.url || !link.title) return ''; 20 | 21 | link.url = encodeURIComponent(link.url); 22 | link.title = encodeURIComponent(link.title); 23 | 24 | const shareTargets = { 25 | weibo: { 26 | url: `http://service.weibo.com/share/share.php?url=${link.url}&title=${link.title}#&searchPic=yes`, 27 | text: '分享到微博', 28 | }, 29 | qzone: { 30 | url: `http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=${link.url}&title=${link.title}&pics=&summary=`, 31 | text: '分享到 QQ 空间', 32 | }, 33 | facebook: { 34 | url: `https://www.facebook.com/sharer/sharer.php?s=100&p%5Btitle%5D=${link.title}&p%5Bsummary%5D=%21&p%5Burl%5D=${link.url}&p%5Bimages%5D=`, 35 | text: '分享到 Facebook', 36 | }, 37 | evernote: { 38 | url: `https://www.evernote.com/clip.action?url=${link.url}&title=${link.title}`, 39 | text: '分享到 Evernote', 40 | }, 41 | twitter: { 42 | url: `https://twitter.com/intent/tweet?text=${link.title}&url=${link.url}&original_referer=`, 43 | text: '分享到 Twitter', 44 | }, 45 | email: { 46 | url: `mailto:?&subject=${link.title}&body=${link.title}%0A${link.url}`, 47 | text: '分享到邮件', 48 | }, 49 | }; 50 | 51 | 52 | let menuItemsTemplate = ''; 53 | for (const target in shareTargets) { 54 | menuItemsTemplate += ShareMenu.genShareMenuItem(shareTargets[target]); 55 | } 56 | 57 | return menuItemsTemplate; 58 | } 59 | 60 | static genShareMenuItem(target) { 61 | return ` 62 |
  • 63 | 64 | 65 | ${target.text} 66 | 67 |
  • 68 | `; 69 | } 70 | } 71 | 72 | ShareMenu.shareMenuItemsCount = 256; 73 | 74 | module.exports = ShareMenu; 75 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | **v2.0 (2017.02.13) CN** 4 | 5 | 1. 升级 **Electron** 至 **V1.4.15**,**Chromium** 至 **54** 6 | 2. 增加了**偏好设置**(感谢设计建议 @**[xiaoyusilen](https://github.com/xiaoyusilen)**) 7 | 3. 增加了英文版本的支持 8 | 4. 增加了一键隐藏窗口(**`ESC`** 键) 9 | 5. 修复了 **macOS** 上窗口最小化时不显示新消息提示的红点(感谢 @wujysh 的贡献) 10 | 6. 修复了聊天框内换行提示仅针对 macOS 的问题 11 | 7. 增加了两个快捷键(感谢 @awmleer 的贡献) 12 | - 搜索联系人:**`Ctrl + F`** 13 | - 切换到全屏模式:**macOS** 下 **`Ctrl + Command + F`**,**Linux** 下为 **`F11`** 14 | 8. 修复了在 Linux 系统下部分菜单按钮失效的问题(感谢 @qzchenwl 的贡献) 15 | 8. 更新了依赖的第三方库的版本至最新兼容版本 16 | 17 | **v2.0 (2017.02.13) EN** 18 | 19 | 1. Update Electron to V1.4.15, Chromium API level 54 20 | 2. Add **Preference Panel** (Thanks for the design advises from @**[xiaoyusilen](https://github.com/xiaoyusilen)**](https://github.com/xiaoyusilen)) 21 | 3. Fully support English UI! 22 | 4. Quick hide windows shortcut (**Press `ESC`**) 23 | 5. Fix **macOS** new message red dot display improperly (Thanks to @wujysh) 24 | 6. Tips in chat window now are adapted with platform 25 | 7. Add two shortcuts (Thanks to @awmleer) 26 | - Search Contact人: **`Ctrl + F`** 27 | - Toggle Fullscreen Mode: **macOS** **`Ctrl + Command + F`**, **Linux** **`F11`** 28 | 8. Fix unfunctional menu items on **Linux** (Thanks to @qzchenwl) 29 | 8. All thrid party libraries are up-to-date 30 | 31 | 32 | **v1.3 (2016.05.19)** 33 | 34 | 1. 升级 electron 至 1.1.0, Chrome 至 50.0.2661.102,Node 至 6.1.0 (感谢 @lfs1102 的贡献) 35 | 2. 新增 `brew cask` 安装方式 (最新可下载版本为 v1.2.0) 36 | 3. 新增 Windows 下的安装脚本 (感谢 @3dseals 的贡献) 37 | 4. 新增 应用启动动画,缩短首次展现时间 38 | 5. 优化 应用启动稳定性,增加超时重试 39 | 6. 优化 主要文案均统一为英文 40 | 7. 优化 减少 20M 应用体积 41 | 8. 修复 关于页面版本号显示的 bug 42 | 9. 修复 Linux 系统下左边栏组件重叠的 bug 43 | 10. 修复 部分 Linux KDE 系统下托盘图标空白的 bug 44 | 11. 其他修改 (感谢 @wzyboy, @rivershang, @hexchain, @samurai00, @boltomli 的贡献) 45 | 46 | 47 | **v1.2 (2016.04.21)** 48 | 49 | 1. 新增 更新检测模块,应用内即可检查更新 50 | 2. 新增 公众号文章的第三方分享功能。现支持一键分享到微博、QQ 空间、Facebook、Twitter、Evernote 和邮件 (感谢 @oblank 的贡献) 51 | 3. 新增 群聊 @ 提及成员功能,但收到提醒需要服务端支持 (感谢 @iamcc 的贡献) 52 | 4. 优化 登录界面使用单独的尺寸 (感谢 @xnfa 的贡献) 53 | 5. 优化 修改 OS X 下隐藏其他窗口的快捷键为 `Command+Alt+H` 54 | 6. 优化 Linux 下可执行文件文件名使用小写字母,去除空格 55 | 7. 优化 Linux 下使用彩色图标 56 | 8. 升级 `electron-prebuilt` 版本至 `0.37.6` , `electron-packager` 版本至 `7.0.0` 57 | 9. ~~降级 Emoji贴纸显示的功能。由于微信协议调整和官方代码缺陷,现有商店内贴纸及部分个人收藏的贴纸无法显示。后续跟进微信的修复进行调整。~~ (Update: 微信已修复,贴纸均可正常显示) 58 | 59 | 60 | **v1.1 (2016.03.17)** 61 | 62 | 1. 新增 OS X 和 Linux 下的托盘菜单,点击可进入应用、退出应用 (仅Linux) (感谢 @iamcc 和 @wenLiangcan 的贡献) 63 | 2. 新增 cnpm 镜像提醒 64 | 3. 优化 应用的退出逻辑,Cmd+Q 退出应用,Cmd+W 或点击关闭隐藏应用 65 | 4. 优化 OS X 和 Linux 下的应用菜单显示 66 | 5. 优化 Emoji贴纸的实现方式,避免滑动时内容抖动,无法回到底部 67 | 6. 优化 接管应用刷新的逻辑,Cmd+R 重新加载页面 68 | 7. 优化 OS X 下 build 后将应用拷贝到 Application 文件夹 69 | 8. 优化 Linux 下使用 Ctrl+Shift+I 打开开发者工具 (感谢 @wenLiangcan 的贡献) 70 | 9. 修复 错误的微信站内重定向 (感谢 @gucheen 的贡献) 71 | 10. 修复 Linux 下应用图标的显示 72 | 11. 修复 聊天列表滑动性能问题 73 | 12. 修复 公众号新窗口打开报错 (感谢 @gzzhanghao 的贡献) 74 | 75 | **v1.0 (2016.03.01)** 76 | 77 | 1. 新增 阻止消息撤回的功能 (感谢 @arrowrowe 的贡献) 78 | 2. 新增 引入了 Travis CI 和 Gitter.im 79 | 3. 优化 贴纸显示的实现方式 (感谢 @arrowrowe 的贡献) 80 | 4. 优化 build 脚本 (感谢 @gaocegege, @viko16 和 @htc550605125 的贡献) 81 | 5. 优化 Linux 下自动隐藏菜单 (感谢 @wenLiangcan 的贡献) 82 | 6. 优化 Linux 下用户头像的显示 83 | 7. 优化 禁用缩放、选中文本、默认光标 84 | 85 | **v0.1 (2016.02.19)** 86 | 87 | 1. Create the project. 88 | 2. Auto resize web content. 89 | 3. Drag to send pictures. 90 | 4. Open inhibited links without additional redirect. 91 | -------------------------------------------------------------------------------- /README_en.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 | # Electronic WeChat 4 | 5 | *A better WeChat on macOS and Linux. Built with [Electron](https://github.com/atom/electron).* 6 | 7 | ## This branch is specially designed for ubuntu. 8 | 9 | **Important:** If you want to build the app by yourself rather than download the release directly, please consider to use the source code from [the production branch](https://github.com/geeeeeeeeek/electronic-wechat/tree/production), the master branch is under development and we cannot guarantee it to be stable. 10 | 11 | [![Gitter](https://badges.gitter.im/geeeeeeeeek/electronic-wechat.svg)](https://gitter.im/geeeeeeeeek/electronic-wechat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge) 12 | [![Build Status](https://travis-ci.org/geeeeeeeeek/electronic-wechat.svg?branch=master)](https://travis-ci.org/geeeeeeeeek/electronic-wechat) 13 | [![Build Status](https://img.shields.io/github/stars/geeeeeeeeek/electronic-wechat.svg)](https://github.com/geeeeeeeeek/electronic-wechat) 14 | [![Build Status](https://img.shields.io/github/forks/geeeeeeeeek/electronic-wechat.svg)](https://github.com/geeeeeeeeek/electronic-wechat) 15 | [![Build Status](https://img.shields.io/badge/README-切换语言-yellow.svg)](README.md) 16 | 17 | ![qq20160428-0 2x](https://cloud.githubusercontent.com/assets/7262715/14876747/ff691ade-0d49-11e6-8435-cb1fac91b3c2.png) 18 | 19 | ## Features ([CHANGELOG](CHANGELOG.md)) 20 | 21 | - **Modern UI and all features from Web WeChat.** 22 | - **Block message recall.** 23 | - **Stickers showing support.** [[?]](https://github.com/geeeeeeeeek/electronic-wechat/issues/2) 24 | - Share subscribed passages on Weibo, Qzone, Facebook, Twitter, Evernote, and email. 25 | - Mention users in a group chat. 26 | - Drag and drop to send photos. 27 | - Behaves like a native app, based on dozens of optimization. 28 | - Removes URL link redirects and takes you directly to blocked websites (e.g. taobao.com). 29 | 30 | ## How To Use 31 | 32 | To clone and run this repository you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](https://www.npmjs.com/)) installed on your computer. From your command line: 33 | 34 | ``` bash 35 | # Clone this repository 36 | git clone https://github.com/geeeeeeeeek/electronic-wechat.git 37 | # Go into the repository 38 | cd electronic-wechat 39 | # Install dependencies and run the app 40 | npm install && npm start 41 | ``` 42 | 43 | To pack into an app, simply type one of these: 44 | 45 | ``` shell 46 | npm run build:osx 47 | npm run build:linux 48 | npm run build:win32 49 | npm run build:win64 50 | ``` 51 | 52 | **New:** Install with your familiar package manager. Check out [images maintained by the community](https://github.com/geeeeeeeeek/electronic-wechat/wiki/System-Support-Matrix#%E7%A4%BE%E5%8C%BA%E8%B4%A1%E7%8C%AE%E7%9A%84%E5%AE%89%E8%A3%85%E5%8C%85)! 53 | 54 | **New:** Or, with homebrew! 55 | 56 | ```bash 57 | brew cask install electronic-wechat 58 | ``` 59 | 60 | #### [Download Released App](https://github.com/geeeeeeeeek/electronic-wechat/releases) 61 | 62 | #### License [MIT](LICENSE.md) 63 | 64 | *Electronic WeChat* is released by this open source project. While Web WeChat is a major component in the app, it should be noted that this is a community release and not an official WeChat release. 65 | -------------------------------------------------------------------------------- /src/handlers/update.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Zhongyi on 3/25/16. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const { dialog, shell, app, nativeImage } = require('electron'); 8 | const AppConfig = require('../configuration'); 9 | const https = require('https'); 10 | const path = require('path'); 11 | 12 | const Common = require('../common');; 13 | 14 | class UpdateHandler { 15 | checkForUpdate(version, silent) { 16 | UpdateHandler.CHECKED = true; 17 | const promise = new Promise((res, rej) => { 18 | if (Common.ELECTRON === app.getName()) { 19 | rej(Common.UPDATE_ERROR_ELECTRON); 20 | } 21 | const req = https.get({ 22 | host: Common.GITHUB_API_HOST, 23 | headers: { 'user-agent': Common.USER_AGENT }, 24 | path: Common.FORKER_GITHUB_API_RELEASE_LATEST_PATH, 25 | }, (response) => { 26 | let body = ''; 27 | response.on('data', (d) => { 28 | body += d; 29 | }); 30 | response.on('end', () => { 31 | this._parseUpdateData(body, version, res, rej); 32 | }); 33 | }); 34 | req.on('error', (err) => { 35 | rej(Common.UPDATE_ERROR_NETWORK); 36 | }); 37 | req.end(); 38 | }).then((fetched) => { 39 | this.showDialog(fetched.name, fetched.description, 'Update', (response) => { 40 | if (!response) return; 41 | shell.openExternal(fetched.url); 42 | }); 43 | }).catch((message) => { 44 | if (silent) return; 45 | if (!message) { 46 | message = Common.UPDATE_ERROR_UNKNOWN; 47 | } 48 | this.showDialog(Common.UPDATE_NA_TITLE, message, 'OK'); 49 | }); 50 | } 51 | 52 | showDialog(message, detail, positiveButton, callback) { 53 | const iconImage = nativeImage.createFromPath(path.join(__dirname, '../../assets/icon.png')); 54 | dialog.showMessageBox({ 55 | type: 'info', 56 | buttons: ['Cancel', positiveButton], 57 | defaultId: 1, 58 | cancelId: 0, 59 | title: message, 60 | message, 61 | detail, 62 | icon: iconImage, 63 | }, callback); 64 | } 65 | 66 | _parseUpdateData(body, version, res, rej) { 67 | try{ 68 | const data = JSON.parse(body); 69 | if (!data || !data.tag_name) rej(Common.UPDATE_ERROR_EMPTY_RESPONSE); 70 | const fetched = { 71 | version: data.tag_name, 72 | is_prerelease: data.prerelease, 73 | name: data.name||`有可用更新 当前版本(${version} > ${data.tag_name})`, 74 | url: data.html_url, 75 | description: data.body, 76 | }; 77 | const versionRegex = /^(v|V)[0-9]+\.[0-9]+\.*[0-9]*$/; 78 | if (versionRegex.test(fetched.version) && this.compareVersion(fetched.version,version) && !fetched.is_prerelease) { 79 | res(fetched); 80 | } else { 81 | rej(Common.UPDATE_ERROR_LATEST(version)); 82 | } 83 | } 84 | catch(e){ 85 | rej(Common.UPDATE_ERROR_UNKNOWN); 86 | } 87 | } 88 | 89 | compareVersion (v1,v2) { 90 | v1 = v1.match(/v(.*)?\.(.*)?\.(.*)?/) 91 | v2 = v2.match(/v(.*)?\.(.*)?\.(.*)?/) 92 | for (let i = 1;i < 4;i++) { 93 | if(parseInt(v1[i]) > parseInt(v2[i])){ 94 | return true 95 | } 96 | if (parseInt(v1[i]) < parseInt(v2[i])) { 97 | return false 98 | } 99 | } 100 | return false 101 | } 102 | } 103 | 104 | UpdateHandler.CHECKED = false; 105 | 106 | module.exports = UpdateHandler; 107 | -------------------------------------------------------------------------------- /src/common_cn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Zhongyi on 3/26/16. 3 | */ 4 | 'use strict'; 5 | 6 | class Common { 7 | 8 | } 9 | Common.ELECTRON = 'Electron'; 10 | Common.ELECTRONIC_WECHAT = 'Electronic WeChat'; 11 | Common.ELECTRONIC_SETINGS = '偏好设置'; 12 | Common.DEBUG_MODE = false; 13 | Common.WINDOW_SIZE = { 14 | width: 800, 15 | height: 600, 16 | }; 17 | Common.WINDOW_SIZE_LOGIN = { 18 | width: 380, 19 | height: 540, 20 | }; 21 | Common.WINDOW_SIZE_LOADING = { 22 | width: 380, 23 | height: 120, 24 | }; 25 | Common.WINDOW_SIZE_SETTINGS = { 26 | width: 800, 27 | height: 600, 28 | }; 29 | 30 | Common.USER_AGENT = { 31 | 'freebsd': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 32 | 'sunos': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 33 | 'win32': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 34 | 'linux': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 35 | 'darwin': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36' 36 | } 37 | 38 | Common.WEB_WECHAT = 'https://wx.qq.com/?&lang=zh_CN&target=t'; 39 | Common.GITHUB = 'https://github.com/geeeeeeeeek/electronic-wechat'; 40 | Common.FORKER_GITHUB = 'https://github.com/kooritea/electronic-wechat' 41 | Common.GITHUB_RELEASES = 'https://github.com/geeeeeeeeek/electronic-wechat/releases'; 42 | Common.FORKER_GITHUB_RELEASES = 'https://github.com/kooritea/electronic-wechat/releases'; 43 | Common.GITHUB_ISSUES = 'https://github.com/geeeeeeeeek/electronic-wechat/issues'; 44 | Common.FORKER_GITHUB_ISSUES = 'https://github.com/kooritea/electronic-wechat/issues' 45 | Common.GITHUB_API_HOST = 'api.github.com'; 46 | Common.GITHUB_API_RELEASE_LATEST_PATH = '/repos/geeeeeeeeek/electronic-wechat/releases/latest'; 47 | Common.FORKER_GITHUB_API_RELEASE_LATEST_PATH = '/repos/kooritea/electronic-wechat/releases/latest'; 48 | 49 | Common.UPDATE_ERROR_ELECTRON = 'Failed to get the local version. If you are using debug mode(by `npm start`), this error would happen. Use packed app instead or manually check for updates.\n\n' + Common.GITHUB_RELEASES; 50 | Common.UPDATE_ERROR_EMPTY_RESPONSE = '没能获取最新的更新信息'; 51 | Common.UPDATE_ERROR_UNKNOWN = '不造什么出错了...'; 52 | Common.UPDATE_NA_TITLE = '没有可用的更新'; 53 | Common.UPDATE_ERROR_NETWORK = '网络连接出错,请检查你的网络'; 54 | Common.UPDATE_ERROR_LATEST = (version) => { 55 | return `已经在使用最新版 - (${version})`; 56 | }; 57 | 58 | Common.MENTION_MENU_INITIAL_X = 300; 59 | Common.MENTION_MENU_OFFSET_X = 30; 60 | Common.MENTION_MENU_INITIAL_Y = 140; 61 | Common.MENTION_MENU_OFFSET_Y = 45; 62 | Common.MENTION_MENU_WIDTH = 120; 63 | Common.MENTION_MENU_OPTION_HEIGHT = 30; 64 | Common.MENTION_MENU_OPTION_DEFAULT_NUM = 4; 65 | Common.MENTION_MENU_HINT_TEXT = '选择回复的人:'; 66 | Common.TEAM_MESSAGE = '群聊消息' 67 | Common.WECHAT_MESSAGE = '微信消息' 68 | Common.RECEIVED_TEAM_MESSAGE = '收到一条群聊消息' 69 | 70 | Common.MESSAGE_PREVENT_RECALL = (name) => { 71 | return `阻止了 \"${name}\" 的一次撤回` 72 | } 73 | Common.EMOJI_MAXIUM_SIZE = 120; 74 | 75 | Common.clearHistoryConfirm = '确定要清除所有聊天记录?' 76 | 77 | Common.MENU = { 78 | about: '关于 Electronic Wechat', 79 | service: '服务', 80 | hide: '隐藏应用', 81 | hideOther: '隐藏其他窗口', 82 | showAll: '显示全部窗口', 83 | pref: '偏好', 84 | quit: '退出', 85 | edit: '编辑', 86 | undo: '撤销', 87 | redo: '取消撤销', 88 | cut: '剪切', 89 | copy: '复制', 90 | paste: '粘贴', 91 | selectAll: '选择全部', 92 | view: '视图', 93 | reload: '重新加载当前窗口', 94 | toggleFullScreen:'切换全屏', 95 | searchContacts:'搜索联系人', 96 | devtool: '开发者工具', 97 | window: '窗口', 98 | min: '最小化', 99 | close: '关闭', 100 | allFront: '全部打开', 101 | help: '帮助', 102 | repo: 'GitHub 目录', 103 | repo_fork: '该分支 Github 目录', 104 | feedback: '联系我们', 105 | feedback_forker: '联系该分支开发者', 106 | checkRelease: '检查更新', 107 | }; 108 | 109 | Common.TRAY = { 110 | show:'显示微信', 111 | pref:'偏好', 112 | exit:'退出' 113 | } 114 | 115 | 116 | module.exports = Common; 117 | -------------------------------------------------------------------------------- /src/windows/controllers/app_tray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Zhongyi on 5/2/16. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const path = require('path'); 8 | const { Menu, nativeImage, Tray, ipcMain } = require('electron'); 9 | 10 | const AppConfig = require('../../configuration'); 11 | 12 | const assetsPath = path.join(__dirname, '../../../assets'); 13 | 14 | const Common = require('../../common');; 15 | 16 | class AppTray { 17 | constructor(splashWindow, wechatWindow, settingsWindow) { 18 | this.splashWindow = splashWindow; 19 | this.wechatWindow = wechatWindow; 20 | this.settingsWindow = settingsWindow; 21 | this.lastUnreadStat = 0; 22 | const trayColor = AppConfig.readSettings('tray-color'); 23 | if (trayColor === 'white' || trayColor === 'black') { 24 | this.trayColor = trayColor; 25 | } else { 26 | this.trayColor = 'white'; 27 | AppConfig.saveSettings('tray-color', this.trayColor); 28 | } 29 | this.createTray(); 30 | } 31 | 32 | createTray() { 33 | let image; 34 | let tray=null 35 | if (process.platform === 'linux' || process.platform === 'win32') { 36 | image = nativeImage.createFromPath(path.join(assetsPath, `tray_${this.trayColor}.png`)); 37 | this.trayIcon = image; 38 | this.trayIconUnread = nativeImage.createFromPath(path.join(assetsPath, `tray_unread_${this.trayColor}.png`)); 39 | } else { 40 | image = nativeImage.createFromPath(path.join(assetsPath, 'status_bar.png')); 41 | } 42 | image.setTemplateImage(true); 43 | 44 | tray = new Tray(image); 45 | this.tray=tray; 46 | this.tray.setToolTip(Common.ELECTRONIC_WECHAT); 47 | 48 | ipcMain.on('refreshIcon', () => this.refreshIcon()); 49 | 50 | if (process.platform === 'linux' || process.platform === 'win32') { 51 | const contextMenu = Menu.buildFromTemplate([ 52 | { label: Common.TRAY.show, icon:path.join(__dirname, `../../../assets/tray_icon.png`), click: () => this.hideSplashAndShowWeChat() }, 53 | { label: Common.TRAY.pref, icon:path.join(__dirname, `../../../assets/tray_settings_${this.trayColor}.png`), click: () => this.showSettings()}, 54 | { label: Common.TRAY.exit, icon:path.join(__dirname, `../../../assets/tray_exit_${this.trayColor}.png`), click: () => this.appExit() }, 55 | ]); 56 | this.tray.setContextMenu(contextMenu); 57 | } 58 | this.tray.on('click', () => this.hideSplashAndShowWeChat()); 59 | } 60 | 61 | setTitle(title) { 62 | this.tray.setTitle(title); 63 | } 64 | 65 | hideSplashAndShowWeChat() { 66 | if (this.splashWindow.isShown){ 67 | this.splashWindow.hide(); 68 | this.wechatWindow.show(); 69 | return; 70 | }; 71 | this.wechatWindow.show(); 72 | } 73 | showSettings() { 74 | this.settingsWindow.show() 75 | } 76 | appExit() { 77 | this.wechatWindow.exit(); 78 | } 79 | refreshIcon() { 80 | this.trayColor = AppConfig.readSettings('tray-color'); 81 | this.trayIcon = nativeImage.createFromPath(path.join(assetsPath, `tray_${this.trayColor}.png`)); 82 | this.trayIconUnread = nativeImage.createFromPath(path.join(assetsPath, `tray_unread_${this.trayColor}.png`)); 83 | if (this.lastUnreadStat === 0) { 84 | this.tray.setImage(this.trayIcon); 85 | } else { 86 | this.tray.setImage(this.trayIconUnread); 87 | } 88 | const contextMenu = Menu.buildFromTemplate([ 89 | { label: Common.TRAY.show, icon:path.join(__dirname, `../../../assets/tray_icon.png`), click: () => this.hideSplashAndShowWeChat() }, 90 | { label: Common.TRAY.pref, icon:path.join(__dirname, `../../../assets/tray_settings_${this.trayColor}.png`), click: () => this.showSettings()}, 91 | { label: Common.TRAY.exit, icon:path.join(__dirname, `../../../assets/tray_exit_${this.trayColor}.png`), click: () => this.appExit() }, 92 | ]); 93 | this.tray.setContextMenu(contextMenu); 94 | } 95 | 96 | setUnreadStat(stat) { 97 | if (stat === this.lastUnreadStat) return; 98 | this.lastUnreadStat = stat; 99 | if (stat === 0) { 100 | this.tray.setImage(this.trayIcon); 101 | } else { 102 | this.tray.setImage(this.trayIconUnread); 103 | } 104 | } 105 | } 106 | 107 | module.exports = AppTray; 108 | -------------------------------------------------------------------------------- /src/windows/styles/settings.css: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-user-select: none; 3 | cursor: default !important; 4 | -webkit-user-drag: none; 5 | } 6 | 7 | body { 8 | margin: 0; 9 | padding: 0; 10 | color: #364854; 11 | font-family: "Microsoft Yahei", "微软雅黑", STXihei, "华文细黑", sans-serif; 12 | background-color: #F3F3F3; 13 | } 14 | 15 | div { 16 | margin: 0; 17 | padding: 0; 18 | } 19 | 20 | ul { 21 | list-style: none; 22 | } 23 | 24 | h1 { 25 | color: #364854; 26 | } 27 | 28 | section { 29 | position: relative; 30 | width: 75%; 31 | left: 12.5%; 32 | border-bottom: 1px solid gray; 33 | overflow: hidden; 34 | } 35 | 36 | .page { 37 | min-width: 500px; 38 | min-height: 350px; 39 | } 40 | 41 | .setting-menu { 42 | padding-top: 5px; 43 | } 44 | 45 | .menu-title { 46 | position: relative; 47 | left: 20%; 48 | } 49 | 50 | .menu-desc { 51 | position: relative; 52 | left: 20%; 53 | } 54 | 55 | .menu-button { 56 | position: relative; 57 | left: 20%; 58 | } 59 | 60 | .setting-top-bar { 61 | padding: 0; 62 | margin: 0 0 10px 0; 63 | border: none; 64 | height: 140px; 65 | width: 100%; 66 | overflow: hidden; 67 | background-color: #CCC; 68 | box-shadow: 0px 5px 5px #CCC; 69 | } 70 | 71 | .title-list { 72 | padding-top: 1px; 73 | } 74 | 75 | .top-bar-icon { 76 | width: 100px; 77 | height: 100px; 78 | float: left; 79 | margin: 15px; 80 | margin-left: 30px; 81 | } 82 | 83 | .top-bar-left { 84 | float: left; 85 | width: 12%; 86 | padding: 1%; 87 | } 88 | 89 | .top-bar-middle { 90 | text-align: center; 91 | } 92 | 93 | .top-bar-right { 94 | text-align: center; 95 | float: right; 96 | width: 18%; 97 | margin-right: 40px; 98 | padding-top: 20px; 99 | } 100 | 101 | .upgrade-btn { 102 | border-radius: 15px; 103 | margin-bottom: 10px; 104 | color: #c9c9c9; 105 | font-size: 16px; 106 | background: #364854; 107 | padding: 10px 20px 10px 20px; 108 | text-decoration: none; 109 | width: 125px; 110 | } 111 | 112 | select{ 113 | -webkit-appearance: none; 114 | height: 25px; 115 | padding-left: 10px; 116 | padding-right: 30px; 117 | text-align: center; 118 | line-height: 25px; 119 | background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTE5OTc2MjkzMzE4IiBjbGFzcz0iaWNvbiIgc3R5bGU9IiIgdmlld0JveD0iMCAwIDE5NzAgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIyMDEiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMzg0Ljc2NTYyNSIgaGVpZ2h0PSIyMDAiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTEzNC42NzY3MjYgMjMuMjA1MDk1QzEwMy44ODkyNjEtNy41ODI0MjQgNTQuMjA4OTY2LTcuODE4NjE3IDIzLjIzMzc5OCAyMy4xNTY1NTFMMjMuMjMzNzk4IDIzLjE1NjU1MUMtNy41MjY4ODUgNTMuOTE3MjUtNy42ODExMTMgMTAzLjYzNTk5MSAyMi44NjYxMSAxMzQuMTgzMTkxTDg1OC45NjUwOTQgOTcwLjI4MjIyMUM5MjAuMzM1NDYzIDEwMzEuNjUyNTgzIDEwMTkuODAyNTQ3IDEwMzEuNjg2NTA4IDEwODEuMjA2ODY1IDk3MC4yODIyMjFMMTkxNy4zMDU4NDkgMTM0LjE4MzE5MUMxOTQ3Ljg2MzQ2OSAxMDMuNjI1NTcxIDE5NDcuOTEzMzI5IDU0LjEzMTcxMSAxOTE2LjkzODE2MSAyMy4xNTY1NTFMMTkxNi45MzgxNjEgMjMuMTU2NTUxQzE4ODYuMTc3NDc4LTcuNjA0MTYgMTgzNi40NzYzMDktNy43NzU5NTEgMTgwNS40OTUyMzMgMjMuMjA1MDk1TDEwMjUuODMxNzQzIDgwMi44Njg2MDFDOTk1LjA0NDIgODMzLjY1NjEyMSA5NDUuMzIxMjkyIDgzMy44NDk2NTMgOTE0LjM0MDIxNiA4MDIuODY4NjAxTDEzNC42NzY3MjYgMjMuMjA1MDk1IDEzNC42NzY3MjYgMjMuMjA1MDk1WiIgcC1pZD0iMjIwMiI+PC9wYXRoPjwvc3ZnPg==) no-repeat scroll 100% transparent; 120 | background-size: 20px; 121 | background-color: #97c9eb; 122 | background-position-x: calc(100% - 3px); 123 | outline: none; 124 | border: none; 125 | } 126 | 127 | select option{ 128 | height: 20px; 129 | line-height: 20px; 130 | } 131 | 132 | input{ 133 | padding: 5px; 134 | border:0; 135 | border-bottom: 1px solid #97c9eb; 136 | background-color: transparent; 137 | outline: none; 138 | } 139 | .exinput{ 140 | margin-top: 20px; 141 | } 142 | textarea{ 143 | border: 1px solid #97c9eb; 144 | outline-color: #97c9eb; 145 | width: 300px; 146 | height: 150px; 147 | } 148 | .button{ 149 | width: 80px; 150 | height: 30px; 151 | border-radius: 3px; 152 | text-align: center; 153 | line-height: 30px; 154 | background-color: #97c9eb; 155 | cursor: pointer!important; 156 | } 157 | .button:hover{ 158 | background-color: #fcd3f3; 159 | } 160 | -------------------------------------------------------------------------------- /src/inject/mention_menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Zhongyi on 4/9/16. 3 | */ 4 | 5 | 'use strict'; 6 | const Common = require('../common'); 7 | const pinyin = require('pinyin'); 8 | 9 | class MentionMenu { 10 | 11 | static init() { 12 | const $box = $('
    '); 13 | 14 | const $div = $('
    '); 15 | $div.html(Common.MENTION_MENU_HINT_TEXT); 16 | $div.addClass('user_select_hint_text'); 17 | $box.append($div); 18 | 19 | const $select = $(' 38 | 39 | 40 | 41 | 42 | 43 | 44 |
    45 |
      46 | 49 | 52 | 58 |
    59 |
    60 |
    61 |
      62 | 65 | 68 | 74 |
    75 |
    76 |
    77 |
      78 | 81 | 84 | 90 |
    91 |
    92 |
    93 |
      94 | 97 | 100 | 106 |
    107 |
    108 |
    109 |
      110 | 113 | 116 | 122 |
    123 |
    124 |
    125 |
      126 | 129 | 132 | 140 |
    141 |
    142 |
    143 |
      144 | 147 | 150 | 156 |
    157 |
    158 |
    159 |
      160 | 163 | 166 | 169 |
    170 |
    171 |
    172 |
      173 | 176 | 179 | 185 |
    186 |
    187 |
    188 |
      189 | 192 | 195 | 201 |
    202 |
    203 |
    204 |
      205 | 208 | 211 | 217 | 232 |
    233 |
    234 |
    235 |
      236 | 239 | 242 | 248 | 251 |
    252 |
    253 |
    254 |
      255 | 258 | 261 | 266 |
    267 |
    268 |
    269 |
      270 | 273 | 276 | 282 | 287 |
    288 |
    289 |
    290 | 291 | 546 | 547 | 548 | 549 | -------------------------------------------------------------------------------- /src/inject/mini_frame.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by kooritea on 5/15/18. 3 | */ 4 | 5 | 'use strict'; 6 | const { ipcRenderer } = require('electron'); 7 | 8 | class MiniFrame { 9 | static init(){ 10 | const $box = $('
    '); 11 | const $boxx = $('
    '); 12 | const $close = $("") 13 | const $maximize = $("") 14 | const $unmaximize = $("") 15 | const $minimize = $("") 16 | const $settings = $("") 17 | $close.attr('src','data:image/png;base64,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') 18 | $close.on('click',()=>{ 19 | ipcRenderer.send('miniFrame-close') 20 | }) 21 | $maximize.attr('src','data:image/png;base64,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') 22 | $maximize.on('click',()=>{ 23 | $maximize.attr('style','display:none') 24 | $unmaximize.attr('style','') 25 | ipcRenderer.send('miniFrame-setFullScreen',true) 26 | }) 27 | $unmaximize.attr('src','data:image/png;base64,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') 28 | $unmaximize.attr('style','display:none') 29 | $unmaximize.on('click',()=>{ 30 | $unmaximize.attr('style','display:none') 31 | $maximize.attr('style','') 32 | ipcRenderer.send('miniFrame-setFullScreen',false) 33 | }) 34 | $minimize.attr('src','data:image/png;base64,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') 35 | $minimize.on('click',()=>{ 36 | ipcRenderer.send('miniFrame-minimize') 37 | }) 38 | $settings.attr('src','data:image/png;base64,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') 39 | $settings.on('click',()=>{ 40 | ipcRenderer.send('open-settings-window') 41 | }) 42 | $boxx.append($close); 43 | $boxx.append($maximize); 44 | $boxx.append($unmaximize); 45 | $boxx.append($minimize); 46 | $boxx.append($settings); 47 | $box.append($boxx) 48 | $(".header").prepend($box) 49 | } 50 | 51 | } 52 | 53 | module.exports = MiniFrame; 54 | --------------------------------------------------------------------------------