├── .gitignore ├── README.md ├── config.json ├── icon └── tray.png ├── main.js ├── package.json ├── scripts ├── build-all.sh ├── build.sh └── tar-all.sh └── server ├── .babelrc ├── config ├── font-awesome.config.js ├── font-awesome.config.less ├── webpack.dev.js └── webpack.prod.js ├── dist ├── 19111266e755d44793e231f12028306d.png ├── 32400f4e08932a94d8bfd2422702c446.eot ├── a35720c2fed2c7f043bc7e4ffb45e073.woff ├── a3de2170e4e9df77161ea5d3f31b2668.ttf ├── app.bundle.js ├── app.css ├── assets │ └── img │ │ ├── default.png │ │ └── logo.png ├── db812d8a70a4e88e888744c1c9a27e89.woff2 ├── f775f9cca88e21d45bebe185b27c0e5b.svg ├── index.html └── vendor.bundle.js ├── package.json └── src ├── assets └── img │ ├── default.png │ └── logo.png ├── controllers ├── index.js ├── index │ └── index.js └── story │ └── story.js ├── css └── main.scss ├── index.html ├── main.js ├── routes.js ├── utils └── storage.js └── vendor.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZhihuDaily for Desktop 2 | 3 | ## About 4 | 5 | A ZhihuDaily desktop application for Mac OS X, Windows and Linux. Powered by [Electron](https://github.com/atom/electron). 6 | 7 | **NOTE:** This is a **community** release, not official. 8 | 9 | **NOTE:** This app is still under **development**. 10 | 11 | ## Supported Platforms 12 | 13 | * OS X (mainly tested) 14 | * Linux (x86/x86_64) (partly tested) 15 | * Windows (32/64 bit) (should work) 16 | 17 | ## Installation 18 | 19 | # Clone the project via `git` 20 | $ git clone https://github.com/DIYgod/ZhihuDaily-for-Desktop.git 21 | 22 | # or directly download from 23 | # https://github.com/DIYgod/ZhihuDaily-for-Desktop/releases 24 | 25 | # switch to server directory, and build scripts 26 | $ cd ZhihuDaily-for-Desktop/server 27 | $ npm i 28 | 29 | # for development use 30 | $ npm run build 31 | 32 | # otherwise 33 | $ npm run build:prod 34 | 35 | # switch back to project root path, start our app 36 | $ cd .. 37 | $ npm i 38 | $ npm start 39 | 40 | ## Contribution 41 | 42 | Ask questions via: https://github.com/DIYgod/ZhihuDaily-for-Desktop/issues 43 | 44 | Share your code via: https://github.com/DIYgod/ZhihuDaily-for-Desktop/pulls 45 | 46 | ## LICENSE 47 | 48 | MIT © [DIYgod](http://github.com/DIYgod) -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "osx" : { 3 | "title": "知乎日报", 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 | } -------------------------------------------------------------------------------- /icon/tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/icon/tray.png -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const electron = require('electron'); 4 | const app = electron.app; 5 | const BrowserWindow = electron.BrowserWindow; 6 | const Menu = electron.Menu; 7 | const Tray = electron.Tray; 8 | 9 | let mainWindow = null; 10 | var appIcon = null; 11 | 12 | function createWindow() { 13 | mainWindow = new BrowserWindow({ 14 | title: '知乎日报', 15 | // icon: 'icon.png', 16 | width: 970, 17 | height: 650, 18 | minWidth: 970, 19 | minHeight: 650, 20 | resizable: true, 21 | center: true, 22 | show: true, 23 | frame: true, 24 | autoHideMenuBar: true, 25 | titleBarStyle: 'hidden-inset', 26 | 'web-preferences': { 27 | javascript: true, 28 | plugins: true, 29 | // nodeIntegration: false, 30 | webSecurity: false 31 | // preload: __dirname + '/inject-preload.js' 32 | } 33 | }); 34 | 35 | mainWindow.loadURL('file://' + __dirname + '/server/dist/index.html'); // Todo 36 | 37 | // Open Developer Tool 38 | mainWindow.webContents.openDevTools(); 39 | 40 | mainWindow.on('closed', function () { 41 | mainWindow = null; 42 | }); 43 | 44 | // Tray icon 45 | // appIcon = new Tray('icon/tray.png'); 46 | // appIcon.setToolTip('This is my application.'); 47 | 48 | } 49 | 50 | app.on('ready', createWindow); 51 | 52 | app.on('window-all-closed', function () { 53 | if (process.platform !== 'darwin') { 54 | app.quit(); 55 | } 56 | }); 57 | 58 | app.on('activate', function () { 59 | if (mainWindow === null) { 60 | createWindow(); 61 | } 62 | }); 63 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zhihudaily", 3 | "productName": "ZhihuDaily for Desktop", 4 | "version": "0.0.1", 5 | "description": "A ZhihuDaily client on Mac OS X, Windows and Linux.", 6 | "main": "main.js", 7 | "scripts": { 8 | "start": "electron main.js", 9 | "dev": "electron --debug=5858 main.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/DIYgod/ZhihuDaily-for-Desktop" 14 | }, 15 | "keywords": [ 16 | "ZhihuDaily", 17 | "zhihu", 18 | "electron", 19 | "知乎" 20 | ], 21 | "author": "DIYgod", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/DIYgod/ZhihuDaily-for-Desktop/issues" 25 | }, 26 | "homepage": "https://github.com/DIYgod/ZhihuDaily-for-Desktop#readme", 27 | "devDependencies": { 28 | "electron-prebuilt": "^0.37.2" 29 | }, 30 | "dependencies": {} 31 | } 32 | -------------------------------------------------------------------------------- /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 ia32 16 | build linux x64 17 | #build win32 ia32 18 | -------------------------------------------------------------------------------- /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 | electron-packager . "Electronic WeChat" --platform=$PLATFORM --arch=$ARCH --version=0.36.9 --icon=assets/icon.icns --overwrite --out=./dist --ignore=./dist 23 | 24 | if [ $? -eq 0 ]; then 25 | echo -e "Packaging for $PLATFORM $ARCH succeeded.\n" 26 | fi 27 | -------------------------------------------------------------------------------- /scripts/tar-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 'Start compressing for Mac OS X.' 4 | tar zcf 'dist/mac-osx.tar.gz' 'dist/Electronic WeChat-darwin-x64' 5 | echo 'Compressing for Mac OS X succeed.' 6 | 7 | echo 'Start compressing for Linux x64.' 8 | tar zcf 'dist/linux-x64.tar.gz' 'dist/Electronic WeChat-linux-x64' 9 | echo 'Compressing for Linux x64 succeed.' 10 | 11 | echo 'Start compressing for Linux ia32.' 12 | tar zcf 'dist/linux-ia32.tar.gz' 'dist/Electronic WeChat-linux-ia32' 13 | echo 'Compressing for Linux ia32 succeed.' 14 | -------------------------------------------------------------------------------- /server/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react", 4 | "es2015" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /server/config/font-awesome.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuration file for font-awesome-webpack 3 | * 4 | * In order to keep the bundle size low in production, 5 | * disable components you don't use. 6 | * 7 | */ 8 | 9 | module.exports = { 10 | styles: { 11 | mixins: true, 12 | core: true, 13 | icons: true, 14 | larger: true, 15 | path: true, 16 | animated: true, 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /server/config/font-awesome.config.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuration file for font-awesome-webpack 3 | * 4 | */ 5 | 6 | // Example: 7 | // @fa-border-color: #ddd; 8 | -------------------------------------------------------------------------------- /server/config/webpack.dev.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var autoprefixer = require('autoprefixer'); 4 | 5 | /** 6 | * Webpack Plugins 7 | */ 8 | var CopyWebpackPlugin = require('copy-webpack-plugin'); 9 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 10 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 11 | 12 | /** 13 | * Webpack configuration 14 | * 15 | * See: http://webpack.github.io/docs/configuration.html#cli 16 | */ 17 | module.exports = { 18 | 19 | // Switch loaders to debug mode. 20 | // 21 | // See: http://webpack.github.io/docs/configuration.html#debug 22 | debug: true, 23 | 24 | // Developer tool to enhance debugging 25 | // 26 | // See: http://webpack.github.io/docs/configuration.html#devtool 27 | // See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps 28 | devtool: 'cheap-module-eval-source-map', 29 | 30 | // Cache generated modules and chunks to improve performance for multiple incremental builds. 31 | // This is enabled by default in watch mode. 32 | // You can pass false to disable it. 33 | // 34 | // See: http://webpack.github.io/docs/configuration.html#cache 35 | // cache: false, 36 | 37 | // The entry point for the bundle 38 | // 39 | // See: http://webpack.github.io/docs/configuration.html#entry 40 | entry: { 41 | 42 | 'app': './src/main.js', 43 | 44 | 'vendor': [ 45 | './src/vendor.js', 46 | 47 | // See: https://github.com/gowravshekar/font-awesome-webpack 48 | 'font-awesome-webpack!./config/font-awesome.config.js' 49 | ] 50 | 51 | }, 52 | 53 | // Options affecting the resolving of modules. 54 | // 55 | // See: http://webpack.github.io/docs/configuration.html#resolve 56 | resolve: { 57 | 58 | // An array of extensions that should be used to resolve modules. 59 | // 60 | // See: http://webpack.github.io/docs/configuration.html#resolve-extensions 61 | extensions: ['', '.js'], 62 | 63 | // Make sure root is src 64 | root: path.resolve(__dirname, '../src') 65 | 66 | }, 67 | 68 | // Options affecting the output of the compilation. 69 | // 70 | // See: http://webpack.github.io/docs/configuration.html#output 71 | output: { 72 | 73 | // The output directory as absolute path (required). 74 | // 75 | // See: http://webpack.github.io/docs/configuration.html#output-path 76 | path: path.resolve(__dirname, '../dist'), 77 | 78 | // Specifies the name of each output file on disk. 79 | // IMPORTANT: You must not specify an absolute path here! 80 | // 81 | // See: http://webpack.github.io/docs/configuration.html#output-filename 82 | filename: '[name].bundle.js', 83 | 84 | // The filename of the SourceMaps for the JavaScript files. 85 | // They are inside the output.path directory. 86 | // 87 | // See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename 88 | sourceMapFilename: '[name].map', 89 | 90 | // The filename of non-entry chunks as relative path 91 | // inside the output.path directory. 92 | // 93 | // See: http://webpack.github.io/docs/configuration.html#output-chunkfilename 94 | chunkFilename: '[id].chunk.js' 95 | 96 | }, 97 | // Options affecting the normal modules. 98 | // 99 | // See: http://webpack.github.io/docs/configuration.html#module 100 | module: { 101 | 102 | // An array of automatically applied loaders. 103 | // 104 | // IMPORTANT: The loaders here are resolved relative to the resource which they are applied to. 105 | // This means they are not resolved relative to the configuration file. 106 | // 107 | // See: http://webpack.github.io/docs/configuration.html#module-loaders 108 | loaders: [ 109 | 110 | // Transform ES6 to ES5 111 | // 112 | // See: https://github.com/babel/babel-loader 113 | {test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, 114 | 115 | // transform *.scss to css, then inline to 116 | { 117 | test: /\.scss$/, 118 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader!sass-loader') 119 | }, 120 | 121 | // Raw loader support for *.html 122 | // Returns file content as string 123 | // 124 | // See: https://github.com/webpack/raw-loader 125 | {test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(__dirname, '../src/index.html')]}, 126 | 127 | {test: /\.png$/, loader: 'url?limit=10000'}, 128 | 129 | // font-awesome 130 | // 131 | // the url-loader uses DataUrls. 132 | // the file-loader emits files. 133 | {test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff"}, 134 | {test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader"} 135 | 136 | ] 137 | 138 | }, 139 | 140 | // Add additional plugins to the compiler. 141 | // 142 | // See: http://webpack.github.io/docs/configuration.html#plugins 143 | plugins: [ 144 | 145 | // Plugin: OccurenceOrderPlugin 146 | // Description: Varies the distribution of the ids to get the smallest id length 147 | // for often used ids. 148 | // 149 | // See: https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin 150 | // See: https://github.com/webpack/docs/wiki/optimization#minimize 151 | new webpack.optimize.OccurenceOrderPlugin(true), 152 | 153 | // Plugin: CommonsChunkPlugin 154 | // Description: Shares common code between the pages. 155 | // It identifies common modules and put them into a commons chunk. 156 | // 157 | // See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin 158 | // See: https://github.com/webpack/docs/wiki/optimization#multi-page-app 159 | new webpack.optimize.CommonsChunkPlugin({name: ['app', 'vendor'], minChunks: Infinity}), 160 | 161 | // Plugin: CopyWebpackPlugin 162 | // Description: Copy files and directories in webpack. 163 | // 164 | // Copies project static assets. 165 | // 166 | // See: https://www.npmjs.com/package/copy-webpack-plugin 167 | new CopyWebpackPlugin([{from: 'src/assets', to: 'assets'}]), 168 | 169 | // Plugin: HtmlWebpackPlugin 170 | // Description: Simplifies creation of HTML files to serve your webpack bundles. 171 | // This is especially useful for webpack bundles that include a hash in the filename 172 | // which changes every compilation. 173 | // 174 | // See: https://github.com/ampedandwired/html-webpack-plugin 175 | new HtmlWebpackPlugin({template: 'src/index.html', chunksSortMode: 'none', inject: true}), 176 | 177 | // Plugin: ExtractTextPlugin 178 | // Description: extract all compiled css into file (*.css) 179 | // 180 | // See: https://github.com/webpack/extract-text-webpack-plugin 181 | new ExtractTextPlugin('[name].css', {allChunks: true}) 182 | 183 | ], 184 | 185 | postcss: [autoprefixer] 186 | 187 | }; 188 | -------------------------------------------------------------------------------- /server/config/webpack.prod.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var autoprefixer = require('autoprefixer'); 4 | 5 | /** 6 | * Webpack Plugins 7 | */ 8 | var CopyWebpackPlugin = require('copy-webpack-plugin'); 9 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 10 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 11 | 12 | /** 13 | * Webpack configuration 14 | * 15 | * See: http://webpack.github.io/docs/configuration.html#cli 16 | */ 17 | module.exports = { 18 | 19 | // Switch loaders to debug mode. 20 | // 21 | // See: http://webpack.github.io/docs/configuration.html#debug 22 | debug: false, 23 | 24 | // Developer tool to enhance debugging 25 | // 26 | // See: http://webpack.github.io/docs/configuration.html#devtool 27 | // See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps 28 | devtool: 'source-map', 29 | 30 | // Cache generated modules and chunks to improve performance for multiple incremental builds. 31 | // This is enabled by default in watch mode. 32 | // You can pass false to disable it. 33 | // 34 | // See: http://webpack.github.io/docs/configuration.html#cache 35 | // cache: false, 36 | 37 | // The entry point for the bundle 38 | // 39 | // See: http://webpack.github.io/docs/configuration.html#entry 40 | entry: { 41 | 42 | 'app': './src/main.js', 43 | 44 | 'vendor': [ 45 | './src/vendor.js', 46 | 47 | // See: https://github.com/gowravshekar/font-awesome-webpack 48 | 'font-awesome-webpack!./config/font-awesome.config.js' 49 | ] 50 | 51 | }, 52 | 53 | // Options affecting the resolving of modules. 54 | // 55 | // See: http://webpack.github.io/docs/configuration.html#resolve 56 | resolve: { 57 | 58 | // An array of extensions that should be used to resolve modules. 59 | // 60 | // See: http://webpack.github.io/docs/configuration.html#resolve-extensions 61 | extensions: ['', '.js'], 62 | 63 | // Make sure root is src 64 | root: path.resolve(__dirname, '../src') 65 | 66 | }, 67 | 68 | // Options affecting the output of the compilation. 69 | // 70 | // See: http://webpack.github.io/docs/configuration.html#output 71 | output: { 72 | 73 | // The output directory as absolute path (required). 74 | // 75 | // See: http://webpack.github.io/docs/configuration.html#output-path 76 | path: path.resolve(__dirname, '../dist'), 77 | 78 | // Specifies the name of each output file on disk. 79 | // IMPORTANT: You must not specify an absolute path here! 80 | // 81 | // See: http://webpack.github.io/docs/configuration.html#output-filename 82 | filename: '[name].[chunkhash].bundle.js', 83 | 84 | // The filename of the SourceMaps for the JavaScript files. 85 | // They are inside the output.path directory. 86 | // 87 | // See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename 88 | sourceMapFilename: '[name].[chunkhash].map', 89 | 90 | // The filename of non-entry chunks as relative path 91 | // inside the output.path directory. 92 | // 93 | // See: http://webpack.github.io/docs/configuration.html#output-chunkfilename 94 | chunkFilename: '[id].[chunkhash].chunk.js' 95 | 96 | }, 97 | // Options affecting the normal modules. 98 | // 99 | // See: http://webpack.github.io/docs/configuration.html#module 100 | module: { 101 | 102 | // An array of automatically applied loaders. 103 | // 104 | // IMPORTANT: The loaders here are resolved relative to the resource which they are applied to. 105 | // This means they are not resolved relative to the configuration file. 106 | // 107 | // See: http://webpack.github.io/docs/configuration.html#module-loaders 108 | loaders: [ 109 | 110 | // Transform ES6 to ES5 111 | // 112 | // See: https://github.com/babel/babel-loader 113 | {test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'}, 114 | 115 | // transform *.scss to css, then inline to 116 | { 117 | test: /\.scss$/, 118 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader!sass-loader') 119 | }, 120 | 121 | // Raw loader support for *.html 122 | // Returns file content as string 123 | // 124 | // See: https://github.com/webpack/raw-loader 125 | {test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(__dirname, '../src/index.html')]}, 126 | 127 | {test: /\.png$/, loader: 'url-loader?limit=10000'}, 128 | 129 | // font-awesome 130 | // 131 | // the url-loader uses DataUrls. 132 | // the file-loader emits files. 133 | {test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff"}, 134 | {test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader"} 135 | 136 | ] 137 | 138 | }, 139 | 140 | // Add additional plugins to the compiler. 141 | // 142 | // See: http://webpack.github.io/docs/configuration.html#plugins 143 | plugins: [ 144 | 145 | // Plugin: DedupePlugin 146 | // Description: Prevents the inclusion of duplicate code into your bundle 147 | // and instead applies a copy of the function at runtime. 148 | // 149 | // See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin 150 | // See: https://github.com/webpack/docs/wiki/optimization#deduplication 151 | new webpack.optimize.DedupePlugin(), 152 | 153 | // Plugin: OccurenceOrderPlugin 154 | // Description: Varies the distribution of the ids to get the smallest id length 155 | // for often used ids. 156 | // 157 | // See: https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin 158 | // See: https://github.com/webpack/docs/wiki/optimization#minimize 159 | new webpack.optimize.OccurenceOrderPlugin(true), 160 | 161 | // Plugin: CommonsChunkPlugin 162 | // Description: Shares common code between the pages. 163 | // It identifies common modules and put them into a commons chunk. 164 | // 165 | // See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin 166 | // See: https://github.com/webpack/docs/wiki/optimization#multi-page-app 167 | new webpack.optimize.CommonsChunkPlugin({name: ['app', 'vendor'], minChunks: Infinity}), 168 | 169 | // Plugin: UglifyJsPlugin 170 | // Description: Minimize all JavaScript output of chunks. 171 | // Loaders are switched into minimizing mode. 172 | // 173 | // See: https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin 174 | // NOTE: To debug prod builds uncomment //debug lines and comment //prod lines 175 | new webpack.optimize.UglifyJsPlugin({ 176 | // beautify: true, //debug 177 | // mangle: false, //debug 178 | // dead_code: false, //debug 179 | // unused: false, //debug 180 | // deadCode: false, //debug 181 | // compress: { 182 | // screw_ie8: true, 183 | // keep_fnames: true, 184 | // drop_debugger: false, 185 | // dead_code: false, 186 | // unused: false 187 | // }, // debug 188 | // comments: true, //debug 189 | 190 | beautify: false,//prod 191 | mangle: {screw_ie8: true}, 192 | compress: {screw_ie8: true}, //prod 193 | comments: false //prod 194 | }), 195 | 196 | // Plugin: CopyWebpackPlugin 197 | // Description: Copy files and directories in webpack. 198 | // 199 | // Copies project static assets. 200 | // 201 | // See: https://www.npmjs.com/package/copy-webpack-plugin 202 | new CopyWebpackPlugin([{from: 'src/assets', to: 'assets'}]), 203 | 204 | // Plugin: HtmlWebpackPlugin 205 | // Description: Simplifies creation of HTML files to serve your webpack bundles. 206 | // This is especially useful for webpack bundles that include a hash in the filename 207 | // which changes every compilation. 208 | // 209 | // See: https://github.com/ampedandwired/html-webpack-plugin 210 | new HtmlWebpackPlugin({template: 'src/index.html', chunksSortMode: 'none', inject: true}), 211 | 212 | // Plugin: ExtractTextPlugin 213 | // Description: extract all compiled css into file (*.css) 214 | // 215 | // See: https://github.com/webpack/extract-text-webpack-plugin 216 | new ExtractTextPlugin('[name]-[chunkhash].css', {allChunks: true}) 217 | ], 218 | 219 | postcss: [autoprefixer] 220 | 221 | }; 222 | -------------------------------------------------------------------------------- /server/dist/19111266e755d44793e231f12028306d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/19111266e755d44793e231f12028306d.png -------------------------------------------------------------------------------- /server/dist/32400f4e08932a94d8bfd2422702c446.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/32400f4e08932a94d8bfd2422702c446.eot -------------------------------------------------------------------------------- /server/dist/a35720c2fed2c7f043bc7e4ffb45e073.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/a35720c2fed2c7f043bc7e4ffb45e073.woff -------------------------------------------------------------------------------- /server/dist/a3de2170e4e9df77161ea5d3f31b2668.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/a3de2170e4e9df77161ea5d3f31b2668.ttf -------------------------------------------------------------------------------- /server/dist/app.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 5 | background: #F4F4F4; } 6 | 7 | a { 8 | color: #fff; 9 | text-decoration: none; } 10 | 11 | header { 12 | width: 100%; 13 | background-color: #009dd7; 14 | position: fixed; 15 | top: 0; 16 | z-index: 1; } 17 | header .header-box { 18 | position: relative; 19 | width: 850px; 20 | height: 60px; 21 | margin: 0 auto; } 22 | header .header-box .logo { 23 | background: url(19111266e755d44793e231f12028306d.png) no-repeat center; 24 | background-size: 105px 35px; 25 | width: 105px; 26 | height: 60px; 27 | display: inline-block; 28 | margin: 0 0 0 10px; } 29 | header .header-box .nav-wrap { 30 | position: absolute; 31 | bottom: 14px; 32 | display: inline-block; } 33 | header .header-box .nav-wrap .control { 34 | display: inline-block; 35 | margin-left: 30px; 36 | background: #11B0EA; 37 | border: 1px solid #008FC3; 38 | font-size: 0; 39 | border-radius: 4px; 40 | vertical-align: middle; 41 | cursor: pointer; } 42 | header .header-box .nav-wrap .control .control-button { 43 | display: inline-block; 44 | height: 13px; 45 | line-height: 13px; 46 | width: 14px; 47 | text-align: center; 48 | color: #B3E5FC; 49 | cursor: pointer; } 50 | header .header-box .nav-wrap .control .control-button:first-child { 51 | border-right: 1px solid #008FC3; } 52 | header .header-box .nav-wrap .control .control-button i { 53 | font-size: 13px; } 54 | header .header-box .nav-wrap nav { 55 | display: inline-block; 56 | font-size: 12px; 57 | margin-left: 10px; } 58 | header .header-box .nav-wrap nav a { 59 | margin-left: 15px; } 60 | 61 | .container { 62 | width: 850px; 63 | margin: 80px auto auto; } 64 | .container .one-day:after { 65 | content: ''; 66 | display: block; 67 | clear: both; } 68 | .container h2 { 69 | font-size: 16px; 70 | font-weight: normal; 71 | margin: 20px 0 15px 0; } 72 | .container .article-list { 73 | position: relative; 74 | width: 190px; 75 | height: 254px; 76 | float: left; 77 | margin: 0 30px 20px 0; 78 | background: #fff; 79 | color: #000; 80 | padding: 10px; 81 | box-sizing: border-box; 82 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.07); 83 | border-radius: 2px; } 84 | .container .article-list:nth-child(4n+1) { 85 | margin-right: 0; } 86 | .container .article-list .article-img { 87 | height: 170px; 88 | width: 170px; } 89 | .container .article-list .article-title { 90 | font-size: 13px; 91 | margin-top: 10px; } 92 | .container .article-list .article-like { 93 | font-size: 10px; 94 | position: absolute; 95 | right: 10px; 96 | bottom: 10px; } 97 | .container .article-list .article-like .fa-heart-o { 98 | margin-right: 5px; } 99 | -------------------------------------------------------------------------------- /server/dist/assets/img/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/assets/img/default.png -------------------------------------------------------------------------------- /server/dist/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/assets/img/logo.png -------------------------------------------------------------------------------- /server/dist/db812d8a70a4e88e888744c1c9a27e89.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DIYgod/ZhihuDaily-for-Desktop/75907ce67318871ae42155572b1cd6ce171de844/server/dist/db812d8a70a4e88e888744c1c9a27e89.woff2 -------------------------------------------------------------------------------- /server/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 知乎日报 6 | 7 | 8 |
9 |
10 |

