119 | {
120 | captureProgress &&
121 |
122 |
141 |
142 | }
143 | {saving && !captureProgress &&
Saving...
}
144 | {!saving &&
Drop a Video to Convert to GIF
}
145 |
146 | );
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/configs/webpack.config.renderer.prod.babel.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Build config for electron renderer process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
8 | import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import merge from 'webpack-merge';
11 | import TerserPlugin from 'terser-webpack-plugin';
12 | import baseConfig from './webpack.config.base';
13 | import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
14 |
15 | CheckNodeEnv('production');
16 | export default merge.smart(baseConfig, {
17 | devtool: 'source-map',
18 |
19 | mode: 'production',
20 |
21 | target: 'electron-renderer',
22 |
23 | entry: path.join(__dirname, '..', 'app/index'),
24 |
25 | output: {
26 | path: path.join(__dirname, '..', 'app/dist'),
27 | publicPath: './dist/',
28 | filename: 'renderer.prod.js'
29 | },
30 |
31 | module: {
32 | rules: [
33 | // Extract all .global.css to style.css as is
34 | {
35 | test: /\.global\.css$/,
36 | use: [
37 | {
38 | loader: MiniCssExtractPlugin.loader,
39 | options: {
40 | publicPath: './'
41 | }
42 | },
43 | {
44 | loader: 'css-loader',
45 | options: {
46 | sourceMap: true
47 | }
48 | }
49 | ]
50 | },
51 | // Pipe other styles through css modules and append to style.css
52 | {
53 | test: /^((?!\.global).)*\.css$/,
54 | use: [
55 | {
56 | loader: MiniCssExtractPlugin.loader
57 | },
58 | {
59 | loader: 'css-loader',
60 | options: {
61 | modules: true,
62 | localIdentName: '[name]__[local]__[hash:base64:5]',
63 | sourceMap: true
64 | }
65 | }
66 | ]
67 | },
68 | // Add SASS support - compile all .global.scss files and pipe it to style.css
69 | {
70 | test: /\.global\.(scss|sass)$/,
71 | use: [
72 | {
73 | loader: MiniCssExtractPlugin.loader
74 | },
75 | {
76 | loader: 'css-loader',
77 | options: {
78 | sourceMap: true,
79 | importLoaders: 1
80 | }
81 | },
82 | {
83 | loader: 'sass-loader',
84 | options: {
85 | sourceMap: true
86 | }
87 | }
88 | ]
89 | },
90 | // Add SASS support - compile all other .scss files and pipe it to style.css
91 | {
92 | test: /^((?!\.global).)*\.(scss|sass)$/,
93 | use: [
94 | {
95 | loader: MiniCssExtractPlugin.loader
96 | },
97 | {
98 | loader: 'css-loader',
99 | options: {
100 | modules: true,
101 | importLoaders: 1,
102 | localIdentName: '[name]__[local]__[hash:base64:5]',
103 | sourceMap: true
104 | }
105 | },
106 | {
107 | loader: 'sass-loader',
108 | options: {
109 | sourceMap: true
110 | }
111 | }
112 | ]
113 | },
114 | // WOFF Font
115 | {
116 | test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
117 | use: {
118 | loader: 'url-loader',
119 | options: {
120 | limit: 10000,
121 | mimetype: 'application/font-woff'
122 | }
123 | }
124 | },
125 | // WOFF2 Font
126 | {
127 | test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
128 | use: {
129 | loader: 'url-loader',
130 | options: {
131 | limit: 10000,
132 | mimetype: 'application/font-woff'
133 | }
134 | }
135 | },
136 | // TTF Font
137 | {
138 | test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
139 | use: {
140 | loader: 'url-loader',
141 | options: {
142 | limit: 10000,
143 | mimetype: 'application/octet-stream'
144 | }
145 | }
146 | },
147 | // EOT Font
148 | {
149 | test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
150 | use: 'file-loader'
151 | },
152 | // SVG Font
153 | {
154 | test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
155 | use: {
156 | loader: 'url-loader',
157 | options: {
158 | limit: 10000,
159 | mimetype: 'image/svg+xml'
160 | }
161 | }
162 | },
163 | // Common Image Formats
164 | {
165 | test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
166 | use: 'url-loader'
167 | }
168 | ]
169 | },
170 |
171 | optimization: {
172 | minimizer: process.env.E2E_BUILD
173 | ? []
174 | : [
175 | new TerserPlugin({
176 | parallel: true,
177 | sourceMap: true,
178 | cache: true
179 | }),
180 | new OptimizeCSSAssetsPlugin({
181 | cssProcessorOptions: {
182 | map: {
183 | inline: false,
184 | annotation: true
185 | }
186 | }
187 | })
188 | ]
189 | },
190 |
191 | plugins: [
192 | /**
193 | * Create global constants which can be configured at compile time.
194 | *
195 | * Useful for allowing different behaviour between development builds and
196 | * release builds
197 | *
198 | * NODE_ENV should be production so that modules do not perform certain
199 | * development checks
200 | */
201 | new webpack.EnvironmentPlugin({
202 | NODE_ENV: 'production'
203 | }),
204 |
205 | new MiniCssExtractPlugin({
206 | filename: 'style.css'
207 | }),
208 |
209 | new BundleAnalyzerPlugin({
210 | analyzerMode:
211 | process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
212 | openAnalyzer: process.env.OPEN_ANALYZER === 'true'
213 | })
214 | ]
215 | });
216 |
--------------------------------------------------------------------------------
/configs/webpack.config.renderer.dev.babel.js:
--------------------------------------------------------------------------------
1 | /* eslint global-require: off, import/no-dynamic-require: off */
2 |
3 | /**
4 | * Build config for development electron renderer process that uses
5 | * Hot-Module-Replacement
6 | *
7 | * https://webpack.js.org/concepts/hot-module-replacement/
8 | */
9 |
10 | import path from 'path';
11 | import fs from 'fs';
12 | import webpack from 'webpack';
13 | import chalk from 'chalk';
14 | import merge from 'webpack-merge';
15 | import { spawn, execSync } from 'child_process';
16 | import baseConfig from './webpack.config.base';
17 | import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
18 |
19 | CheckNodeEnv('development');
20 |
21 | const port = process.env.PORT || 1212;
22 | const publicPath = `http://localhost:${port}/dist`;
23 | const dll = path.join(__dirname, '..', 'dll');
24 | const manifest = path.resolve(dll, 'renderer.json');
25 | const requiredByDLLConfig = module.parent.filename.includes(
26 | 'webpack.config.renderer.dev.dll'
27 | );
28 |
29 | /**
30 | * Warn if the DLL is not built
31 | */
32 | if (!requiredByDLLConfig && !(fs.existsSync(dll) && fs.existsSync(manifest))) {
33 | console.log(
34 | chalk.black.bgYellow.bold(
35 | 'The DLL files are missing. Sit back while we build them for you with "yarn build-dll"'
36 | )
37 | );
38 | execSync('yarn build-dll');
39 | }
40 |
41 | export default merge.smart(baseConfig, {
42 | devtool: 'inline-source-map',
43 |
44 | mode: 'development',
45 |
46 | target: 'electron-renderer',
47 |
48 | entry: [
49 | 'react-hot-loader/patch',
50 | `webpack-dev-server/client?http://localhost:${port}/`,
51 | 'webpack/hot/only-dev-server',
52 | require.resolve('../app/index')
53 | ],
54 |
55 | output: {
56 | publicPath: `http://localhost:${port}/dist/`,
57 | filename: 'renderer.dev.js'
58 | },
59 |
60 | module: {
61 | rules: [
62 | {
63 | test: /\.jsx?$/,
64 | exclude: /node_modules/,
65 | use: {
66 | loader: 'babel-loader',
67 | options: {
68 | cacheDirectory: true
69 | }
70 | }
71 | },
72 | {
73 | test: /\.global\.css$/,
74 | use: [
75 | {
76 | loader: 'style-loader'
77 | },
78 | {
79 | loader: 'css-loader',
80 | options: {
81 | sourceMap: true
82 | }
83 | }
84 | ]
85 | },
86 | {
87 | test: /^((?!\.global).)*\.css$/,
88 | use: [
89 | {
90 | loader: 'style-loader'
91 | },
92 | {
93 | loader: 'css-loader',
94 | options: {
95 | modules: true,
96 | sourceMap: true,
97 | importLoaders: 1,
98 | localIdentName: '[name]__[local]__[hash:base64:5]'
99 | }
100 | }
101 | ]
102 | },
103 | // SASS support - compile all .global.scss files and pipe it to style.css
104 | {
105 | test: /\.global\.(scss|sass)$/,
106 | use: [
107 | {
108 | loader: 'style-loader'
109 | },
110 | {
111 | loader: 'css-loader',
112 | options: {
113 | sourceMap: true
114 | }
115 | },
116 | {
117 | loader: 'sass-loader'
118 | }
119 | ]
120 | },
121 | // SASS support - compile all other .scss files and pipe it to style.css
122 | {
123 | test: /^((?!\.global).)*\.(scss|sass)$/,
124 | use: [
125 | {
126 | loader: 'style-loader'
127 | },
128 | {
129 | loader: 'css-loader',
130 | options: {
131 | modules: true,
132 | sourceMap: true,
133 | importLoaders: 1,
134 | localIdentName: '[name]__[local]__[hash:base64:5]'
135 | }
136 | },
137 | {
138 | loader: 'sass-loader'
139 | }
140 | ]
141 | },
142 | // WOFF Font
143 | {
144 | test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
145 | use: {
146 | loader: 'url-loader',
147 | options: {
148 | limit: 10000,
149 | mimetype: 'application/font-woff'
150 | }
151 | }
152 | },
153 | // WOFF2 Font
154 | {
155 | test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
156 | use: {
157 | loader: 'url-loader',
158 | options: {
159 | limit: 10000,
160 | mimetype: 'application/font-woff'
161 | }
162 | }
163 | },
164 | // TTF Font
165 | {
166 | test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
167 | use: {
168 | loader: 'url-loader',
169 | options: {
170 | limit: 10000,
171 | mimetype: 'application/octet-stream'
172 | }
173 | }
174 | },
175 | // EOT Font
176 | {
177 | test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
178 | use: 'file-loader'
179 | },
180 | // SVG Font
181 | {
182 | test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
183 | use: {
184 | loader: 'url-loader',
185 | options: {
186 | limit: 10000,
187 | mimetype: 'image/svg+xml'
188 | }
189 | }
190 | },
191 | // Common Image Formats
192 | {
193 | test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
194 | use: 'url-loader'
195 | }
196 | ]
197 | },
198 |
199 | plugins: [
200 | requiredByDLLConfig
201 | ? null
202 | : new webpack.DllReferencePlugin({
203 | context: path.join(__dirname, '..', 'dll'),
204 | manifest: require(manifest),
205 | sourceType: 'var'
206 | }),
207 |
208 | new webpack.HotModuleReplacementPlugin({
209 | multiStep: true
210 | }),
211 |
212 | new webpack.NoEmitOnErrorsPlugin(),
213 |
214 | /**
215 | * Create global constants which can be configured at compile time.
216 | *
217 | * Useful for allowing different behaviour between development builds and
218 | * release builds
219 | *
220 | * NODE_ENV should be production so that modules do not perform certain
221 | * development checks
222 | *
223 | * By default, use 'development' as NODE_ENV. This can be overriden with
224 | * 'staging', for example, by changing the ENV variables in the npm scripts
225 | */
226 | new webpack.EnvironmentPlugin({
227 | NODE_ENV: 'development'
228 | }),
229 |
230 | new webpack.LoaderOptionsPlugin({
231 | debug: true
232 | })
233 | ],
234 |
235 | node: {
236 | __dirname: false,
237 | __filename: false
238 | },
239 |
240 | devServer: {
241 | port,
242 | publicPath,
243 | compress: true,
244 | noInfo: true,
245 | stats: 'errors-only',
246 | inline: true,
247 | lazy: false,
248 | hot: true,
249 | headers: { 'Access-Control-Allow-Origin': '*' },
250 | contentBase: path.join(__dirname, 'dist'),
251 | watchOptions: {
252 | aggregateTimeout: 300,
253 | ignored: /node_modules/,
254 | poll: 100
255 | },
256 | historyApiFallback: {
257 | verbose: true,
258 | disableDotRule: false
259 | },
260 | before() {
261 | if (process.env.START_HOT) {
262 | console.log('Starting Main Process...');
263 | spawn('npm', ['run', 'start-main-dev'], {
264 | shell: true,
265 | env: process.env,
266 | stdio: 'inherit'
267 | })
268 | .on('close', code => process.exit(code))
269 | .on('error', spawnError => console.error(spawnError));
270 | }
271 | }
272 | }
273 | });
274 |
--------------------------------------------------------------------------------
/app/menu.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import { app, Menu, shell, BrowserWindow } from 'electron';
3 |
4 | export default class MenuBuilder {
5 | mainWindow: BrowserWindow;
6 |
7 | constructor(mainWindow: BrowserWindow) {
8 | this.mainWindow = mainWindow;
9 | }
10 |
11 | buildMenu() {
12 | if (
13 | process.env.NODE_ENV === 'development' ||
14 | process.env.DEBUG_PROD === 'true'
15 | ) {
16 | this.setupDevelopmentEnvironment();
17 | }
18 |
19 | const template =
20 | process.platform === 'darwin'
21 | ? this.buildDarwinTemplate()
22 | : this.buildDefaultTemplate();
23 |
24 | const menu = Menu.buildFromTemplate(template);
25 | Menu.setApplicationMenu(menu);
26 |
27 | return menu;
28 | }
29 |
30 | setupDevelopmentEnvironment() {
31 | this.mainWindow.openDevTools();
32 | this.mainWindow.webContents.on('context-menu', (e, props) => {
33 | const { x, y } = props;
34 |
35 | Menu.buildFromTemplate([
36 | {
37 | label: 'Inspect element',
38 | click: () => {
39 | this.mainWindow.inspectElement(x, y);
40 | }
41 | }
42 | ]).popup(this.mainWindow);
43 | });
44 | }
45 |
46 | buildDarwinTemplate() {
47 | const subMenuAbout = {
48 | label: 'Electron',
49 | submenu: [
50 | {
51 | label: 'About Vif',
52 | selector: 'orderFrontStandardAboutPanel:'
53 | },
54 | { type: 'separator' },
55 | { label: 'Services', submenu: [] },
56 | { type: 'separator' },
57 | {
58 | label: 'Hide ElectronReact',
59 | accelerator: 'Command+H',
60 | selector: 'hide:'
61 | },
62 | {
63 | label: 'Hide Others',
64 | accelerator: 'Command+Shift+H',
65 | selector: 'hideOtherApplications:'
66 | },
67 | { label: 'Show All', selector: 'unhideAllApplications:' },
68 | { type: 'separator' },
69 | {
70 | label: 'Quit',
71 | accelerator: 'Command+Q',
72 | click: () => {
73 | app.quit();
74 | }
75 | }
76 | ]
77 | };
78 | const subMenuEdit = {
79 | label: 'Edit',
80 | submenu: [
81 | { label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' },
82 | { label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' },
83 | { type: 'separator' },
84 | { label: 'Cut', accelerator: 'Command+X', selector: 'cut:' },
85 | { label: 'Copy', accelerator: 'Command+C', selector: 'copy:' },
86 | { label: 'Paste', accelerator: 'Command+V', selector: 'paste:' },
87 | {
88 | label: 'Select All',
89 | accelerator: 'Command+A',
90 | selector: 'selectAll:'
91 | }
92 | ]
93 | };
94 | const subMenuViewDev = {
95 | label: 'View',
96 | submenu: [
97 | {
98 | label: 'Reload',
99 | accelerator: 'Command+R',
100 | click: () => {
101 | this.mainWindow.webContents.reload();
102 | }
103 | },
104 | {
105 | label: 'Toggle Full Screen',
106 | accelerator: 'Ctrl+Command+F',
107 | click: () => {
108 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
109 | }
110 | },
111 | {
112 | label: 'Toggle Developer Tools',
113 | accelerator: 'Alt+Command+I',
114 | click: () => {
115 | this.mainWindow.toggleDevTools();
116 | }
117 | }
118 | ]
119 | };
120 | const subMenuViewProd = {
121 | label: 'View',
122 | submenu: [
123 | {
124 | label: 'Toggle Full Screen',
125 | accelerator: 'Ctrl+Command+F',
126 | click: () => {
127 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
128 | }
129 | }
130 | ]
131 | };
132 | const subMenuWindow = {
133 | label: 'Window',
134 | submenu: [
135 | {
136 | label: 'Minimize',
137 | accelerator: 'Command+M',
138 | selector: 'performMiniaturize:'
139 | },
140 | { label: 'Close', accelerator: 'Command+W', selector: 'performClose:' },
141 | { type: 'separator' },
142 | { label: 'Bring All to Front', selector: 'arrangeInFront:' }
143 | ]
144 | };
145 | const subMenuHelp = {
146 | label: 'Help',
147 | submenu: [
148 | {
149 | label: 'Learn More',
150 | click() {
151 | shell.openExternal('http://electron.atom.io');
152 | }
153 | },
154 | {
155 | label: 'Documentation',
156 | click() {
157 | shell.openExternal(
158 | 'https://github.com/atom/electron/tree/master/docs#readme'
159 | );
160 | }
161 | },
162 | {
163 | label: 'Community Discussions',
164 | click() {
165 | shell.openExternal('https://discuss.atom.io/c/electron');
166 | }
167 | },
168 | {
169 | label: 'Search Issues',
170 | click() {
171 | shell.openExternal('https://github.com/atom/electron/issues');
172 | }
173 | }
174 | ]
175 | };
176 |
177 | const subMenuView =
178 | process.env.NODE_ENV === 'development' ? subMenuViewDev : subMenuViewProd;
179 |
180 | return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
181 | }
182 |
183 | buildDefaultTemplate() {
184 | const templateDefault = [
185 | {
186 | label: '&File',
187 | submenu: [
188 | {
189 | label: '&Open',
190 | accelerator: 'Ctrl+O'
191 | },
192 | {
193 | label: '&Close',
194 | accelerator: 'Ctrl+W',
195 | click: () => {
196 | this.mainWindow.close();
197 | }
198 | }
199 | ]
200 | },
201 | {
202 | label: '&View',
203 | submenu:
204 | process.env.NODE_ENV === 'development'
205 | ? [
206 | {
207 | label: '&Reload',
208 | accelerator: 'Ctrl+R',
209 | click: () => {
210 | this.mainWindow.webContents.reload();
211 | }
212 | },
213 | {
214 | label: 'Toggle &Full Screen',
215 | accelerator: 'F11',
216 | click: () => {
217 | this.mainWindow.setFullScreen(
218 | !this.mainWindow.isFullScreen()
219 | );
220 | }
221 | },
222 | {
223 | label: 'Toggle &Developer Tools',
224 | accelerator: 'Alt+Ctrl+I',
225 | click: () => {
226 | this.mainWindow.toggleDevTools();
227 | }
228 | }
229 | ]
230 | : [
231 | {
232 | label: 'Toggle &Full Screen',
233 | accelerator: 'F11',
234 | click: () => {
235 | this.mainWindow.setFullScreen(
236 | !this.mainWindow.isFullScreen()
237 | );
238 | }
239 | }
240 | ]
241 | },
242 | {
243 | label: 'Help',
244 | submenu: [
245 | {
246 | label: 'Learn More',
247 | click() {
248 | shell.openExternal('http://electron.atom.io');
249 | }
250 | },
251 | {
252 | label: 'Documentation',
253 | click() {
254 | shell.openExternal(
255 | 'https://github.com/atom/electron/tree/master/docs#readme'
256 | );
257 | }
258 | },
259 | {
260 | label: 'Community Discussions',
261 | click() {
262 | shell.openExternal('https://discuss.atom.io/c/electron');
263 | }
264 | },
265 | {
266 | label: 'Search Issues',
267 | click() {
268 | shell.openExternal('https://github.com/atom/electron/issues');
269 | }
270 | }
271 | ]
272 | }
273 | ];
274 |
275 | return templateDefault;
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vif",
3 | "productName": "Vif",
4 | "version": "1.0.0",
5 | "description": "cross-platform desktop application to convert videos to high-quality GIFs",
6 | "scripts": {
7 | "build": "concurrently \"yarn build-main\" \"yarn build-renderer\"",
8 | "build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors",
9 | "build-e2e": "cross-env E2E_BUILD=true yarn build",
10 | "build-main": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors",
11 | "build-renderer": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors",
12 | "dev": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && cross-env START_HOT=1 yarn start-renderer-dev",
13 | "flow": "flow",
14 | "flow-typed": "rimraf flow-typed/npm && flow-typed install --overwrite || true",
15 | "lint": "cross-env NODE_ENV=development eslint --cache --format=pretty .",
16 | "lint-fix": "yarn --silent lint --fix; exit 0",
17 | "lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss",
18 | "lint-styles-fix": "yarn --silent lint-styles --fix; exit 0",
19 | "package": "yarn build && electron-builder build --publish never",
20 | "package-all": "yarn build && electron-builder build -mwl",
21 | "package-ci": "yarn postinstall && yarn build && electron-builder --publish always",
22 | "package-linux": "yarn build && electron-builder build --linux",
23 | "package-win": "yarn build && electron-builder build --win --x64",
24 | "postinstall": "yarn flow-typed && electron-builder install-app-deps package.json && yarn build-dll && opencollective-postinstall",
25 | "postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{*{js,jsx,json},babelrc,eslintrc,prettierrc,stylelintrc}'",
26 | "postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'",
27 | "prestart": "yarn build",
28 | "start": "cross-env NODE_ENV=production electron ./app/main.prod.js",
29 | "start-main-dev": "cross-env HOT=1 NODE_ENV=development electron -r @babel/register ./app/main.dev.js",
30 | "start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js",
31 | "test": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 jest",
32 | "test-all": "yarn lint && yarn flow && yarn build && yarn test && yarn build-e2e && yarn test-e2e",
33 | "test-e2e": "node -r @babel/register ./internals/scripts/CheckBuiltsExist.js && cross-env NODE_ENV=test testcafe electron:./ ./test/e2e/HomePage.e2e.js",
34 | "test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuiltsExist.js && cross-env NODE_ENV=test testcafe-live electron:./ ./test/e2e/HomePage.e2e.js",
35 | "test-watch": "yarn test --watch"
36 | },
37 | "lint-staged": {
38 | "*.{js,jsx}": [
39 | "cross-env NODE_ENV=development eslint --cache --format=pretty",
40 | "prettier --ignore-path .eslintignore --single-quote --write",
41 | "git add"
42 | ],
43 | "{*.json,.{babelrc,eslintrc,prettierrc,stylelintrc}}": [
44 | "prettier --ignore-path .eslintignore --parser json --write",
45 | "git add"
46 | ],
47 | "*.{css,scss}": [
48 | "stylelint --ignore-path .eslintignore --syntax scss --fix",
49 | "prettier --ignore-path .eslintignore --single-quote --write",
50 | "git add"
51 | ],
52 | "*.{yml,md}": [
53 | "prettier --ignore-path .eslintignore --single-quote --write",
54 | "git add"
55 | ]
56 | },
57 | "main": "./app/main.prod.js",
58 | "build": {
59 | "productName": "Vif",
60 | "appId": "org.develar.Vif",
61 | "files": [
62 | "app/dist/",
63 | "app/app.html",
64 | "app/main.prod.js",
65 | "app/main.prod.js.map",
66 | "package.json"
67 | ],
68 | "dmg": {
69 | "contents": [
70 | {
71 | "x": 130,
72 | "y": 220
73 | },
74 | {
75 | "x": 410,
76 | "y": 220,
77 | "type": "link",
78 | "path": "/Applications"
79 | }
80 | ]
81 | },
82 | "win": {
83 | "target": [
84 | "nsis",
85 | "msi"
86 | ]
87 | },
88 | "linux": {
89 | "target": [
90 | "deb",
91 | "rpm",
92 | "snap",
93 | "AppImage"
94 | ],
95 | "category": "Development"
96 | },
97 | "directories": {
98 | "buildResources": "resources",
99 | "output": "release"
100 | },
101 | "publish": {
102 | "provider": "github",
103 | "owner": "soroushchehresa",
104 | "repo": "Vif",
105 | "private": false
106 | }
107 | },
108 | "repository": {
109 | "type": "git",
110 | "url": "git+https://github.com/soroushchehresa/Vif.git"
111 | },
112 | "author": {
113 | "name": "Soroush Chehresa",
114 | "email": "s1996ch@gmail.com",
115 | "url": "https://github.com/soroushchehresa/Vif"
116 | },
117 | "contributors": [
118 | {
119 | "name": "Vikram Rangaraj",
120 | "email": "vikr01@icloud.com",
121 | "url": "https://github.com/vikr01"
122 | },
123 | {
124 | "name": "Amila Welihinda",
125 | "email": "amilajack@gmail.com",
126 | "url": "https://github.com/amilajack"
127 | }
128 | ],
129 | "license": "MIT",
130 | "bugs": {
131 | "url": "https://github.com/soroushchehresa/Vif/issues"
132 | },
133 | "keywords": [
134 | "vif",
135 | "video-to-gif",
136 | "gif",
137 | "gif-animation",
138 | "converter",
139 | "video-converter",
140 | "convert-videos",
141 | "react",
142 | "electron-app"
143 | ],
144 | "homepage": "https://github.com/soroushchehresa/Vif#readme",
145 | "jest": {
146 | "testURL": "http://localhost/",
147 | "moduleNameMapper": {
148 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "