Repository: zhongyi-tong/electronic-wechat Branch: master Commit: dc50c871d9b5 Files: 38 Total size: 73.7 KB Directory structure: gitextract_2blxg1ih/ ├── .eslintrc ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── README.md ├── README_zh.md ├── assets/ │ └── icon.icns ├── config.json ├── package.json ├── scripts/ │ ├── build-all.sh │ ├── build-win32.bat │ ├── build.sh │ ├── qiniu.sh │ └── tar-all.sh └── src/ ├── common.js ├── common_cn.js ├── configuration.js ├── handlers/ │ ├── menu.js │ ├── message.js │ └── update.js ├── inject/ │ ├── badge_count.js │ ├── css.js │ ├── emoji_parser.js │ ├── mention_menu.js │ ├── preload.js │ └── share_menu.js ├── main.js └── windows/ ├── controllers/ │ ├── app_tray.js │ ├── settings.js │ ├── splash.js │ └── wechat.js ├── styles/ │ ├── settings.css │ └── splash.css └── views/ ├── settings.html └── splash.html ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintrc ================================================ { "parser": "babel-eslint", "extends": "airbnb/base", "rules": { "strict": "off", "max-len": "off", "prefer-template": "warn", "arrow-body-style": "off", "no-unused-vars": "warn", "no-undef": "off", "array-callback-return": "off", "no-confusing-arrow": "off", "consistent-return": "warn", "no-param-reassign": "off", "default-case": "off", "guard-for-in": "off", "no-restricted-syntax": "off", "no-underscore-dangle": "off", "new-cap": "warn", "no-console": "off", "global-require": "off", "class-methods-use-this": "warn" }, } ================================================ FILE: .gitignore ================================================ .DS_Store /dist npm-debug.log* .idea # Dependency directories node_modules *.sublime-project *.sublime-workspace ================================================ FILE: .travis.yml ================================================ language: node_js sudo: required node_js: - '5.2' branches: only: - master - production before_script: - npm install script: - ./scripts/build-all.sh - ./scripts/tar-all.sh deploy: provider: releases api_key: secure: ETudcaMBembv5mq5WcA0Zu5YCQt02A8sfMIYJ+XN0dTUCFRODYgyk8SiW3ndI4zLfhsc31KbYecSVfcrvYhPlkLucdhD0hY+v4mowrGaG6q3DUE4v9+qATOE5z51MPNTQO/suPNZpeFkSCKaWh6SY9oSd/tsD+YmbcpuD0//DMiFMpYqA8ueQ7yka4SmlZq8C48MsRbULAtyHNEVNJ4en9xdE9vFHZ45kM2A2IWYVikuCa5J6YoL7N2CyIFwtKMeF68d0vwidXUXEc7z1VOHwosG7V0vEfNRrIy4mft0tXyEYe/nM8GlYnirVRCy3xF4h4ssERXbLMuZSYGm+bg/pqReL+dvsN5oKszuo7IseZnE8QfmmhfbMB4dWf8Le5WXfFgJTG28lNvl2VwTTEW4Cj5qeJmfO524GydqRE+i3uQvW4c2tBTFmfpusPnaFqVXTPH7o54hT18hYvgaBvJQv6pyMNMLLXq0BbkzquTTWTwb8lSi8XiRr/fWkQreRZNofJc21ZUSI5YcuqZpzbz1fOLseC4QJ8YXQ9b2OU/LiFF3gvHTK6vSKMQmbOFg0zFXMi5FT1SzCi/mKduax/OR/H6lolVW83eXCG1Ni+sIrwUkp0d/UL6E1pVeJMibBrOEgriWIpD+AiVzNVyBdq/oDC6qG9IXRWzii9Ks6J9zH7k= file: - 'dist/mac-osx.tar.gz' - 'dist/linux-x64.tar.gz' - 'dist/linux-ia32.tar.gz' skip_cleanup: true on: repo: geeeeeeeeek/electronic-wechat branch: production notifications: webhooks: urls: - https://webhooks.gitter.im/e/d6bab2376f47ee992d78 on_success: always # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always on_start: always # options: [always|never|change] default: always after_deploy: - ./scripts/qiniu.sh ================================================ FILE: CHANGELOG.md ================================================ # CHANGELOG **v2.0 (2017.02.13) CN** 1. 升级 **Electron** 至 **V1.4.15**,**Chromium** 至 **54** 2. 增加了**偏好设置**(感谢设计建议 @**[xiaoyusilen](https://github.com/xiaoyusilen)**) 3. 增加了英文版本的支持 4. 增加了一键隐藏窗口(**`ESC`** 键) 5. 修复了 **macOS** 上窗口最小化时不显示新消息提示的红点(感谢 @wujysh 的贡献) 6. 修复了聊天框内换行提示仅针对 macOS 的问题 7. 增加了两个快捷键(感谢 @awmleer 的贡献) - 搜索联系人:**`Ctrl + F`** - 切换到全屏模式:**macOS** 下 **`Ctrl + Command + F`**,**Linux** 下为 **`F11`** 8. 修复了在 Linux 系统下部分菜单按钮失效的问题(感谢 @qzchenwl 的贡献) 8. 更新了依赖的第三方库的版本至最新兼容版本 **v2.0 (2017.02.13) EN** 1. Update Electron to V1.4.15, Chromium API level 54 2. Add **Preference Panel** (Thanks for the design advises from @**[xiaoyusilen](https://github.com/xiaoyusilen)**](https://github.com/xiaoyusilen)) 3. Fully support English UI! 4. Quick hide windows shortcut (**Press `ESC`**) 5. Fix **macOS** new message red dot display improperly (Thanks to @wujysh) 6. Tips in chat window now are adapted with platform 7. Add two shortcuts (Thanks to @awmleer) - Search Contact人: **`Ctrl + F`** - Toggle Fullscreen Mode: **macOS** **`Ctrl + Command + F`**, **Linux** **`F11`** 8. Fix unfunctional menu items on **Linux** (Thanks to @qzchenwl) 8. All thrid party libraries are up-to-date **v1.3 (2016.05.19)** 1. 升级 electron 至 1.1.0, Chrome 至 50.0.2661.102,Node 至 6.1.0 (感谢 @lfs1102 的贡献) 2. 新增 `brew cask` 安装方式 (最新可下载版本为 v1.2.0) 3. 新增 Windows 下的安装脚本 (感谢 @3dseals 的贡献) 4. 新增 应用启动动画,缩短首次展现时间 5. 优化 应用启动稳定性,增加超时重试 6. 优化 主要文案均统一为英文 7. 优化 减少 20M 应用体积 8. 修复 关于页面版本号显示的 bug 9. 修复 Linux 系统下左边栏组件重叠的 bug 10. 修复 部分 Linux KDE 系统下托盘图标空白的 bug 11. 其他修改 (感谢 @wzyboy, @rivershang, @hexchain, @samurai00, @boltomli 的贡献) **v1.2 (2016.04.21)** 1. 新增 更新检测模块,应用内即可检查更新 2. 新增 公众号文章的第三方分享功能。现支持一键分享到微博、QQ 空间、Facebook、Twitter、Evernote 和邮件 (感谢 @oblank 的贡献) 3. 新增 群聊 @ 提及成员功能,但收到提醒需要服务端支持 (感谢 @iamcc 的贡献) 4. 优化 登录界面使用单独的尺寸 (感谢 @xnfa 的贡献) 5. 优化 修改 OS X 下隐藏其他窗口的快捷键为 `Command+Alt+H` 6. 优化 Linux 下可执行文件文件名使用小写字母,去除空格 7. 优化 Linux 下使用彩色图标 8. 升级 `electron-prebuilt` 版本至 `0.37.6` , `electron-packager` 版本至 `7.0.0` 9. ~~降级 Emoji贴纸显示的功能。由于微信协议调整和官方代码缺陷,现有商店内贴纸及部分个人收藏的贴纸无法显示。后续跟进微信的修复进行调整。~~ (Update: 微信已修复,贴纸均可正常显示) **v1.1 (2016.03.17)** 1. 新增 OS X 和 Linux 下的托盘菜单,点击可进入应用、退出应用 (仅Linux) (感谢 @iamcc 和 @wenLiangcan 的贡献) 2. 新增 cnpm 镜像提醒 3. 优化 应用的退出逻辑,Cmd+Q 退出应用,Cmd+W 或点击关闭隐藏应用 4. 优化 OS X 和 Linux 下的应用菜单显示 5. 优化 Emoji贴纸的实现方式,避免滑动时内容抖动,无法回到底部 6. 优化 接管应用刷新的逻辑,Cmd+R 重新加载页面 7. 优化 OS X 下 build 后将应用拷贝到 Application 文件夹 8. 优化 Linux 下使用 Ctrl+Shift+I 打开开发者工具 (感谢 @wenLiangcan 的贡献) 9. 修复 错误的微信站内重定向 (感谢 @gucheen 的贡献) 10. 修复 Linux 下应用图标的显示 11. 修复 聊天列表滑动性能问题 12. 修复 公众号新窗口打开报错 (感谢 @gzzhanghao 的贡献) **v1.0 (2016.03.01)** 1. 新增 阻止消息撤回的功能 (感谢 @arrowrowe 的贡献) 2. 新增 引入了 Travis CI 和 Gitter.im 3. 优化 贴纸显示的实现方式 (感谢 @arrowrowe 的贡献) 4. 优化 build 脚本 (感谢 @gaocegege, @viko16 和 @htc550605125 的贡献) 5. 优化 Linux 下自动隐藏菜单 (感谢 @wenLiangcan 的贡献) 6. 优化 Linux 下用户头像的显示 7. 优化 禁用缩放、选中文本、默认光标 **v0.1 (2016.02.19)** 1. Create the project. 2. Auto resize web content. 3. Drag to send pictures. 4. Open inhibited links without additional redirect. ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to Electronic WeChat First of all, thanks for contributing to this project. It would be appreciated if you read through this contributing guide. ## Issues - Check if your issue is already [there](https://github.com/geeeeeeeeek/electronic-wechat/issues). - Check if your issue is `Electronic WeChat` related rather than upstream related. - Follow the guide in the issue template. ## Pull Requests 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. ## Be a collaborator! 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! ================================================ FILE: ISSUE_TEMPLATE.md ================================================ #### Description First of all, thanks for your attention to open an issue for this project. Please notice that if you are requesting a **feature**, then you should give a **brief description** of your request. If you are reporting a **bug**, please **follow the template** below. A bug report **without detailed information** required will have a **very low priority** and even be **ignored** (closed directly)! #### Specifications - Version of Electron (run `$ electron --version`): `v0.0.0` - OS: `` - Stack trace from the error message (if any) ``` ``` ================================================ FILE: LICENSE.md ================================================ The MIT License (MIT) Copyright (c) 2017 Zhongyi Tong Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ logo # Electronic WeChat *A better WeChat on macOS and Linux. Built with [Electron](https://github.com/atom/electron).* > **⚠️⚠️ NO LONGER IN ACTIVE DEVELOPMENT | 项目不再维护 ⚠️⚠️** > > Thanks for supporting this project for **1000** days since Feb 16, 2016. > > It started with the idea to make WeChat better on MacOS when the official support was abscent. It was de facto dead when Tencent rolled out a new WeChat and started to block other third-party clients. For me, it's no longer worthwhile to hack a lot to accomplish little. Hope this project had been helpful to you in any way. You're welcome to fork or make copies with a reference. HAPPY HACKING. > > 感谢历史上的用户和贡献者,你们已经陪伴这个项目走过了 **1000** 个日子。我曾经想要打造一个更好的 Mac 微信客户端,因为官方版本几年没有更新、bug 层出。而在腾讯自己开始了定期更新并限制第三方客户端时,这个项目实际已经没有什么意义。这个项目目前作为一个存档供大家学习。希望它曾经对你有所帮助,你也可以 fork 或者转载(标注来源)来进行修改。祝你玩得愉快。 > > **SPECIAL THANKS TO | 特别感谢** > > [Kulbear](https://github.com/Kulbear), > [arrowrowe](https://github.com/arrowrowe), > [Rocka](https://github.com/rocka), > [CC](https://github.com/iamcc), > [xgdgsc](https://github.com/xgdgsc), > [死水微澜](https://github.com/ripples-alive), > [Jason](https://github.com/gzzhanghao), > [Ce Gao](https://github.com/gaocegege), > [viko16](https://github.com/viko16), > [卡晨](https://github.com/awmleer), > [Ray](https://github.com/ray26), > [尹良灿](https://github.com/wenLiangcan), > [gehuangyi20](https://github.com/gehuangyi20), > [Kevin Tan](https://github.com/stkevintan), > [Jiaye Wu](https://github.com/wujysh), > [loufq](https://github.com/loufq), > [Miaow](https://github.com/miaowing), > [Chuan Ji](https://github.com/jichu4n), > [Oaker](https://github.com/cyio), > [Fengshuang Li](https://github.com/lfs1102), > [Song Li](https://github.com/boltomli), > [afon](https://github.com/samurai00), > [lional wang](https://github.com/3dseals), > [Haochen Tong](https://github.com/hexchain), > [Zhuoyun Wei](https://github.com/wzyboy), > [rivershang](https://github.com/rivershang), > [Ivan Jiang](https://github.com/iplus26), > [oBlank](https://github.com/oblank), > [Cheng Gu](https://github.com/gucheen), > [NullMDR](https://github.com/NullMDR), > [ReadmeCritic](https://github.com/ReadmeCritic). --- **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. [![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) [![Build Status](https://travis-ci.org/geeeeeeeeek/electronic-wechat.svg?branch=master)](https://travis-ci.org/geeeeeeeeek/electronic-wechat) [![Build Status](https://img.shields.io/github/stars/geeeeeeeeek/electronic-wechat.svg)](https://github.com/geeeeeeeeek/electronic-wechat) [![Build Status](https://img.shields.io/github/forks/geeeeeeeeek/electronic-wechat.svg)](https://github.com/geeeeeeeeek/electronic-wechat) [![Build Status](https://img.shields.io/badge/README-切换语言-yellow.svg)](README_zh.md) ![qq20160428-0 2x](https://cloud.githubusercontent.com/assets/7262715/14876747/ff691ade-0d49-11e6-8435-cb1fac91b3c2.png) ## Features ([CHANGELOG](CHANGELOG.md)) - **Modern UI and all features from Web WeChat.** - **Block message recall.** - **Stickers showing support.** [[?]](https://github.com/geeeeeeeeek/electronic-wechat/issues/2) - Share subscribed passages on Weibo, Qzone, Facebook, Twitter, Evernote, and email. - Mention users in a group chat. - Drag and drop to send photos. - Behaves like a native app, based on dozens of optimization. - Removes URL link redirects and takes you directly to blocked websites (e.g. taobao.com). ## How To Use 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: ``` bash # Clone this repository git clone https://github.com/geeeeeeeeek/electronic-wechat.git # Go into the repository cd electronic-wechat # Install dependencies and run the app npm install && npm start ``` To pack into an app, simply type one of these: ``` shell npm run build:osx npm run build:linux npm run build:win32 npm run build:win64 ``` **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)! **New:** Or, with homebrew! ```bash brew cask install electronic-wechat ``` #### [Download Released App](https://github.com/geeeeeeeeek/electronic-wechat/releases) #### License [MIT](LICENSE.md) *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. ================================================ FILE: README_zh.md ================================================ logo # Electronic WeChat [![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) [![Build Status](https://travis-ci.org/geeeeeeeeek/electronic-wechat.svg?branch=master)](https://travis-ci.org/geeeeeeeeek/electronic-wechat) [English](README.md) **Mac OS X 和 Linux 下更好用的微信客户端. 更多功能, 更少bug. 使用[Electron](https://github.com/atom/electron)构建.** **Important:** 如果你希望在自己的电脑上构建 Electronic WeChat,请使用 [production branch](https://github.com/geeeeeeeeek/electronic-wechat/tree/production),master branch 包含正在开发的部分,并且不能保证是稳定的版本——尽管 production 版本也有bug :D ![qq20160428-0 2x](https://cloud.githubusercontent.com/assets/7262715/14876747/ff691ade-0d49-11e6-8435-cb1fac91b3c2.png) ## 应用特性 ([更新日志](CHANGELOG.md)) - **来自网页版微信的更现代的界面和更丰富的功能** - **阻止消息撤回** - **显示表情贴纸** [[?]](https://github.com/geeeeeeeeek/electronic-wechat/issues/2) - 公众号文章支持一键分享到微博、QQ 空间、Facebook、Twitter、Evernote 和邮件 - 拖入图片、文件即可发送 - 群聊 @ 提及成员 - 原生应用体验,未读消息小红点、消息通知等数十项优化 - 去除外链重定向,直接打开淘宝等网站 - 没有原生客户端万年不修复的bug ## 如何使用 在下载和运行这个项目之前,你需要在电脑上安装 [Git](https://git-scm.com) 和 [Node.js](https://nodejs.org/en/download/) (来自 [npm](https://www.npmjs.com/))。在命令行中输入: ``` bash # 下载仓库 git clone https://github.com/geeeeeeeeek/electronic-wechat.git # 进入仓库 cd electronic-wechat # 安装依赖, 运行应用 npm install && npm start ``` 根据你的平台打包应用: ``` shell npm run build:osx npm run build:linux npm run build:win ``` **提示:** 如果 `npm install` 下载缓慢,你可以使用 [淘宝镜像(cnpm)](http://npm.taobao.org/) 替代 npm 。 **新渠道:** 使用你熟悉的包管理工具安装。请查看 [社区贡献的镜像](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) 。 **新渠道:** homebrew 安装也已支持 (更新至 electronic-wechat v1.2.0)! ```bash brew cask install electronic-wechat ``` #### [下载开箱即用的稳定版应用](https://github.com/geeeeeeeeek/electronic-wechat/releases) #### 项目使用 [MIT](LICENSE.md) 许可 *Electronic WeChat* 是这个开源项目发布的产品。网页版微信是其中重要的一部分,但请注意这是一个社区发布的产品,而 *不是* 官方微信团队发布的产品。 ================================================ FILE: config.json ================================================ { "osx" : { "title": "Electronic Wechat", "background": "icon.png", "icon": "icon.icns", "icon-size": 80, "contents": [ { "x": 438, "y": 344, "type": "link", "path": "/Applications" }, { "x": 192, "y": 344, "type": "file" } ] } } ================================================ FILE: package.json ================================================ { "name": "electronic-wechat", "version": "2.0.0", "description": "An Electron application for WeChat", "main": "src/main.js", "scripts": { "start": "electron src/main.js", "build": "./scripts/build-all.sh", "build:osx": "./scripts/build.sh darwin x64", "build:osx64": "./scripts/build.sh darwin x64", "build:linux32": "./scripts/build.sh linux ia32", "build:linux": "./scripts/build.sh linux x64", "build:linux64": "./scripts/build.sh linux x64", "build:win": ".\\scripts\\build-win32.bat win32 ia32", "build:win32": ".\\scripts\\build-win32.bat win32 ia32", "build:win64": ".\\scripts\\build-win32.bat win32 x64" }, "repository": { "type": "git", "url": "https://github.com/geeeeeeeeek/wechat-electron.git" }, "keywords": [ "Electron", "WeChat", "微信", "Web" ], "author": "Zhongyi Tong", "license": "MIT", "bugs": { "url": "https://github.com/geeeeeeeeek/wechat-electron/issues" }, "homepage": "https://github.com/geeeeeeeeek/wechat-electron/", "dependencies": { "electron": "1.4.15", "electron-packager": "^8.5.1", "nconf": "^0.8.4", "pinyin": "^2.8.0", "emojione": "^2.2.7", "electron-localshortcut": "1.1.0", "is-xfce": "^1.0.2" }, "devDependencies": { "babel-eslint": "^7.1.1", "eslint": "^3.15.0", "eslint-config-airbnb": "^14.1.0", "eslint-plugin-import": "^2.2.0", "eslint-plugin-jsx-a11y": "^4.0.0", "eslint-plugin-react": "^6.9.0" } } ================================================ FILE: scripts/build-all.sh ================================================ #!/bin/bash if ! hash electron-packager 2>/dev/null; then RED='\033[0;31m' NC='\033[0m' echo "${RED}Error${NC}: you need to npm install electron-packager. Aborting." exit 1 fi function build() { ./scripts/build.sh $@ } build darwin x64 build linux ia32 build linux x64 #build win32 ia32 ================================================ FILE: scripts/build-win32.bat ================================================ set PLATFORM=%1% set ARCH=%2% set APP_NAME="Electronic WeChat" set ignore_list="dist|scripts|\.idea|.*\.md|.*\.yml|node_modules/nodejieba" electron-packager . "%APP_NAME%" --platform=%PLATFORM% --arch=%ARCH% --electronVersion=1.4.15 --app-version=1.4.0 --asar --icon=assets\icon.png --overwrite --out=.\dist --ignore=%ignore_list% ================================================ FILE: scripts/build.sh ================================================ #!/bin/bash if ! hash electron-packager 2>/dev/null; then RED='\033[0;31m' NC='\033[0m' echo "${RED}Error${NC}: you need to npm install electron-packager. Aborting." exit 1 fi if [ "$#" -ne 2 ]; then echo -e "Usage: ./script/build.sh " echo -e " platform: darwin, linux, win32" echo -e " arch: ia32, x64" exit 1 fi PLATFORM=$1 ARCH=$2 echo "Start packaging for $PLATFORM $ARCH." if [ $PLATFORM = "linux" ]; then APP_NAME="electronic-wechat" else APP_NAME="Electronic WeChat" fi ignore_list="dist|scripts|\.idea|.*\.md|.*\.yml|node_modules/nodejieba" electron-packager . "${APP_NAME}" --platform=$PLATFORM --arch=$ARCH --electronVersion=1.4.15 --app-version=1.4.0 --asar --icon=assets/icon.icns --overwrite --out=./dist --ignore=${ignore_list} if [ $? -eq 0 ]; then echo -e "$(tput setaf 2)Packaging for $PLATFORM $ARCH succeeded.$(tput sgr0)\n" fi if [ $PLATFORM = "darwin" ]; then ditto -rsrcFork ./dist/Electronic\ WeChat-darwin-x64/Electronic\ WeChat.app /Applications/Electronic\ WeChat.app echo "$(tput setaf 3)App copied to /Applications. You can open Electronic WeChat there or from Spotlight.$(tput sgr0)" fi ================================================ FILE: scripts/qiniu.sh ================================================ #!/bin/bash case "$(uname -s)" in Linux*) wget http://devtools.qiniu.com/qiniu-devtools-linux_amd64-current.tar.gz -O dist/qiniu-devtools.tar.gz ;; Darwin) wget http://devtools.qiniu.io/qiniu-devtools-darwin_amd64-current.tar.gz -O dist/qiniu-devtools.tar.gz ;; *) ;; esac mkdir dist/qiniu-devtools tar -xvf dist/qiniu-devtools.tar.gz -C dist/qiniu-devtools rm -rf /tmp/qiniu mkdir /tmp/qiniu cp dist/mac-osx.tar.gz /tmp/qiniu cp dist/linux-x64.tar.gz /tmp/qiniu cp dist/linux-ia32.tar.gz /tmp/qiniu echo '{ "src": "/tmp/qiniu", "dest": "qiniu:access_key='$QINIU_ACCESS_KEY'&secret_key='$QINIU_SECRET_KEY'&bucket=flymeos-cancro", "debug_level": 1 }' > qiniu-config.json ./dist/qiniu-devtools/qrsync qiniu-config.json ================================================ FILE: scripts/tar-all.sh ================================================ #!/bin/bash cd dist echo 'Start compressing for Mac OS X.' tar zcf 'mac-osx.tar.gz' 'Electronic WeChat-darwin-x64' echo 'Compressing for Mac OS X succeed.' echo 'Start compressing for Linux x64.' tar zcf 'linux-x64.tar.gz' 'electronic-wechat-linux-x64' echo 'Compressing for Linux x64 succeed.' echo 'Start compressing for Linux ia32.' tar zcf 'linux-ia32.tar.gz' 'electronic-wechat-linux-ia32' echo 'Compressing for Linux ia32 succeed.' cd .. ================================================ FILE: src/common.js ================================================ /** * Created by Zhongyi on 3/26/16. */ 'use strict'; class Common { } Common.ELECTRON = 'Electron'; Common.ELECTRONIC_WECHAT = 'Electronic WeChat'; Common.DEBUG_MODE = false; Common.WINDOW_SIZE = { width: 800, height: 600, }; Common.WINDOW_SIZE_LOGIN = { width: 380, height: 540, }; Common.WINDOW_SIZE_LOADING = { width: 380, height: 120, }; Common.WINDOW_SIZE_SETTINGS = { width: 800, height: 600, }; Common.USER_AGENT = { freebsd: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', sunos: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', win32: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', linux: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 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', }; Common.WEB_WECHAT = 'https://wx.qq.com/?lang=en_US'; Common.GITHUB = 'https://github.com/geeeeeeeeek/electronic-wechat'; Common.GITHUB_RELEASES = 'https://github.com/geeeeeeeeek/electronic-wechat/releases'; Common.GITHUB_ISSUES = 'https://github.com/geeeeeeeeek/electronic-wechat/issues'; Common.GITHUB_API_HOST = 'api.github.com'; Common.GITHUB_API_RELEASE_LATEST_PATH = '/repos/geeeeeeeeek/electronic-wechat/releases/latest'; 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}`; Common.UPDATE_ERROR_EMPTY_RESPONSE = 'Failed to fetch release info.'; Common.UPDATE_ERROR_UNKNOWN = 'Something went wrong.'; Common.UPDATE_NA_TITLE = 'No Update Available'; Common.UPDATE_ERROR_NETWORK = 'Connection hang up unexpectedly. Check your network settings.'; Common.UPDATE_ERROR_LATEST = (version) => { return `You are using the latest version(${version}).`; }; Common.MENTION_MENU_INITIAL_X = 300; Common.MENTION_MENU_OFFSET_X = 30; Common.MENTION_MENU_INITIAL_Y = 140; Common.MENTION_MENU_OFFSET_Y = 45; Common.MENTION_MENU_WIDTH = 120; Common.MENTION_MENU_OPTION_HEIGHT = 30; Common.MENTION_MENU_OPTION_DEFAULT_NUM = 4; Common.MENTION_MENU_HINT_TEXT = 'Mention:'; Common.MESSAGE_PREVENT_RECALL = 'Blocked a message recall.'; Common.EMOJI_MAXIUM_SIZE = 120; Common.languageTitle = 'Language(Need to Restart)'; Common.languageDesc = 'Select a default language for WeChat!'; Common.recallTitle = 'Prevent Message Recall'; Common.recallDesc = 'Message recall feature might be annoying'; Common.instanceTitle = 'Allow Multiple Instance'; Common.instanceDesc = 'Multiple instance can login with different accounts'; Common.iconTitle = 'File Path (In Development)'; Common.iconDesc = 'Set a default file path'; Common.trayTitle = 'Tray Icon color (Black/White)'; Common.trayDesc = 'Select a color to match your desktop theme'; Common.UPGRADE = 'UPGRADE'; Common.FEEDBACK = 'FEEDBACK'; Common.MENU = { about: 'About Electronic Wechat', service: 'Service', hide: 'Hide Application', hideOther: 'Hide Others', showAll: 'Show All', pref: 'Preference', quit: 'Quit', edit: 'Edit', undo: 'Undo', redo: 'Redo', cut: 'Cut', copy: 'Copy', paste: 'Paste', selectAll: 'Select All', view: 'View', reload: 'Reload This Window', toggleFullScreen: 'Toggle Full Screen', searchContacts: 'Search Contacts', devtool: 'Toggle DevTools', window: 'Window', min: 'Minimize', close: 'Close', allFront: 'Bring All to Front', help: 'Help', repo: 'GitHub Repository', feedback: 'Report Issue', checkRelease: 'Check for New Release', }; module.exports = Common; ================================================ FILE: src/common_cn.js ================================================ /** * Created by Zhongyi on 3/26/16. */ 'use strict'; class Common { } Common.ELECTRON = 'Electron'; Common.ELECTRONIC_WECHAT = 'Electronic WeChat'; Common.DEBUG_MODE = false; Common.WINDOW_SIZE = { width: 800, height: 600, }; Common.WINDOW_SIZE_LOGIN = { width: 380, height: 540, }; Common.WINDOW_SIZE_LOADING = { width: 380, height: 120, }; Common.WINDOW_SIZE_SETTINGS = { width: 800, height: 600, }; Common.USER_AGENT = { 'freebsd': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 'sunos': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 'win32': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', 'linux': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36', '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' } Common.WEB_WECHAT = 'https://wx.qq.com/?lang=zh_CN'; Common.GITHUB = 'https://github.com/geeeeeeeeek/electronic-wechat'; Common.GITHUB_RELEASES = 'https://github.com/geeeeeeeeek/electronic-wechat/releases'; Common.GITHUB_ISSUES = 'https://github.com/geeeeeeeeek/electronic-wechat/issues'; Common.GITHUB_API_HOST = 'api.github.com'; Common.GITHUB_API_RELEASE_LATEST_PATH = '/repos/geeeeeeeeek/electronic-wechat/releases/latest'; 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; Common.UPDATE_ERROR_EMPTY_RESPONSE = '没能获取最新的更新信息'; Common.UPDATE_ERROR_UNKNOWN = '不造什么出错了...'; Common.UPDATE_NA_TITLE = '没有可用的更新'; Common.UPDATE_ERROR_NETWORK = '网络连接出错,请检查你的网络'; Common.UPDATE_ERROR_LATEST = (version) => { return `已经在使用最新版 - (${version})`; }; Common.MENTION_MENU_INITIAL_X = 300; Common.MENTION_MENU_OFFSET_X = 30; Common.MENTION_MENU_INITIAL_Y = 140; Common.MENTION_MENU_OFFSET_Y = 45; Common.MENTION_MENU_WIDTH = 120; Common.MENTION_MENU_OPTION_HEIGHT = 30; Common.MENTION_MENU_OPTION_DEFAULT_NUM = 4; Common.MENTION_MENU_HINT_TEXT = '选择回复的人:'; Common.MESSAGE_PREVENT_RECALL = '阻止了一次撤回'; Common.EMOJI_MAXIUM_SIZE = 120; Common.MENU = { about: '关于 Electronic Wechat', service: '服务', hide: '隐藏应用', hideOther: '隐藏其他窗口', showAll: '显示全部窗口', pref: '偏好', quit: '退出', edit: '编辑', undo: '撤销', redo: '取消撤销', cut: '剪切', copy: '复制', paste: '粘贴', selectAll: '选择全部', view: '视图', reload: '重新加载当前窗口', toggleFullScreen:'切换全屏', searchContacts:'搜索联系人', devtool: '开发者工具', window: '窗口', min: '最小化', close: '关闭', allFront: '全部打开', help: '帮助', repo: 'GitHub 目录', feedback: '联系我们', checkRelease: '检查更新', }; module.exports = Common; ================================================ FILE: src/configuration.js ================================================ 'use strict'; function getUserHome() { return process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME']; } const nconf = require('nconf').file({ file: `${getUserHome()}/.ew.json`, }); function saveSettings(settingKey, settingValue) { nconf.set(settingKey, settingValue); nconf.save(); } function readSettings(settingKey) { nconf.load(); return nconf.get(settingKey); } module.exports = { saveSettings, readSettings, }; ================================================ FILE: src/handlers/menu.js ================================================ 'use strict'; const { remote, shell, ipcRenderer } = require('electron'); const AppConfig = require('../configuration'); const { Menu, app } = remote; const lan = AppConfig.readSettings('language'); let Common; if (lan === 'zh-CN') { Common = require('../common_cn'); } else { Common = require('../common'); } class MenuHandler { create() { const template = this.getTemplate(remote.process.platform); if (template) { const menuFromTemplate = Menu.buildFromTemplate(template); Menu.setApplicationMenu(menuFromTemplate); } } getTemplate(platform) { const darwinTemplate = [ { label: Common.ELECTRONIC_WECHAT, submenu: [ { label: Common.MENU.about, selector: 'orderFrontStandardAboutPanel:', }, { type: 'separator', }, { label: Common.MENU.service, submenu: [], }, { type: 'separator', }, { label: Common.MENU.hide, accelerator: 'Command+H', selector: 'hide:', }, { label: Common.MENU.hideOther, accelerator: 'Command+Alt+H', selector: 'hideOtherApplications:', }, { label: Common.MENU.showAll, selector: 'unhideAllApplications:', }, { type: 'separator', }, { label: Common.MENU.pref, click: MenuHandler._preference, }, { type: 'separator', }, { label: Common.MENU.quit, accelerator: 'Command+Q', click: MenuHandler._quitApp, }, ], }, { label: Common.MENU.edit, submenu: [ { label: Common.MENU.undo, accelerator: 'Command+Z', selector: 'undo:', }, { label: Common.MENU.redo, accelerator: 'Shift+Command+Z', selector: 'redo:', }, { type: 'separator', }, { label: Common.MENU.cut, accelerator: 'Command+X', selector: 'cut:', }, { label: Common.MENU.copy, accelerator: 'Command+C', selector: 'copy:', }, { label: Common.MENU.paste, accelerator: 'Command+V', selector: 'paste:', }, { label: Common.MENU.selectAll, accelerator: 'Command+A', selector: 'selectAll:', }, { type: 'separator', }, { label: Common.MENU.searchContacts, accelerator: 'Command+F', click: () => { $('#search_bar input')[0].focus(); }, }, ], }, { label: Common.MENU.view, submenu: [ { label: Common.MENU.reload, accelerator: 'Command+R', click: MenuHandler._reload, }, { label: Common.MENU.devtool, accelerator: 'Alt+Command+I', click: MenuHandler._devTools, }, ], }, { label: Common.MENU.window, submenu: [ { label: Common.MENU.min, accelerator: 'Command+M', selector: 'performMiniaturize:', }, { label: Common.MENU.close, accelerator: 'Command+W', selector: 'performClose:', }, { label: Common.MENU.toggleFullScreen, accelerator: 'Ctrl+Command+F', click: (item, focusedWindow) => { if (focusedWindow) { focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); } }, }, { type: 'separator', }, { label: Common.MENU.allFront, selector: 'arrangeInFront:', }, ], }, { label: Common.MENU.help, submenu: [ { label: Common.MENU.repo, click: MenuHandler._github, }, { type: 'separator', }, { label: Common.MENU.feedback, click: MenuHandler._githubIssues, }, { label: Common.MENU.checkRelease, click: MenuHandler._update, }], }, ]; const linuxTemplate = [ { label: Common.MENU.window, submenu: [ { label: Common.MENU.pref, click: MenuHandler._preference, }, { label: Common.MENU.reload, accelerator: 'Ctrl+R', click: MenuHandler._reload, }, { label: Common.MENU.toggleFullScreen, accelerator: 'F11', click: (item, focusedWindow) => { if (focusedWindow) { focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); } }, }, { type: 'separator', }, { label: Common.MENU.searchContacts, accelerator: 'Ctrl+F', click: () => { $('#search_bar input')[0].focus(); }, }, { label: Common.MENU.devtool, accelerator: 'Ctrl+Shift+I', click: MenuHandler._devTools, }, { type: 'separator', }, { label: Common.MENU.quit, accelerator: 'Ctrl+Q', click: MenuHandler._quitApp, }, ], }, { label: Common.MENU.help, submenu: [ { label: Common.MENU.repo, click: MenuHandler._github, }, { type: 'separator', }, { label: Common.MENU.feedback, click: MenuHandler._githubIssues, }, { label: Common.MENU.checkRelease, click: MenuHandler._update, }], }, ]; if (platform === 'darwin') { return darwinTemplate; } else if (platform === 'linux') { return linuxTemplate; } } static _quitApp() { app.exit(0); } static _reload() { ipcRenderer.send('reload'); } static _devTools() { remote.getCurrentWindow().toggleDevTools(); } static _github() { shell.openExternal(Common.GITHUB); } static _githubIssues() { shell.openExternal(Common.GITHUB_ISSUES); } static _update() { ipcRenderer.send('update'); } static _preference() { ipcRenderer.send('open-settings-window'); } } module.exports = MenuHandler; ================================================ FILE: src/handlers/message.js ================================================ 'use strict'; const qs = require('querystring'); const url = require('url'); class MessageHandler { handleRedirectMessage(origin) { return qs.parse(url.parse(origin).query).requrl || origin; } } module.exports = MessageHandler; ================================================ FILE: src/handlers/update.js ================================================ /** * Created by Zhongyi on 3/25/16. */ 'use strict'; const { dialog, shell, app, nativeImage } = require('electron'); const AppConfig = require('../configuration'); const https = require('https'); const path = require('path'); const lan = AppConfig.readSettings('language'); let Common; if (lan === 'zh-CN') { Common = require('../common_cn'); } else { Common = require('../common'); } class UpdateHandler { checkForUpdate(version, silent) { UpdateHandler.CHECKED = true; const promise = new Promise((res, rej) => { if (Common.ELECTRON === app.getName()) { rej(Common.UPDATE_ERROR_ELECTRON); } const req = https.get({ host: Common.GITHUB_API_HOST, headers: { 'user-agent': Common.USER_AGENT }, path: Common.GITHUB_API_RELEASE_LATEST_PATH, }, (response) => { let body = ''; response.on('data', (d) => { body += d; }); response.on('end', () => { this._parseUpdateData(body, version, res, rej); }); }); req.on('error', (err) => { rej(Common.UPDATE_ERROR_NETWORK); }); req.end(); }).then((fetched) => { this.showDialog(fetched.name, fetched.description, 'Update', (response) => { if (!response) return; shell.openExternal(fetched.url); }); }).catch((message) => { if (silent) return; if (!message) { message = Common.UPDATE_ERROR_UNKNOWN; } this.showDialog(Common.UPDATE_NA_TITLE, message, 'OK'); }); } showDialog(message, detail, positiveButton, callback) { const iconImage = nativeImage.createFromPath(path.join(__dirname, '../assets/icon.png')); dialog.showMessageBox({ type: 'info', buttons: ['Cancel', positiveButton], defaultId: 1, cancelId: 0, title: message, message, detail, icon: iconImage, }, callback); } _parseUpdateData(body, version, res, rej) { const data = JSON.parse(body); if (!data || !data.tag_name) rej(Common.UPDATE_ERROR_EMPTY_RESPONSE); const fetched = { version: data.tag_name, is_prerelease: data.prerelease, name: data.name, url: data.html_url, description: data.body, }; const versionRegex = /^v[0-9]+\.[0-9]+\.*[0-9]*$/; if (versionRegex.test(fetched.version) && fetched.version > version && !fetched.is_prerelease) { res(fetched); } else { rej(Common.UPDATE_ERROR_LATEST(version)); } } } UpdateHandler.CHECKED = false; module.exports = UpdateHandler; ================================================ FILE: src/inject/badge_count.js ================================================ /** * Created by Zhongyi on 4/12/16. */ 'use strict'; const { ipcRenderer } = require('electron'); class BadgeCount { static init() { setInterval(() => { let count = 0; $('.icon.web_wechat_reddot_middle').each(function () { count += parseInt(this.textContent, 10); }); if (count > 0) { ipcRenderer.send('badge-changed', count.toString()); } else { ipcRenderer.send('badge-changed', ''); } }, 1500); } } module.exports = BadgeCount; ================================================ FILE: src/inject/css.js ================================================ /** * Created by Zhongyi on 2/23/16. */ 'use strict'; const Common = require('../common'); class CSSInjector { } CSSInjector.commonCSS = ` div.header, div.title_wrap { -webkit-app-region: drag; } div.title.poi { -webkit-app-region: no-drag; } div.header .avatar, div.header .info { -webkit-app-region: no-drag; } div.main { height: 100% !important; min-height: 0 !important; padding-top: 0 !important; } div.main_inner { max-width: none !important; min-width: 0 !important; } div.message_empty { margin-top: 50px; } div.img_preview_container div.img_opr_container { bottom: 50px !important; } p.copyright { display: none !important } a.web_wechat_screencut { display: none !important; } * { -webkit-user-select: none; cursor: default !important; -webkit-user-drag: none; } pre, input { -webkit-user-select: initial; cursor: initial !important; } html, body { width: 100%; height: 100%; overflow: hidden; } div.login_box { top: initial; left: initial; margin-left: initial; margin-top: initial; width: 100%; height: 100%; } div.login { min-width: 0; min-height: 0; width: 100%; height: 100%; overflow: hidden; } div.lang, div.copyright { display: none !important } /* Group mention: user selection box */ div#userSelectionBox select option:hover { background: #eeeeee; } div#userSelectionBox select option { padding: 4px 10px; text-overflow: hidden; font-size: 14px; } .user_select_hint_text { padding: 4px 10px; font-size: 14px; background: #eeeeee; } div#userSelectionBox select { width: 120px; border: none; outline: none; height: inherit; } div#userSelectionBox { box-shadow: 1px 1px 10px #ababab; background: #fff; display: none; position: fixed; bottom: ${Common.MENTION_MENU_INITIAL_Y}px; left: ${Common.MENTION_MENU_INITIAL_X}px; } span.measure_text { padding-left: 20px; outline: 0; border: 0; font-size: 14px; } img.emojione { width: 20px; height: 20px; } @media (max-width: 512px) { .panel { width: 75px !important; transition: width .3s; } .panel .header, .chat_item { padding: 8px 16px !important; } .header, .panel .tab, .search_bar, .chat_item .info, .chat_item .ext { display: none !important } .nav_view { top: 36px !important } .chat_item.active { border-left: 2px solid #02b300 !important } } `; CSSInjector.osxCSS = ` div.header div.avatar img.img { width: 24px; height: 24px; } div.header { padding-top: 38px; padding-bottom: 8px; } span.display_name { width: 172px !important; } @media (max-width: 512px) { .nav_view { top: 36px !important } } `; module.exports = CSSInjector; ================================================ FILE: src/inject/emoji_parser.js ================================================ /** * Created by chenwl on 9/29/16. */ var emojione = require('emojione'); // const emojiSpanRegex = /<\/span>/g; function unicodeToString(point) { const offset = point - 0x10000; const lead = 0xd800 + (offset >> 10); const trail = 0xdc00 + (offset & 0x3ff); return String.fromCharCode(lead, trail); } class EmojiParser { static emojiSpanToString(str) { return str.replace(emojiSpanRegex, function(span, emojiHex) { const point = parseInt(emojiHex, 16); return unicodeToString(point); }); } static emojiToImage(str) { return emojione.unicodeToImage(EmojiParser.emojiSpanToString(str)); } } module.exports = EmojiParser; ================================================ FILE: src/inject/mention_menu.js ================================================ /** * Created by Zhongyi on 4/9/16. */ 'use strict'; const Common = require('../common'); const pinyin = require('pinyin'); class MentionMenu { static init() { const $box = $('
'); const $div = $('
'); $div.html(Common.MENTION_MENU_HINT_TEXT); $div.addClass('user_select_hint_text'); $box.append($div); const $select = $('
================================================ FILE: src/windows/views/splash.html ================================================ Starting App
Starting App