11 | 27 |
28 |
29 |
30 | 31 | -------------------------------------------------------------------------------- /server/dist/vendor.bundle.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // install a JSONP callback for chunk loading 3 | /******/ var parentJsonpFunction = window["webpackJsonp"]; 4 | /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { 5 | /******/ // add "moreModules" to the modules object, 6 | /******/ // then flag all "chunkIds" as loaded and fire callback 7 | /******/ var moduleId, chunkId, i = 0, callbacks = []; 8 | /******/ for(;i < chunkIds.length; i++) { 9 | /******/ chunkId = chunkIds[i]; 10 | /******/ if(installedChunks[chunkId]) 11 | /******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); 12 | /******/ installedChunks[chunkId] = 0; 13 | /******/ } 14 | /******/ for(moduleId in moreModules) { 15 | /******/ modules[moduleId] = moreModules[moduleId]; 16 | /******/ } 17 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); 18 | /******/ while(callbacks.length) 19 | /******/ callbacks.shift().call(null, __webpack_require__); 20 | /******/ if(moreModules[0]) { 21 | /******/ installedModules[0] = 0; 22 | /******/ return __webpack_require__(0); 23 | /******/ } 24 | /******/ }; 25 | 26 | /******/ // The module cache 27 | /******/ var installedModules = {}; 28 | 29 | /******/ // object to store loaded and loading chunks 30 | /******/ // "0" means "already loaded" 31 | /******/ // Array means "loading", array contains callbacks 32 | /******/ var installedChunks = { 33 | /******/ 0:0 34 | /******/ }; 35 | 36 | /******/ // The require function 37 | /******/ function __webpack_require__(moduleId) { 38 | 39 | /******/ // Check if module is in cache 40 | /******/ if(installedModules[moduleId]) 41 | /******/ return installedModules[moduleId].exports; 42 | 43 | /******/ // Create a new module (and put it into the cache) 44 | /******/ var module = installedModules[moduleId] = { 45 | /******/ exports: {}, 46 | /******/ id: moduleId, 47 | /******/ loaded: false 48 | /******/ }; 49 | 50 | /******/ // Execute the module function 51 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 52 | 53 | /******/ // Flag the module as loaded 54 | /******/ module.loaded = true; 55 | 56 | /******/ // Return the exports of the module 57 | /******/ return module.exports; 58 | /******/ } 59 | 60 | /******/ // This file contains only the entry chunk. 61 | /******/ // The chunk loading function for additional chunks 62 | /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { 63 | /******/ // "0" is the signal for "already loaded" 64 | /******/ if(installedChunks[chunkId] === 0) 65 | /******/ return callback.call(null, __webpack_require__); 66 | 67 | /******/ // an array means "currently loading". 68 | /******/ if(installedChunks[chunkId] !== undefined) { 69 | /******/ installedChunks[chunkId].push(callback); 70 | /******/ } else { 71 | /******/ // start chunk loading 72 | /******/ installedChunks[chunkId] = [callback]; 73 | /******/ var head = document.getElementsByTagName('head')[0]; 74 | /******/ var script = document.createElement('script'); 75 | /******/ script.type = 'text/javascript'; 76 | /******/ script.charset = 'utf-8'; 77 | /******/ script.async = true; 78 | 79 | /******/ script.src = __webpack_require__.p + "" + chunkId + ".chunk.js"; 80 | /******/ head.appendChild(script); 81 | /******/ } 82 | /******/ }; 83 | 84 | /******/ // expose the modules object (__webpack_modules__) 85 | /******/ __webpack_require__.m = modules; 86 | 87 | /******/ // expose the module cache 88 | /******/ __webpack_require__.c = installedModules; 89 | 90 | /******/ // __webpack_public_path__ 91 | /******/ __webpack_require__.p = ""; 92 | 93 | /******/ // Load entry module and return exports 94 | /******/ return __webpack_require__(0); 95 | /******/ }) 96 | /************************************************************************/ 97 | /******/ ({ 98 | 99 | /***/ 0: 100 | /***/ function(module, exports, __webpack_require__) { 101 | 102 | __webpack_require__(92); 103 | module.exports = __webpack_require__(114); 104 | 105 | 106 | /***/ }, 107 | 108 | /***/ 52: 109 | /***/ function(module, exports, __webpack_require__) { 110 | 111 | eval("\n\n//\n// Generated on Tue Dec 16 2014 12:13:47 GMT+0100 (CET) by Charlie Robbins, Paolo Fragomeni & the Contributors (Using Codesurgeon).\n// Version 1.2.6\n//\n\n(function (exports) {\n\n/*\n * browser.js: Browser specific functionality for director.\n *\n * (C) 2011, Charlie Robbins, Paolo Fragomeni, & the Contributors.\n * MIT LICENSE\n *\n */\n\nvar dloc = document.location;\n\nfunction dlocHashEmpty() {\n // Non-IE browsers return '' when the address bar shows '#'; Director's logic\n // assumes both mean empty.\n return dloc.hash === '' || dloc.hash === '#';\n}\n\nvar listener = {\n mode: 'modern',\n hash: dloc.hash,\n history: false,\n\n check: function () {\n var h = dloc.hash;\n if (h != this.hash) {\n this.hash = h;\n this.onHashChanged();\n }\n },\n\n fire: function () {\n if (this.mode === 'modern') {\n this.history === true ? window.onpopstate() : window.onhashchange();\n }\n else {\n this.onHashChanged();\n }\n },\n\n init: function (fn, history) {\n var self = this;\n this.history = history;\n\n if (!Router.listeners) {\n Router.listeners = [];\n }\n\n function onchange(onChangeEvent) {\n for (var i = 0, l = Router.listeners.length; i < l; i++) {\n Router.listeners[i](onChangeEvent);\n }\n }\n\n //note IE8 is being counted as 'modern' because it has the hashchange event\n if ('onhashchange' in window && (document.documentMode === undefined\n || document.documentMode > 7)) {\n // At least for now HTML5 history is available for 'modern' browsers only\n if (this.history === true) {\n // There is an old bug in Chrome that causes onpopstate to fire even\n // upon initial page load. Since the handler is run manually in init(),\n // this would cause Chrome to run it twise. Currently the only\n // workaround seems to be to set the handler after the initial page load\n // http://code.google.com/p/chromium/issues/detail?id=63040\n setTimeout(function() {\n window.onpopstate = onchange;\n }, 500);\n }\n else {\n window.onhashchange = onchange;\n }\n this.mode = 'modern';\n }\n else {\n //\n // IE support, based on a concept by Erik Arvidson ...\n //\n var frame = document.createElement('iframe');\n frame.id = 'state-frame';\n frame.style.display = 'none';\n document.body.appendChild(frame);\n this.writeFrame('');\n\n if ('onpropertychange' in document && 'attachEvent' in document) {\n document.attachEvent('onpropertychange', function () {\n if (event.propertyName === 'location') {\n self.check();\n }\n });\n }\n\n window.setInterval(function () { self.check(); }, 50);\n\n this.onHashChanged = onchange;\n this.mode = 'legacy';\n }\n\n Router.listeners.push(fn);\n\n return this.mode;\n },\n\n destroy: function (fn) {\n if (!Router || !Router.listeners) {\n return;\n }\n\n var listeners = Router.listeners;\n\n for (var i = listeners.length - 1; i >= 0; i--) {\n if (listeners[i] === fn) {\n listeners.splice(i, 1);\n }\n }\n },\n\n setHash: function (s) {\n // Mozilla always adds an entry to the history\n if (this.mode === 'legacy') {\n this.writeFrame(s);\n }\n\n if (this.history === true) {\n window.history.pushState({}, document.title, s);\n // Fire an onpopstate event manually since pushing does not obviously\n // trigger the pop event.\n this.fire();\n } else {\n dloc.hash = (s[0] === '/') ? s : '/' + s;\n }\n return this;\n },\n\n writeFrame: function (s) {\n // IE support...\n var f = document.getElementById('state-frame');\n var d = f.contentDocument || f.contentWindow.document;\n d.open();\n d.write(\"