Compare commits

...

870 Commits

Author SHA1 Message Date
Dr_rOot af1cc4db8e chore: bump version to 1.8.15 2023-04-28 22:54:29 +08:00
Dr_rOot 8defa9ee71 Merge pull request #1466 from agalwood/hotfix/aria2_x64_20230428
fix: rebuild darwin x64 aria2c bin
2023-04-28 22:51:56 +08:00
Dr_rOot cb6d9f2b20 chore: change node mini version to 16 2023-04-28 22:50:01 +08:00
Dr_rOot 9f6c31ffa3 fix: rebuild darwin x64 aria2c bin 2023-04-28 22:49:10 +08:00
greenhandzdl 0b3161ca6f docs: fix yay install script (#1465)
* Fix Doc
2023-04-28 22:39:06 +08:00
Dr_rOot c79bdff4b8 Merge pull request #1464 from agalwood/hotfix/aria2_arm64_20230428
fix: rebuild arm64 aria2c bin
2023-04-28 18:45:00 +08:00
Dr_rOot b92957668b chore: update deps 2023-04-28 18:19:57 +08:00
Dr_rOot b1b52e2640 fix: rebuild arm64 aria2c bin 2023-04-28 18:16:01 +08:00
Dr_rOot a39fa2979c chore: bump version to 1.8.14 2023-04-27 17:49:04 +08:00
Dr_rOot e0a74f7979 fix: selected task item border color in dark mode 2023-04-27 17:47:59 +08:00
Dr_rOot a7b8333710 chore: bump version to 1.8.13 2023-04-27 17:08:14 +08:00
Dr_rOot 77850da0fe Merge pull request #1455 from agalwood/hotfix/auto_update_20230427
fix: app auto update failed
2023-04-27 17:06:53 +08:00
Dr_rOot 71f4eeeb25 chore: change app update generic url 2023-04-27 16:51:28 +08:00
Dr_rOot e5eace479d fix: handle auto updater update canceled event 2023-04-27 16:51:06 +08:00
Dr_rOot 7e927fea10 chore: bump version to 1.8.12 2023-04-27 11:11:34 +08:00
Dr_rOot 38cd952b44 Merge pull request #1453 from agalwood/hotfix/stop_engine_20230427
fix: stop engine failed when app quit
2023-04-27 11:10:23 +08:00
Dr_rOot b07fedeba0 chore: electron build mac target add universal 2023-04-27 10:54:38 +08:00
Dr_rOot 2bbaae5d7d feat: preference advanced add log level setting 2023-04-27 10:53:27 +08:00
Dr_rOot 003e9ffccb fix: stop engine failed when app quit 2023-04-27 10:23:08 +08:00
Dr_rOot 7a51dbaf5e chore: update bug report issue template 2023-04-27 08:00:07 +08:00
Dr_rOot 4fa4878e61 fix: appx for ms store & bump version to 1.8.11 2023-04-26 21:14:33 +08:00
Dr_rOot daa04d995e fix: publisher for ms store & bump version to 1.8.10 2023-04-26 20:59:50 +08:00
Dr_rOot 74e4bce6bf fix: identity for ms store & bump version to 1.8.9 2023-04-26 20:55:29 +08:00
Dr_rOot a0aa100a99 fix: author for ms store & bump version to 1.8.8 2023-04-26 20:08:53 +08:00
Dr_rOot 4c3b248cc0 chore: bump version to 1.8.7 2023-04-26 18:59:56 +08:00
Dr_rOot 96d525832f fix: github action SNAPCRAFT_STORE_CREDENTIALS 2023-04-26 18:59:34 +08:00
Dr_rOot 9255c95ecc chore: bump version to 1.8.6 2023-04-26 18:31:00 +08:00
Dr_rOot e117d5925a fix: notarize apple id password 2023-04-26 18:29:35 +08:00
Dr_rOot 6a5d7637c2 chore: bump version to 1.8.5 2023-04-26 18:22:19 +08:00
Dr_rOot 93e8bdff00 chore: notarize tool 2023-04-26 18:21:55 +08:00
Dr_rOot a82afbf97b chore: bump version to 1.8.4 2023-04-26 17:48:52 +08:00
Dr_rOot e1363d3fe2 fix: electron build notarization tool 2023-04-26 17:48:43 +08:00
Dr_rOot 1338861dc3 chore: bump version to 1.8.3 2023-04-26 17:34:32 +08:00
Dr_rOot b9068559e2 refactor: electron build notarization 2023-04-26 17:34:07 +08:00
Dr_rOot b7ed072966 chore: bump version to 1.8.2 2023-04-26 16:56:36 +08:00
Dr_rOot e281b71d4e refactor: github electron build action 2023-04-26 16:56:21 +08:00
Dr_rOot 67d26e4b1f chore: bump version to 1.8.1 2023-04-26 16:01:41 +08:00
Dr_rOot 1b27980992 Merge pull request #1445 from agalwood/feature/show_progess_bar_20230426
feat: preference basic show progress bar
2023-04-26 15:04:08 +08:00
Dr_rOot 292ad15152 chore: update deps 2023-04-26 13:27:39 +08:00
Dr_rOot df1b30d6f4 chore: sign darwin aria2c bin 2023-04-26 13:27:31 +08:00
Dr_rOot 0d3aa86d31 chore: i18n show progress bar 2023-04-26 13:27:04 +08:00
Dr_rOot a07f81e20c feat: preference basic show progress bar 2023-04-26 13:26:47 +08:00
Dr_rOot 61365d738c chore: lint fix after sign hook js 2023-04-26 10:53:17 +08:00
Dr_rOot 33f13b51b0 fix: electron builder win targets artifact name 2023-04-25 11:35:07 +08:00
Dr_rOot 2bda3b40eb fix: github action snapcraft token env (#1441) 2023-04-24 21:14:20 +08:00
Dr_rOot e456ba660b Merge pull request #1440 from agalwood/feature/aria2_conf_path_20230423 2023-04-23 19:41:57 +08:00
Dr_rOot 342b2b2069 chore: aria2 max-overall-upload-limit default 0 2023-04-23 18:17:55 +08:00
Dr_rOot 91697aee42 chore: i18n aria2 conf path 2023-04-23 18:17:03 +08:00
Dr_rOot f4e56ca4b7 feat: preference advanced show aria2 conf path 2023-04-23 18:16:44 +08:00
Dr_rOot 363cef2959 Merge pull request #1439 from agalwood/feature/appx_20230421
feat: build output add windows appx
2023-04-21 21:19:57 +08:00
Dr_rOot e938f30377 chore: rename appId avoid linux .desktop 2023-04-21 21:02:24 +08:00
Dr_rOot ed622ade1f chore: build output add windows appx 2023-04-21 21:01:13 +08:00
Dr_rOot 06f0ccf2e5 Merge pull request #1436 from agalwood/feature/rpc_listen_port_20230419
feat: preference advanced config rpc listen port
2023-04-19 21:55:15 +08:00
Dr_rOot 6885da1b86 feat: linux build add mime types 2023-04-19 18:14:42 +08:00
Dr_rOot 3ffce0566b feat: task detail files show completed percent 2023-04-19 18:14:16 +08:00
Dr_rOot a215df0360 feat: preference advanced config rpc listen port 2023-04-19 18:13:22 +08:00
Dr_rOot 6bea4322c1 chore: upgrade electron builder action (#1435) 2023-04-18 10:45:52 +08:00
Dr_rOot 493df2b333 feat: release support arm arch linux (#1434)
* feat: release support arm arch linux

Aria2 build:
https://github.com/motrixapp/Aria2-Pro-Core/tree/build_for_motrix

* chore: update github action yml

* chore: revert github action ubuntu-arm64
2023-04-17 21:31:08 +08:00
Chiao-Wei Wang 73c5a6790a feat: Add cURL support for convenient download with cookie/referer information (#1430)
* Add CURL support

* Fix GET request parameters problem

* Add AppleSilicon build command

* Use patched curl-to-json

* Add AppleSilicon building instruction on README

* Update curl-to-json to get rid of warnings

* fix: cannot correctly parse curl -b option

* fix: curl cannot use -A -e options

* fix: update curl-to-json to patch

* chore: update curl-to-json to v1.2.7

* Use --arm64 instead of --universal for build::applesilicon
2023-04-17 11:29:46 +08:00
Dr_rOot 644966e438 feat: app menu add task list and bind hotkey 2023-04-15 21:50:57 +08:00
Chiao-Wei Wang af6e0f33c0 fix: bug regarding cookie/referer (#1428)
When cookie/referer are set at the same time, aria2 failed to parse the cookie/referer arguments.
2023-04-15 11:11:45 +08:00
Dr_rOot 81656a2cd0 Merge pull request #1427 from agalwood/feature/dir_history_20230412
feat: choose dir from history directory
2023-04-13 15:20:22 +08:00
Dr_rOot 74b9f465a1 fix: update nat-api to fix xml2js vulnerability 2023-04-13 14:44:17 +08:00
Dr_rOot 92177a2c4b feat: choose dir from history directory 2023-04-13 12:49:25 +08:00
Dr_rOot bc0114a164 refactor: tracker utils 2023-04-13 12:42:24 +08:00
Dr_rOot ff918c916c refactor: text direction 2023-04-13 12:24:49 +08:00
Dr_rOot d81c0bbb9a chore: update git ignore 2023-04-13 12:23:04 +08:00
Dr_rOot b240029a47 refactor: parseHeader replace substr to substring 2023-04-12 19:52:50 +08:00
Dr_rOot ba887bcc2b fix: directory history props 2023-04-12 14:40:01 +08:00
Dr_rOot 1d90231ebd feat: add task dir history 2023-04-12 11:21:07 +08:00
Dr_rOot 39d92907e9 Merge pull request #1426 from agalwood/hotfix/linux_rendering_bug_20230410
fix: BrowserWindow rendering bug under linux
2023-04-12 09:51:33 +08:00
Dr_rOot 4272a53f69 fix: preference basic need confirm but not changed
The modified preferences will be lost, are you sure you want to leave?
2023-04-11 12:02:06 +08:00
Dr_rOot 0bbe980d48 chore: declare node version >= 18 2023-04-10 21:24:23 +08:00
Dr_rOot d2017a6c25 fix: BrowserWindow rendering bug under linux 2023-04-10 18:23:37 +08:00
Dr_rOot e3da125cc7 refactor: update some aria2 default conf (#1425)
* chore: update deps

* chore: update axios

* chore: update default aria2 config

Some configurations are learned from
https://github.com/P3TERX/aria2.conf

* feat: preferences basic add bt-force-encryption ui
2023-04-09 21:43:04 +08:00
Shatyuka 41a81e7793 feat: add taskbar progress (#1424) 2023-04-09 21:12:19 +08:00
Dr_rOot 11c08b0dc2 chore: update new cn bug report issue template 2023-04-06 10:44:55 +08:00
Imamuzzaki Abu Salam dbc95965aa chore: Create New Bug Report Issue Template to prevent bad contributor experience 2023-04-06 10:16:18 +08:00
Dr_rOot 26b5662c82 refactor: adjust the style of the speed limit 2023-04-05 15:24:28 +08:00
Dr_rOot bb37d4f328 Merge branch 'l10n-tw-master'
chore: improve zh-TW localization quality
2023-04-05 14:23:01 +08:00
Dr_rOot b355bcf623 Merge branch 'master' of github.com:l10n-tw/Motrix into l10n-tw-master
# Conflicts:
#	src/shared/locales/zh-TW/preferences.js
2023-04-05 14:22:13 +08:00
Dr_rOot 9076ec08f8 chore: update pt-BR task stopped translate
closed #1045
2023-04-04 23:55:11 +08:00
Dr_rOot 65794cabab Merge pull request #1420 from agalwood/hotfix/mac_dmg_20230401
fix: electron-builder build mac dmg
2023-04-04 23:42:43 +08:00
Dr_rOot e3f506ec0c fix: electron-builder dmg build fail 2023-04-04 23:40:14 +08:00
Dr_rOot 70e7c99ff9 refactor: move dependencies to devDependencies
Reduce the final size of the app release
2023-04-04 23:39:57 +08:00
Dr_rOot bc66511647 refactor: remove electron-debug 2023-04-04 23:34:57 +08:00
Dr_rOot 002ef830dd fix: addTask autofillResourceLink this error 2023-04-04 23:29:15 +08:00
Shatyuka 06ffe6bd87 feat: lock AddTask dialog (#1416) 2023-04-04 23:23:32 +08:00
Sammy ecf59583d6 fix: add nullcheck for legacy speed settings (#1417) 2023-04-04 19:37:56 +08:00
Sammy 7201f17aed feat: Allow more customization for transfer speeds (#1413) 2023-04-03 10:57:51 +08:00
Dr_rOot b4df97b471 fix: hide tray not show when run mode changed 2023-04-01 22:34:08 +08:00
Dr_rOot 5ea19eb441 Merge pull request #1412 from agalwood/feature/hide_tray_20230401
feat: hide tray application
2023-04-01 17:51:02 +08:00
Dr_rOot 8857290a0a chore: update deps & bump version to 1.8.0 2023-04-01 17:26:53 +08:00
Dr_rOot 1dec09b005 feature: refactor run mode add hide tray 2023-04-01 17:13:16 +08:00
Dr_rOot d67ba74b44 refactor: application init 2023-04-01 17:11:58 +08:00
Dr_rOot 696d5c7f02 docs: update translation guide locales 2023-04-01 16:17:21 +08:00
Dr_rOot 106410cb23 docs: update lost nl locale 2023-04-01 15:36:29 +08:00
Dr_rOot 237df6011e chore: update task authorization i18n 2023-04-01 15:36:10 +08:00
Dr_rOot 20dbeb33ac refactor: mock ua 2023-03-31 20:57:07 +08:00
Dr_rOot 55e2a42f3d chore: upgrade aria2 version to 1.36 (#1411)
* chore: update build scripts

* fix: setup protocols client empty error

* refactor: auto change theme

* refactor: engine max connection per server

* refactor: adjust add task dialog style

* refactor: aria2 client lib import

* chore: update deps

* chore: striped darwin arm64 aria2c bin

* chore: strip darwin engine x64 aria2c bin

* chore: upgrade linux engine arai2c bin to 1.36

* chore: upgrade windows engine arai2c bin to 1.36
2023-03-31 20:08:19 +08:00
Dr_rOot 637d5e9a80 Merge pull request #1408 from agalwood/hotfix/some_url_fix_20230328
fix: some fix
2023-03-29 22:03:01 +08:00
Dr_rOot 9867c578dc chore: i18n update stop seeding tip 2023-03-29 21:22:45 +08:00
Dr_rOot a8bac652d1 chore: bump @motrix/nat-api version 2023-03-29 21:21:15 +08:00
Dr_rOot 7d0a94ee37 chore: change notarize deps 2023-03-29 11:54:11 +08:00
Dr_rOot 0276c8e5b4 refactor: simplified upnp mapping fail log 2023-03-29 11:53:25 +08:00
RaymondSalim e93d6a2c92 feat: add http authorization header (#1263)
Co-authored-by: Dr_rOot <agalwood.net@gmail.com>
2023-03-29 10:48:33 +08:00
Dr_rOot 8743e8a025 chore: change jsdelivr cdn url 2023-03-28 13:21:58 +08:00
Dr_rOot 680fdac38b refactor: dock manager 2023-03-28 13:21:32 +08:00
Dr_rOot e06850b5a2 chore: update Transmission mock version 2023-03-28 13:20:55 +08:00
Dr_rOot 038511fed4 fix: github actions mac skip notarize 2023-03-27 22:10:44 +08:00
Dr_rOot 6b2deb8303 fix: engine aria2 bin path 20230327 (#1405)
* fix: engine aria2 bin

* chore: upgrade github actions release node version

* chore: github actions skip notarization if not tag
2023-03-27 21:42:07 +08:00
Dr_rOot a8846eaf92 fix: update deps 20230324 (#1404)
* refactor: i18n thai language

* chore: rename renderer app name

* refactor: remove svg-innerhtml import

* refactor: update deps

* fix: protocol config save error

* fix: arch engine path copy

* chore: build arm64 arch aria2 v1.36.0
2023-03-27 21:19:56 +08:00
Dr_rOot 6039a89441 Merge pull request #1056 from 149segolte/update-windows-aria2-executables
Update Windows aria2 executables per architecture
2023-03-24 21:48:25 +08:00
Nesaku 2bfab8b9c8 fix: Improve English Translations (#1367) 2023-03-24 21:40:44 +08:00
Esteban Zapata e6c533e139 fix: spanish translation (#1361) 2023-03-24 21:40:14 +08:00
MagicLike 1c2fd0de05 fix: German translation (#1302)
- Fixed German translations for "preferences", "theme-auto", "thunder" & "auto-check-update"
2023-03-24 21:38:49 +08:00
Minseo Lee a91af1032c fix: Update Korean translation (#1290)
* Update about.js

* Update app.js

* Update edit.js

* Update help.js

* Update menu.js

* Update preferences.js

* Update app.js

* Update preferences.js

* Update task.js

* Update window.js

* Update task.js

* Update preferences.js

* Update app.js

* Update preferences.js

* Update preferences.js

* Update task.js
2023-03-24 21:38:20 +08:00
CDzungx c80102c5f5 refactor: Small Vietnamese translation update (#1162)
* refactor: Small Vietnamese translation fix

* Update edit.js

* Update task.js
2023-03-24 21:36:26 +08:00
Non-Official NPM Mirror Bot ff312df849 docs: update taobao npm registry address (#1155)
Co-authored-by: NPM Mirror Bot <npmmirror@localhost>
2023-03-24 21:35:56 +08:00
Nawapon Boonjua 65bf25dc1a feat: Translated to Thai Language (#1046) 2023-03-24 21:32:19 +08:00
toto6038 6f35e64c2a chore(l10n): Improve zh-tw localization quality 2022-04-08 23:11:21 +08:00
SiderealArt 4c5bba89ef chore: update zh-TW translation (#1107) 2022-02-13 22:37:37 +08:00
Nick Bouwhuis 51b1be7bbc feat: add Dutch language translations (#1104)
* add Dutch language translations

* fix typo

* add 'nl' to `src/shared/locales/app.js` and `src/shared/locales/all.js`

* fix indenting

Co-authored-by: Nick Bouwhuis <nick@bouwhuis.io>
Co-authored-by: Nick Bouwhuis <n.bouwhuis@speakup.nl>
2021-12-02 15:50:49 +08:00
Dr_rOot 1bf594b369 Merge pull request #1097 from tso1158687/chinese-traditional
refactor: adjust chinese traditional translation
2021-12-01 10:38:25 +08:00
Dr_rOot de1db5687b fix: add session-reset & session-reset-confirm to de language (#1103)
fix: add session-reset & session-reset-confirm to de language
2021-12-01 10:38:09 +08:00
Dr_rOot 98580fc094 Merge pull request #1093 from shatyuka/webpack_cli
fix: upgrade webpack cli parameters
2021-12-01 10:36:08 +08:00
Dr_rOot 8994312ee0 Merge pull request #1092 from shatyuka/save_preference
refactor: improve preference
2021-12-01 10:34:32 +08:00
Nick Bouwhuis bd9b5eca12 add session-reset & session-reset-confirm to de language 2021-11-27 19:44:34 +01:00
jason zheng 4ed0bba8ba adjust chinese traditional translation 2021-11-23 12:59:52 +08:00
Shatyuka 7868a4870b fix: update webpack cli parameters 2021-11-22 03:55:36 +08:00
Shatyuka 8052aa047e refactor: improve preference 2021-11-22 03:30:17 +08:00
Dr_rOot 559df6bb8f Merge pull request #1085 from shatyuka/macos_tray_tooltip
fix: do not show tray tooltip for macOS
2021-11-18 10:45:59 +08:00
Shatyuka c70a35e083 fix: do not show tray tooltip for macOS 2021-11-12 13:29:25 +08:00
149segolte 30817eac86 docs: Update Readme 2021-09-24 11:05:46 +05:30
149segolte 751efd6b00 feat: Update windows aria2 binaries to 1.36.0 2021-09-23 14:20:34 +05:30
149segolte 7688115bd4 build: Update Windows aria2 executables 2021-09-17 13:29:43 +05:30
Eshagh 732327f5a3 fix: update persian translation (#1024)
* update persian translation

* update persian translate
2021-09-13 10:48:07 +08:00
Dr_rOot 38fb29382b Merge pull request #1022 from shatyuka/fix_macos_dark_menu
fix: macos dark menu
2021-08-15 14:36:15 +08:00
Dr_rOot ee05252163 Merge pull request #1019 from shatyuka/fix_minimize
fix: showWindow won't restore minimized window
2021-08-15 14:36:04 +08:00
Shatyuka 74ba6ec5ab fix: macos dark menu icon 2021-08-09 12:10:09 +08:00
Shatyuka 1f5f5dc5f0 fix: showWindow won't restore minimized window 2021-08-06 00:17:54 +08:00
Dr_rOot 6be0afd5ff Merge pull request #998 from agalwood/feature/app_improve_20210530 2021-07-04 23:04:01 +08:00
Dr_rOot 2c269e3a52 Merge branch 'master' into feature/app_improve_20210530 2021-07-04 22:21:21 +08:00
Dr_rOot 79dea2f4b7 fix: update node version for electron-builder 2021-07-04 22:03:42 +08:00
Dr_rOot 9db5c52f13 chore: update deps 2021-07-04 22:02:48 +08:00
Dr_rOot 81a73557e8 refactor: sort i18n locale key 2021-07-04 22:02:21 +08:00
Dr_rOot 6fc02f752d chore: i18n bt-auto-download-content 2021-07-04 21:59:48 +08:00
Dr_rOot 6d893bd1ce refactor: drag select 2021-07-04 15:17:45 +08:00
albanobattistella 68ba9207f9 refactor: i18n update it (#990)
* Update app.js

* Update preferences.js

* Update task.js
2021-06-30 12:11:31 +08:00
Dr_rOot b01d43cf73 refactor: bt auto download content 2021-06-19 22:39:01 +08:00
Dr_rOot ba97bbfa66 refactor: set follow torrent metalink default true 2021-06-19 15:53:25 +08:00
dicarne b8dbc902a3 fix: reorganize the code 2021-06-19 15:51:13 +08:00
dicarne b79ef074dd feat: add switch for auto download magnet and torrent 2021-06-19 15:51:13 +08:00
dicarne 3ceccea9da fix: tasks list has old wrong items 2021-06-19 15:51:13 +08:00
CDzungx c591ea9655 refactor: Update Vietnamese translation (#978) 2021-06-19 15:51:13 +08:00
Dr_rOot 3245bbdaa1 Merge pull request #980 from dicarne/master
fix: tasks list has old wrong items and add switch for auto download torrent
2021-06-19 15:49:41 +08:00
dicarne 60161518c6 fix: reorganize the code 2021-06-15 19:50:27 +08:00
Dr_rOot 1de2acc505 fix: spawn ENAMETOOLONG by reduceTrackerString 2021-06-15 12:06:35 +08:00
dicarne a77e62066a feat: add switch for auto download magnet and torrent 2021-06-09 13:09:28 +08:00
dicarne c6722d141b fix: tasks list has old wrong items 2021-06-09 00:37:54 +08:00
CDzungx 509c79989b refactor: Update Vietnamese translation (#978) 2021-06-08 22:33:30 +08:00
Dr_rOot 333f01afd3 refactor: improve rtl support 2021-05-30 14:33:50 +08:00
Dr_rOot edd4053730 refactor: improve responsive style 2021-05-30 14:30:13 +08:00
Dr_rOot 7db1e4ff5b refactor: page init skeleton 2021-05-30 14:28:03 +08:00
Dr_rOot a9f5312a90 refactor: util bytesToSize precision 2021-05-30 14:22:17 +08:00
Dr_rOot 6d9a640030 fix: task item status 2021-05-30 13:51:03 +08:00
Dr_rOot 74c241f819 chore: remove task item action more button 2021-05-30 13:50:16 +08:00
Dr_rOot 3e0df405ee chore: update deps 2021-05-29 18:39:21 +08:00
Dr_rOot 4dd6e948f4 docs: update readme chocolatey 2021-05-29 18:35:42 +08:00
Dr_rOot c0b7612e3a Merge pull request #967 from agalwood/dependabot/npm_and_yarn/dns-packet-1.3.4
chore(deps): bump dns-packet from 1.3.1 to 1.3.4
2021-05-29 18:34:03 +08:00
dependabot[bot] 0486e4b417 chore(deps): bump dns-packet from 1.3.1 to 1.3.4
Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 1.3.1 to 1.3.4.
- [Release notes](https://github.com/mafintosh/dns-packet/releases)
- [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-29 04:12:41 +00:00
Dr_rOot 160fe9725d docs: readme add chocolatey pkg 2021-05-21 11:26:44 +08:00
Dr_rOot 577a9b32a1 Merge pull request #957 from shatyuka/fix_windows_titlebar
fix: window resize
2021-05-20 10:37:42 +08:00
Shatyuka f05994d9f8 fix: window resize 2021-05-19 22:22:58 +08:00
Dr_rOot dec938f2f0 chore: setup github action codeql 2021-05-19 12:01:37 +08:00
Dr_rOot 084b5350fd docs: update readme add flatpak 2021-05-19 10:56:10 +08:00
Dr_rOot e971f86932 docs: update readme release status of nb 2021-05-18 21:18:52 +08:00
Dr_rOot 0be90dda31 docs: update i18n contributors add nb 2021-05-18 21:14:41 +08:00
Dr_rOot 2bc4a8c61e fix: i18n get language by electron locale 2021-05-18 21:14:34 +08:00
Dr_rOot 6baef42274 Merge pull request #953 from shatyuka/macos_vibrancy
feat: add vibrancy sidebar for macos
2021-05-18 21:06:48 +08:00
Shatyuka f4cc731e63 feat: add vibrancy sidebar for macos 2021-05-18 20:54:40 +08:00
rubjo 480039c4cc feat: Added Norwegian Bokmål (#952)
* feat: Added Norwegian Bokmål (nb-NO)

* fix: Escape apstrophe

* refactor: Rename from nb-NO to nb

* fix: Learn alphabet
2021-05-18 17:07:26 +08:00
Dr_rOot b0242d3d5b chore: bump version v1.6.11 2021-05-15 22:30:00 +08:00
Dr_rOot 58cfd2b873 Merge pull request #944 from agalwood/feature/improve_detail_20210513
feat: improve task detail
2021-05-15 22:27:00 +08:00
Dr_rOot 804f864709 chore: update deps 2021-05-15 22:12:19 +08:00
Dr_rOot 57fb4d95ae feat: get file selection util 2021-05-15 21:59:01 +08:00
Dr_rOot 8030699e15 chore: i18n task select at least one 2021-05-15 21:58:22 +08:00
Dr_rOot 1185a81c0c chore: i18n save & reset 2021-05-15 21:45:41 +08:00
Dr_rOot aa4941f842 feat: save task file selection 2021-05-15 21:44:21 +08:00
Dr_rOot 841bd8b923 fix: task detail activity graphic align center 2021-05-13 21:52:57 +08:00
Dr_rOot 85ae4cdbca Merge pull request #942 from agalwood/hotfix/auto_update_20210511
fix: some bug
2021-05-12 23:34:25 +08:00
Dr_rOot c257816608 fix: element ui message z-index 2021-05-12 22:32:53 +08:00
Dr_rOot 1b44ef725b fix: task detail not auto hide when remove task 2021-05-12 11:47:18 +08:00
Dr_rOot bffe919b93 fix: add one task triggered rename rule 2021-05-12 11:24:51 +08:00
Dr_rOot 87635ade34 fix: auto theme 2021-05-12 11:24:15 +08:00
Dr_rOot c6a9eb226d fix: auto update exception 2021-05-11 15:18:21 +08:00
Dr_rOot da2b6638d9 Merge pull request #939 from agalwood/feature/lab_dark_20210509
feat: preference lab panel dark theme
2021-05-11 15:06:22 +08:00
Dr_rOot 91072509d3 refactor: mo icon 2021-05-09 22:12:47 +08:00
Dr_rOot 0d75370f95 fix: drawer header close icon could not click 2021-05-09 22:12:21 +08:00
Dr_rOot 994d351998 feat: lab page dark theme 2021-05-09 12:07:15 +08:00
Dr_rOot 166aba7747 chore: bump version v1.6.10 2021-05-07 23:22:26 +08:00
Dr_rOot bc3ea97780 Merge pull request #928 from agalwood/hotfix/app_style_20210507
fix: app style
2021-05-07 22:37:43 +08:00
Dr_rOot 2beb6f14a8 chore: update app info icon 2021-05-07 21:49:32 +08:00
Dr_rOot 5d8566a934 feat: mock ua add more ua options 2021-05-07 21:36:52 +08:00
Dr_rOot 84b002d513 feat: add more speed options 2021-05-07 21:25:29 +08:00
Dr_rOot a4fb082088 refactor: style code format 2021-05-07 21:25:04 +08:00
Dr_rOot 3aa18e7f72 fix: revert mac target 2021-05-07 19:19:10 +08:00
Dr_rOot e939f9e5dc Merge pull request #925 from agalwood/hotfix/app_hang_20210507 2021-05-07 16:40:04 +08:00
Dr_rOot 53ec0b1dee chore: update deps 2021-05-07 14:11:34 +08:00
Dr_rOot fcfd32a71e refactor: task detail style 2021-05-07 14:06:35 +08:00
Dr_rOot 2ff56a3770 refactor: task item style 2021-05-07 14:06:28 +08:00
Dr_rOot 48768f0658 fix: copyright year 2021-05-07 14:03:32 +08:00
Dr_rOot 3e84230b33 fix: app reset engine not start 2021-05-07 14:03:13 +08:00
Dr_rOot 5490946267 fix: app hang caused by child_process spawn
https://github.com/electron/electron/issues/24329#issuecomment-760699187
2021-05-07 14:02:48 +08:00
Dr_rOot 9461381042 chore: bump version v1.6.8 2021-05-06 15:30:01 +08:00
Dr_rOot 364d7a8f66 chore: lock electron-builder version to 22.10.5 2021-05-06 15:27:39 +08:00
Dr_rOot 7a5a1554ca chore: bump version & electron-builder -> 22.10.5 2021-05-06 14:58:50 +08:00
Dr_rOot 8410be59b2 chore: bump version 1.6.6 2021-05-06 14:19:22 +08:00
Dr_rOot 795db0b926 chore: github action build force release 2021-05-06 14:18:30 +08:00
Dr_rOot 079cab8544 chore: bump version v1.6.5 2021-05-06 13:57:32 +08:00
Dr_rOot 7109747e00 chore: update github actions 2021-05-06 13:56:57 +08:00
Dr_rOot 9b698f5a0e chore: bump version v1.6.3 2021-05-06 12:05:25 +08:00
Dr_rOot 2b35fb9bc2 chore: bump version v1.6.1 2021-05-06 12:02:41 +08:00
Dr_rOot 2b80127ad0 docs: update readme i18n 2021-05-06 12:01:57 +08:00
Dr_rOot d47fa3d705 chore: bump version to 1.6.0 2021-05-06 11:24:16 +08:00
Dr_rOot 555db61ec0 Merge pull request #922 from agalwood/hotfix/theme_style_20210506
refactor: task detail dark theme style
2021-05-06 11:09:57 +08:00
Dr_rOot 7c2fc774ca chore: update deps 2021-05-06 10:48:31 +08:00
Dr_rOot 8eeab3d3fa feat: task graphic dark theme style 2021-05-06 10:36:33 +08:00
Dr_rOot 7a5b16aecc refactor: task status theme 2021-05-06 10:36:02 +08:00
Dr_rOot c5f72414e2 refactor: preference store actions 2021-05-06 10:35:26 +08:00
Dr_rOot 4016f5c02e Merge pull request #921 from agalwood/feature/task_detail_20210503 2021-05-05 23:20:09 +08:00
Dr_rOot af7eb1f359 Merge branch 'master' into feature/task_detail_20210503 2021-05-05 23:08:19 +08:00
Dr_rOot f30ed3c8f7 fix: update task peers table column width 2021-05-05 22:56:44 +08:00
Dr_rOot e9e86fbc83 refactor: task detail tab content scrollable 2021-05-05 22:36:14 +08:00
Dr_rOot d7b985bc3f docs: update app features 2021-05-05 16:54:40 +08:00
Dr_rOot e307240a60 fix: remove useless code 2021-05-05 16:52:28 +08:00
Dr_rOot 8dd1d84485 chore: i18n task detail 2021-05-05 16:51:12 +08:00
Dr_rOot 3c7b0b26e3 chore: i18n bt settings 2021-05-05 16:26:01 +08:00
Dr_rOot 778e092c17 docs: update contributing locale guide 2021-05-05 15:54:32 +08:00
Dr_rOot 6e462166d1 chore: i18n task files 2021-05-05 11:35:30 +08:00
Dr_rOot 812b419379 chore: update task list i18n 2021-05-05 10:39:21 +08:00
Dr_rOot 04dcddd3e1 docs: update translation contributors 2021-05-05 09:45:23 +08:00
أحمد الطبراني 1cfec289b7 fix: Complete translation into Arabic (#919)
* refactor: Complete translation into Arabic

* refactor: Complete translation into Arabic

* Update preferences.js
2021-05-05 09:41:03 +08:00
Dr_rOot 2dcfb8c25e refactor: change some log 2021-05-04 20:38:47 +08:00
Dr_rOot 482b9312b1 chore: i18n task detail 2021-05-04 15:30:16 +08:00
Dr_rOot dbb1889fc9 feat: task detail 2021-05-04 15:06:44 +08:00
Dr_rOot a6de12c875 feat: task activity 2021-05-04 15:04:02 +08:00
Dr_rOot d14ddef8e8 feat: task peers 2021-05-04 15:03:33 +08:00
Dr_rOot c8698e5b80 refactor: task files component 2021-05-04 15:03:10 +08:00
Dr_rOot e8c99caf87 feat: task trackers 2021-05-04 14:59:31 +08:00
Dr_rOot f70595915d feat: task general info 2021-05-04 14:58:39 +08:00
Dr_rOot c5962041cb feat: task bitfield graphic 2021-05-04 14:55:39 +08:00
Dr_rOot 28bbf26334 refactor: select torrent file list 2021-05-03 20:00:07 +08:00
Dr_rOot 3d6931f8d8 refactor: main menu quit 2021-05-03 19:43:14 +08:00
Dr_rOot 46d686bee5 fix: remove file to trash for electron v11.x 2021-05-03 19:41:41 +08:00
Dr_rOot 9ffaf1116f Merge pull request #915 from agalwood/feature/bt_config_202104231109 2021-05-03 19:19:57 +08:00
Dr_rOot 2d4a05f3b0 chore: update deps lock 2021-05-03 19:01:54 +08:00
Dr_rOot e04d3a582e fix: store task checkTaskIsBT 2021-05-03 18:51:12 +08:00
Hadi Alqattan 943830f2ed feat: Add Arabic Localization
* Partial Arabic Language support!

* Partial Arabic Language support!

* translate more words...
2021-05-03 18:35:58 +08:00
Dr_rOot 137927d44a chore: revert electron from 12.x to 11.x 2021-05-03 18:33:29 +08:00
Dr_rOot 819f86632e feat: task progress info show seeder number 2021-05-03 18:18:55 +08:00
Dr_rOot 06f881932c refactor: dev env add engine log 2021-05-03 18:17:41 +08:00
Dr_rOot cb845ea65a refactor: update pause task speed use force pause 2021-05-03 18:15:24 +08:00
Dr_rOot 60e4907be6 fix: stop seeding params gid 2021-04-26 15:00:59 +08:00
Dr_rOot bc38978d6a refactor: open url external 2021-04-23 17:37:16 +08:00
Dr_rOot 90c3bbff13 fix: deps electron remote 2021-04-23 17:36:45 +08:00
Dr_rOot 3116c53734 refactor: electron remote 2021-04-23 15:12:40 +08:00
Dr_rOot 78fb6ba455 refactor: css-minimizer-webpack-plugin
replace css-minimizer-webpack-plugin with css-minimizer-webpack-plugin
2021-04-23 14:51:41 +08:00
Dr_rOot 86304c126d chore: update deps 2021-04-23 11:48:56 +08:00
Dr_rOot 3424424e67 feat: preference bt setting bt-save-metadata 2021-04-23 11:39:34 +08:00
Dr_rOot 7206f2fc3c Merge pull request #892 from agalwood/feature/bt_202103131952
feat: new app icon & bt setting
2021-04-01 23:39:57 +08:00
Dr_rOot bd25e566c8 chore: i18n zh-TW bt keep seeding 2021-03-24 23:26:02 +08:00
Dr_rOot f54bc32e90 feat: bt keep seeding 2021-03-24 23:23:04 +08:00
Dr_rOot f6dde55234 feat: new app icon 2021-03-13 21:14:43 +08:00
Dr_rOot 1303713f5e feat: reset session 2021-03-13 20:08:14 +08:00
Dr_rOot 57a5c0c932 Merge pull request #877 from agalwood/feature/engine_refactor_202102182037
refactor: replace forever with child process
2021-03-13 19:50:43 +08:00
Dr_rOot 22a41c332f Merge branch 'master' into feature/engine_refactor_202102182037
# Conflicts:
#	yarn.lock
2021-03-13 18:37:25 +08:00
Dr_rOot 76e7223e85 Merge pull request #875 from agalwood/dependabot/npm_and_yarn/elliptic-6.5.4
chore(deps): bump elliptic from 6.5.3 to 6.5.4
2021-03-13 18:35:15 +08:00
Dr_rOot 014619ed46 chore: update deps 2021-03-13 18:29:02 +08:00
Dr_rOot aec3a25e3a chore: engine error code text remove # 2021-03-13 11:23:57 +08:00
dependabot[bot] 02f6ffa3cb chore(deps): bump elliptic from 6.5.3 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-11 07:16:59 +00:00
Dr_rOot 5d32fc633c feat: add more speed options 2021-03-01 11:12:49 +08:00
Dr_rOot cde2832ae3 chore: aria2 conf http accept gzip 2021-03-01 11:10:02 +08:00
Dr_rOot 8656fa0862 refactor: replace forever with child process 2021-03-01 11:09:14 +08:00
Dr_rOot 0cd1ed1e34 Merge pull request #865 from agalwood/feature/tracker_cdn_202102181833
feat: add tracker cdn source
2021-02-18 20:31:17 +08:00
Dr_rOot d58e485846 refactor: auto sync tracker 2021-02-18 19:03:19 +08:00
Dr_rOot a6aca44672 refactor: preference tracker cdn source select 2021-02-18 18:41:57 +08:00
Dr_rOot cc28e4b19b chore: replace default tracker source config 2021-02-18 18:41:14 +08:00
Dr_rOot 599dec1d6e feat: add tracker cdn urls 2021-02-18 18:35:10 +08:00
Dr_rOot d020359058 Merge pull request #851 from upuppz/master
fix: Function overload error, unable to trigger events bound in EngineClient.vue
2021-01-14 20:23:02 +08:00
upuppz 04d68e293b fix: Function overload error, unable to trigger events bound in EngineClient.vue(函数重载错误, 无法触发在 EngineClient.vue 中绑定的事件) 2021-01-12 18:25:48 +08:00
upuppz 6b93a80888 Merge pull request #4 from agalwood/master
Sync
2021-01-12 18:20:49 +08:00
Dr_rOot c3400d936e Merge pull request #844 from alyn3d/master
feat: Added Romanian translation
2021-01-05 11:12:11 +08:00
alyn3d 871be123d4 feat: Added Romanian translation 2021-01-03 00:29:01 +02:00
Dr_rOot bed2148ba0 Merge pull request #843 from agalwood/hotfix/tray_retina_202012292116
refactor: dynamic tray scale
2020-12-29 21:24:16 +08:00
Dr_rOot 8b97c90e88 refactor: dynamic tray scale 2020-12-29 21:16:36 +08:00
Dr_rOot 832befbafd Merge pull request #842 from agalwood/hotfix/style_202012291454
fix: some style improve
2020-12-29 21:05:31 +08:00
Dr_rOot ddbf27e2f9 refactor: form actions position sticky 2020-12-29 14:55:57 +08:00
Dr_rOot 64b30b6c26 fix: task progress info text font style normal 2020-12-29 14:55:38 +08:00
Dr_rOot 32c8767e65 Merge pull request #840 from agalwood/hotfix/multispinner_202012282315
chore: replace multispinner deps
2020-12-28 23:27:48 +08:00
Dr_rOot 69391c6de0 chore: update deps 2020-12-28 23:21:47 +08:00
Dr_rOot fbec4e7c4d Merge pull request #839 from shatyuka/big_sur_tray
fix: big sur tray color
2020-12-28 23:14:13 +08:00
Shatyuka 7640ba583d fix: big sur tray color 2020-12-28 19:45:53 +08:00
Dr_rOot 924b397727 Merge pull request #838 from agalwood/hotfix/tray_workder_202012271447
fix: tray worker cannot find module 'lodash'
2020-12-27 21:45:06 +08:00
Dr_rOot 565afdde74 chore: update deps & change npm to yarn 2020-12-27 20:07:53 +08:00
Dr_rOot 3dfd4ec4da fix: tray worker cannot find module 'lodash' 2020-12-27 14:47:55 +08:00
Dr_rOot 0a21f590ff Merge pull request #836 from shatyuka/apple_silicon
feat: Support Apple Silicon
2020-12-27 14:45:37 +08:00
カワリミ人形 79bf90bb3c docs: Fix installation instructions in README.md (#834) 2020-12-26 21:09:55 +08:00
Shatyuka f4602b4b68 fix: import JSONRPCError 2020-12-26 13:00:29 +08:00
Shatyuka 93a6f1cfbd fix: Shadow not complete 2020-12-26 12:00:08 +08:00
Shatyuka f0d14afb7e chore: update dependency sass-loader 2020-12-26 11:10:02 +08:00
Shatyuka d9a69ae009 fix: use iframe instead of webview 2020-12-26 09:29:26 +08:00
Shatyuka 0f5398b106 fix: engine failed to quit 2020-12-26 09:03:38 +08:00
Shatyuka c6eb96547a fix: tray menu crash 2020-12-26 07:39:00 +08:00
Shatyuka 31ab487d82 feat: Add native arm support for macos aria2
universal binary
2020-12-26 06:03:36 +08:00
Shatyuka 0b2e271663 feat: Update electron to 11 to support Apple Silicon
Update almost all of the dependencies.
This commit only promises the app would be successfully built and run.
2020-12-26 00:09:44 +08:00
jimman2003 a4a4b2321f fix: updated axios and forever-monitor to get rid of error in dev enviroment (#818) 2020-12-09 20:51:18 +08:00
XIU2 ef372da87b fix: replace TrackersListCollection other.txt with http.txt (#809) 2020-11-25 13:59:00 +08:00
Dr_rOot 10cab1a9a0 docs: readme i18n add Italiano 2020-10-09 21:08:55 +08:00
blackcat-917 a4a651b397 feat: Added Italian language (#794)
* Feat: added italian

* Small fix

* Update index.js to match to the original indent style
2020-10-09 20:56:06 +08:00
Dr_rOot b2770795ad docs: i18n add el (Greek) 2020-08-30 13:22:17 +08:00
Akis S f4c8ff66d5 feat: Added Greek language (#774)
* feat: Added Greek language

* Update index.js
2020-08-30 13:17:49 +08:00
Dr_rOot 1b450c8022 docs: i18n add missing locales es & hu 2020-08-04 21:52:14 +08:00
zalnars e5b8846286 feat: Added Hungarian language (#754)
* Added Hungarian language

* Update all.js

* Update app.js

* Update all.js
2020-07-26 21:06:19 +08:00
Samuel Martineau 8de8591725 fix: correction of the french locale (#742)
* Correction of the French locale

- `transfer-speed-upload`and `transfer-speed-download` were the same
- `transfer-speed-unlimited` was still in English

* fix: correction of the french locale

* fix: correction of the french locale
2020-07-15 20:55:17 +08:00
Dr_rOot 20c30279b0 docs: update readme cn 2020-07-04 21:43:00 +08:00
Stanisław Nieradko 9000be502b feat: Added Polish (#731)
* Added Polish

* Sorted imports in src/shared/locales/app.js
2020-07-04 21:36:34 +08:00
Dr_rOot cfe66cf337 Merge pull request #720 from agalwood/feature/tray_speedometer_202006211216
feat: menu bar tray speedometer #643
2020-06-21 21:30:51 +08:00
Dr_rOot 3557d17bb6 chore: update deps, upgrade electron to 9.x
> That was a bug in Chromium, which got fixed by this [commit](https://chromium.googlesource.com/chromium/src/+/09514b7fbd4fb14ce12a43bc7f4807179612fa94) (available in Chrome v83).

https://stackoverflow.com/questions/61268950/offscreen-converttoblob-very-slow
2020-06-21 21:10:22 +08:00
Dr_rOot 2af891aab8 chore: i18n tray speedometer 2020-06-21 16:23:07 +08:00
Dr_rOot 0d276de39b feat: preference tray speedometer setting 2020-06-21 16:12:35 +08:00
Dr_rOot 8a6beda335 feat: tray speedometer 2020-06-21 16:12:04 +08:00
Dr_rOot 68f1cdc4de chore: update copyright year 2020-06-21 15:30:28 +08:00
Dr_rOot 5290fcfa14 feat: dockmanager add handleSpeedChange 2020-06-21 15:21:06 +08:00
Dr_rOot d865b630a3 refactor: rename enable args 2020-06-21 15:19:50 +08:00
Dr_rOot 9d95d294cd refactor: rename store actions mutations 2020-06-21 13:47:02 +08:00
Dr_rOot ea46d9b3c6 refactor: load config fn use ipc invoke 2020-06-21 12:33:28 +08:00
Dr_rOot ef2c992af9 refactor: remove deprecated fns 2020-06-21 12:30:43 +08:00
Dr_rOot 64ee097c85 Merge pull request #718 from agalwood/feature/stop_seeding_202006201236
fix: stop bt task seeding notification #604
2020-06-20 18:29:48 +08:00
Dr_rOot 31517f93cb chore: i18n stopping seeding tip 2020-06-20 15:51:24 +08:00
Dr_rOot 6d54e557b9 fix: oddly stop seeding notify #604 2020-06-20 15:50:18 +08:00
Dr_rOot 3e61adcea3 Merge pull request #716 from agalwood/feature/url_protocol_202005290826
refactor: redesign motrix scheme
2020-06-20 12:34:52 +08:00
Dr_rOot 84d9ced137 Merge pull request #714 from agalwood/hotfix/hide_run_mode_202006192140
fix: preference show run mode only in macOS
2020-06-19 23:01:36 +08:00
Dr_rOot bc45ed9d5b refactor: add jsconfig 2020-06-19 21:44:53 +08:00
Dr_rOot 3d98104dbf fix: preference show run mode only in macOS 2020-06-19 21:42:00 +08:00
Dr_rOot fb6986ff6e docs: update readme app icon 2020-06-19 20:55:07 +08:00
Dr_rOot b8507570c6 refactor: rename initialForm to initForm 2020-06-12 17:22:38 +08:00
Dr_rOot cf3ef7606c fix: new task uri 2020-06-06 23:31:24 +08:00
Dr_rOot 12a9fa92c1 chore: bump version 2020-06-05 23:54:14 +08:00
Dr_rOot 0fd6617eba docs: update readme i18n 2020-06-05 23:52:34 +08:00
Dr_rOot 7ebbf929d5 fix: i18n no-confirm-before-delete-task missed 2020-06-05 23:49:27 +08:00
Dr_rOot 14223c2204 chore: bump version 2020-06-05 23:26:11 +08:00
Dr_rOot 2cfb6b1914 Merge pull request #689 from agalwood/hotfix/handle_url_202006051331
fix: open app with url handle fail
2020-06-05 14:04:27 +08:00
Dr_rOot c38cf80589 chore: update deps 2020-06-05 13:40:30 +08:00
Dr_rOot 3ee98eae1d fix: open app with resource url 2020-06-05 13:33:22 +08:00
Dr_rOot d2cff6356a Merge pull request #686 from NickoAilus/master
fix: edited Russian locale
2020-06-01 22:12:46 +08:00
NickoAilus 3ee432d683 Fixed Russian locale 2020-06-01 16:10:36 +03:00
Dmitry Kalinin 7f1822bb7e feat: Added bulgarian (bg) translations (#685)
* Added bulgarian (bg) translations

* Improve structure

* Fixed bugs

* Deleted comma
2020-06-01 17:33:46 +08:00
Dr_rOot 0223e691ff docs: readme i18n add vi 2020-05-31 22:57:56 +08:00
Duy–Thanh Doan 117dba9f37 feat: Add vietnamese translation (#680)
* Add vietnamese translation

* Update app.js and index.js

* Translated about.js

* Translated app.js

* first draft

* final draft

* final update - ready to review

* Update format
2020-05-31 22:52:26 +08:00
Dr_rOot e5241d09d7 refactor: protocol manager init 2020-05-29 17:28:03 +08:00
Dr_rOot c9ea1dece2 refactor: motrix url protocol 2020-05-29 17:02:43 +08:00
Dr_rOot 60d4108ddc refactor: promise all to allSettled 2020-05-29 17:00:47 +08:00
Dr_rOot ffc8de4766 refactor: add task utils 2020-05-29 16:58:35 +08:00
Dr_rOot 66f114bf72 Merge pull request #674 from agalwood/hotfix/upnp_cb_202005271904
fix: nat-api autoUpdate cb is not a function
2020-05-28 15:28:28 +08:00
Dr_rOot 44f00483f9 chore: update deps 2020-05-28 14:42:43 +08:00
Dr_rOot 1866e3fd4f fix: nat-api autoUpdate cb is not a function
replace nat-api to @motrix/nat-api

@motrix/nat-api forked from https://github.com/alxhotel/nat-api
2020-05-28 14:42:05 +08:00
Dr_rOot cfac883cbf chore: remove deprecated vue-html-loader 2020-05-28 12:11:30 +08:00
Dr_rOot 1431bab366 Merge pull request #670 from agalwood/hotfix/full_screen_preference_202005271103
fix: full screen save preference issue #663
2020-05-27 11:20:23 +08:00
Dr_rOot bb373947ff fix: full screen save preference issue #663 2020-05-27 11:06:51 +08:00
Dr_rOot 8f0dc65341 refactor: rename auto hide window 2020-05-27 11:06:31 +08:00
Dr_rOot 402185e1a2 chore: bump version 2020-05-25 22:35:09 +08:00
Dr_rOot d59b5c9841 Merge pull request #667 from agalwood/hotfix/refactor_202005231656
fix: upnp client & full screen issues
2020-05-25 22:15:36 +08:00
Dr_rOot eb442e4a7a fix: windows auto launch config lose 2020-05-25 21:55:23 +08:00
Dr_rOot e82e567069 refactor: time constants 2020-05-24 20:15:20 +08:00
Dr_rOot dc2876098d fix: upnp client is destroyed #662 2020-05-24 20:13:43 +08:00
Dr_rOot 6287942fbc fix: full screen mode no traffic light #663 2020-05-24 17:04:08 +08:00
Dr_rOot 389dc080b6 refactor: improve macOS fullscreen mode usability 2020-05-24 15:30:50 +08:00
Dr_rOot 45a23d73e6 fix: code error 2020-05-23 17:16:16 +08:00
Dr_rOot 8303dd305b refactor: fn rename & format 2020-05-23 17:03:45 +08:00
Dr_rOot a98292ce1e refactor: remove title bar buttons spacer 2020-05-23 16:57:01 +08:00
Dr_rOot 8df97b8433 fix: switching system theme will not auto switch app theme 2020-05-22 11:21:45 +08:00
Dr_rOot f29e95c9bc chore: add electron apps banner 2020-05-21 16:32:10 +08:00
Dr_rOot 52e045c886 docs: update readme for github markdown 2020-05-21 08:56:28 +08:00
Dr_rOot 4632c3619a docs: update readme 2020-05-21 08:54:01 +08:00
Dr_rOot 54c48be29b chore: bump version 2020-05-21 07:51:47 +08:00
Dr_rOot 301f1403df Merge pull request #658 from aarestu/translation/indonesia
feat: add Indonesian translations
2020-05-21 07:17:12 +08:00
Dr_rOot 88de047778 Merge pull request #659 from agalwood/hotfix/webpack_copy_202005210655
fix: webpack copy plugin path
2020-05-21 07:07:29 +08:00
Dr_rOot c119de78ce fix: webpack copy plugin path 2020-05-21 06:56:04 +08:00
Restu Suhendar 9d381e16da add translation Indonesia 2020-05-21 04:24:07 +07:00
Dr_rOot e4c6d6a9c0 Merge pull request #655 from agalwood/hotfix/linux_tray_202005202115
fix: linux tray context menu
2020-05-20 21:33:13 +08:00
Dr_rOot 5bb727cb6f chore: update deps 2020-05-20 21:16:35 +08:00
Dr_rOot 00f3209c68 refactor: improve logs 2020-05-20 21:16:11 +08:00
Dr_rOot 3f8b0e6f5f fix: tray popUpContextMenu linux not support 2020-05-20 21:16:01 +08:00
Dr_rOot 0543bc4e2c chore: bump version 2020-05-20 16:32:55 +08:00
Dr_rOot 9ded42f127 chore: update docs 2020-05-20 13:53:20 +08:00
Dr_rOot 834a1ad839 docs: update readme linux section 2020-05-20 11:30:50 +08:00
Dr_rOot 8f830f6a0d fix: too fast to toggle tracker syncing spinner 2020-05-20 11:10:59 +08:00
Dr_rOot ee111c92ee fix: too fast to shut down the engine 2020-05-20 11:09:50 +08:00
Dr_rOot 74c3a3c696 Merge pull request #650 from agalwood/hotfix/linux_tray_20200519
fix: linux tray not support right-click event
2020-05-19 22:06:45 +08:00
Dr_rOot 4d964ae16e fix: tray destroy remove listener 2020-05-19 21:50:36 +08:00
Dr_rOot be2c2e8383 docs: update readme snapcraft markdown 2020-05-19 12:23:31 +08:00
Dr_rOot 4e6164816f fix: linux tray not support right click 2020-05-19 12:23:00 +08:00
Dr_rOot fa7daf377f docs: update app screenshots 2020-05-18 14:24:06 +08:00
Dr_rOot afbe364525 docs: fix release badge 2020-05-18 13:43:36 +08:00
Dr_rOot ece5cea512 docs: update readme 2020-05-18 13:37:36 +08:00
Dr_rOot dc8fa5c647 chore: bump version v1.5.10 2020-05-15 21:54:16 +08:00
Dr_rOot 4fd96e7cae chore: bump version v1.5.9 2020-05-15 21:45:22 +08:00
Dr_rOot 1f22b5efba Merge pull request #640 from agalwood/hotfix/task_manager_202005151229
fix: save session delay too long
fix: hide delete selected tasks on stopped task list
2020-05-15 16:44:31 +08:00
Dr_rOot 801db0ed38 chore: upgrade electron 2020-05-15 12:34:39 +08:00
Dr_rOot f72577de65 fix: hide delete selected tasks on stopped task list 2020-05-15 12:33:58 +08:00
Dr_rOot dd21c76dea fix: save session delay too long 2020-05-15 12:29:51 +08:00
Dr_rOot 5a5a932735 Merge pull request #639 from agalwood/feature/no_confirm_202005062312
feat: no confirm before delete task
feat: add task select video include sub files
feat: preference support add custom tracker source #627
feat: Ctrl or ⌘ + Enter quick submit task #638
feat: improve task total length is zero ui #614
fix: split & max-connection-per-server failed #270
fix: npm build:clean script
2020-05-15 00:03:54 +08:00
Dr_rOot d63c1d431d feat: improve task total length is zero ui #614 2020-05-14 23:43:42 +08:00
Dr_rOot 1a12256c4c feat: Ctrl or ⌘ + Enter quick submit task 2020-05-14 23:40:37 +08:00
Dr_rOot 9394a0a79b chore: update deps & bump version 2020-05-14 22:27:44 +08:00
Dr_rOot 5e66205298 chore: disable electron security warnings 2020-05-14 22:26:34 +08:00
Dr_rOot eb796c3c5f feat: add task select video include sub files 2020-05-14 22:26:11 +08:00
Dr_rOot 9d17b3e9b2 fix: split & max-connection-per-server failed #270 2020-05-14 22:25:35 +08:00
Dr_rOot 7ee8d4fa0f refactor: engine instance listeners 2020-05-14 22:21:57 +08:00
Dr_rOot dba4bfb0e7 fix: perference sync tracker empty 2020-05-14 22:20:23 +08:00
Dr_rOot f9755f69cd chore: improve aria2 bt config 2020-05-14 22:20:02 +08:00
Dr_rOot 7a68e1bb82 fix: npm build:clean script 2020-05-14 22:14:18 +08:00
Dr_rOot 3b12f3960f refactor: code format 2020-05-14 22:13:56 +08:00
Dr_rOot dbe26dfa98 feat: preference support add custom tracker source 2020-05-14 22:12:34 +08:00
Dr_rOot 3be8952cff refactor: task actions commands 2020-05-14 22:08:59 +08:00
Dr_rOot dc5a368e00 Merge pull request #630 from agalwood/hotfix/aria2c_darwin_202005081709
fix: rebuild darwin aria2c v1.35

closed #628
2020-05-08 17:30:53 +08:00
Dr_rOot 11aca7ea0b chore: remove bt-force-encryption 2020-05-08 17:16:48 +08:00
Dr_rOot c35af2b109 fix: rebuild aria2c #628
static build script:
https://github.com/aria2/aria2/blob/master/
makerelease-osx.mk
2020-05-08 17:12:04 +08:00
Dr_rOot b33b505ccb refactor: upnp close client 2020-05-06 23:21:49 +08:00
Dr_rOot dd22cc0306 fix: remove enable egg features config 2020-05-06 23:19:58 +08:00
Dr_rOot 206eda08aa refactor: renderer native utils 2020-05-06 23:19:08 +08:00
Dr_rOot f6e29700d0 feat: no confirm before delete config 2020-05-06 23:16:50 +08:00
Dr_rOot c17ceb365d chore: upgrade electron-builder 2020-05-03 23:00:41 +08:00
Dr_rOot a1851c6b31 chore: bump version v1.5.6 2020-05-03 22:10:32 +08:00
Dr_rOot 071b0a21c2 chore: bump version v1.5.5 2020-05-03 21:58:39 +08:00
Dr_rOot e25dfb143c Merge pull request #621 from agalwood/hotfix/prepare_release_202004280758
refactor: redesigned the lab page
2020-05-03 21:32:12 +08:00
Dr_rOot 652f04bada chore: bump version 2020-05-03 20:26:06 +08:00
Dr_rOot 5962334f3d feat: new lab page 2020-05-03 20:25:32 +08:00
Dr_rOot f984b175dc refactor: code format 2020-05-03 20:25:05 +08:00
Dr_rOot ad1979417a refactor: engine config 2020-04-30 22:22:48 +08:00
Dr_rOot 16822b9b55 Merge pull request #618 from agalwood/feature/upgrade_aria2_202004302143
feat: upgrade aria2 to v1.35.0
2020-04-30 22:15:34 +08:00
Dr_rOot 36551da19e refactor: arai2 config 2020-04-30 21:46:01 +08:00
Dr_rOot f3426fdc90 chore: upgrade aria2 version to 1.35.0
Compile it with reference to the script of q3aql/aria2-static-builds. The difference from the official version of Aria2 is that the max-connection-per-server is modified to 64.

https://github.com/q3aql/aria2-static-builds
2020-04-30 21:45:46 +08:00
Dr_rOot 94ead296bf docs: update readme 2020-04-30 13:26:40 +08:00
Dr_rOot 22a6f73e51 Merge pull request #616 from agalwood/feature/github_action_202004292314
feat: github action
2020-04-30 11:47:28 +08:00
Dr_rOot 94b4c08da9 fix: travis ci rpm 2020-04-30 11:03:52 +08:00
Dr_rOot 041b7701c2 fix: remove pacman 2020-04-30 00:23:27 +08:00
Dr_rOot c20d9b65ee fix: github action mac build notarize 2020-04-30 00:10:57 +08:00
Dr_rOot 47c5daea81 feat: test github action 2020-04-29 23:15:45 +08:00
Dr_rOot 9676e2a060 fix: remove ci node-sass config 2020-04-28 22:50:52 +08:00
Dr_rOot bb75fa6dcc refactor: change drag select color 2020-04-28 13:28:36 +08:00
Dr_rOot b547ef8f2e refactor: improve shutdown upnp speed 2020-04-28 13:22:20 +08:00
Dr_rOot cc44e21d0e feat: implemented menu pause & resume task 2020-04-28 13:22:20 +08:00
Dr_rOot 20ac050514 Merge pull request #615 from agalwood/hotfix/update_deps_202004271523
chore: update dependencies
2020-04-28 08:27:31 +08:00
Dr_rOot 7eeafb6c93 chore: update deps 2020-04-28 08:15:52 +08:00
Dr_rOot 6fd63c872f fix: windows aria2 cmd
revert forever-monitor version to 1.7.2

https://github.com/foreversd/forever-monitor/commit/93cfbef1c5248eeccf00f4d760c04625476aeb51#commitcomment-37379168
2020-04-28 07:56:54 +08:00
Dr_rOot b8b4f04423 chore: bump version 2020-04-27 23:36:30 +08:00
Dr_rOot e3e2abac6f chore: js code format 2020-04-27 23:33:48 +08:00
Dr_rOot b34f3ceb89 chore: vue code format 2020-04-27 23:30:17 +08:00
Dr_rOot feb07a43e1 chore: upgrade babel & eslint 2020-04-27 23:28:38 +08:00
Dr_rOot 4652672ef4 refactor: replace node-sass to dart-sass 2020-04-27 23:23:45 +08:00
Dr_rOot 8b375c019d refactor: code format 2020-04-27 17:59:45 +08:00
Dr_rOot e232e4af70 fix: upnp config watch 2020-04-27 10:02:12 +08:00
Dr_rOot f57d71cebe Merge pull request #611 from agalwood/feature/upnp_202004222153
feat: UPnP support

Closed #411
2020-04-26 23:08:27 +08:00
Dr_rOot 90daf4cb19 chore: bump version 2020-04-22 22:01:37 +08:00
Dr_rOot d1f759ec44 fix: update task progress info with 2020-04-22 22:00:22 +08:00
Dr_rOot 45ad6dfbda chore: update chrome ua 2020-04-22 21:59:35 +08:00
Dr_rOot 65d45f69fe fix: engine shutdown 2020-04-22 21:59:25 +08:00
Dr_rOot 7e626704ac feat: router upnp mapping 2020-04-22 21:58:53 +08:00
Dr_rOot e0f9dce952 Merge pull request #605 from agalwood/hotfix/app_improve_202004062214
refactor: app improve
Closed #588 #547 #491 #484 #481 #439 #425 #410 #376 #174 #106 #85 #27 #560 #413 #598 #551 #603
2020-04-21 18:01:26 +08:00
Dr_rOot edf627923e fix: after sign hook 2020-04-21 17:47:24 +08:00
Dr_rOot 40f7abcc22 fix: drag select components path at linux 2020-04-21 17:36:13 +08:00
Dr_rOot d837e97d02 fix: dev build html webpack plugin 2020-04-21 17:32:48 +08:00
Dr_rOot 13034b4e90 chore: update deps & bump version to 1.5.x 2020-04-21 17:32:30 +08:00
Dr_rOot b3826032ea refactor: max connection per server 2020-04-20 21:40:31 +08:00
Dr_rOot d5e9ada2c9 chore: i18n batch delete task 2020-04-19 15:32:51 +08:00
Dr_rOot 724a2a7f76 fix: aria2 bt conf 2020-04-18 18:02:07 +08:00
Dr_rOot 64326a11af feat: select all task hotkey 2020-04-18 18:01:26 +08:00
Dr_rOot b00536a0c7 feat: task list drag select & batch delete task 2020-04-18 17:31:11 +08:00
Dr_rOot 8885e63474 feat: drag select component
forked from andi23rosca/drag-select-vue
2020-04-18 16:47:14 +08:00
Dr_rOot 28936fd13e feat: batch remove task api 2020-04-18 16:21:00 +08:00
Dr_rOot 08a419f209 refactor: task progress info 2020-04-18 13:18:30 +08:00
Dr_rOot 8a3391c9f4 fix: restart task option split 2020-04-18 11:26:58 +08:00
Dr_rOot 3777a1f753 refactor: remove task 2020-04-18 11:26:11 +08:00
Dr_rOot b81298d6eb refactor: batch change task option api 2020-04-18 11:20:18 +08:00
Dr_rOot f67b9b8dd6 refactor: task status 2020-04-18 10:38:05 +08:00
Dr_rOot a303afb9a5 refactor: improve max connection per server 2020-04-17 22:44:35 +08:00
Dr_rOot eee07b1b7d chore: update readme features 2020-04-15 23:57:00 +08:00
Dr_rOot a27c49a376 chore: update readme 2020-04-15 21:23:21 +08:00
Dr_rOot fd81dc5194 fix: get random int util 2020-04-13 21:24:21 +08:00
Dr_rOot 394dfdfffc chore: i18n bt listen ports 2020-04-13 21:22:25 +08:00
Dr_rOot 99e9aa8046 feat: advanced preference bt listen ports setting 2020-04-12 22:23:43 +08:00
Dr_rOot ec295b3d72 refactor: is renderer linux mas 2020-04-12 19:57:10 +08:00
Dr_rOot 8208440987 feat: bt listen ports config 2020-04-12 19:52:37 +08:00
Dr_rOot 47426f2d66 refactor: import code format 2020-04-12 15:41:16 +08:00
Dr_rOot ac75a05511 refactor: tray manager 2020-04-12 15:31:23 +08:00
Dr_rOot c3ff1f3b23 refactor: log format 2020-04-11 14:22:15 +08:00
Dr_rOot 0f3157980c refactor: remove outdated trackers 2020-04-10 21:12:59 +08:00
Dr_rOot 36929f9dc5 feat: fetch task item peers api 2020-04-07 11:19:19 +08:00
Dr_rOot 11c507008b refactor: app quit 2020-04-06 22:32:44 +08:00
Dr_rOot 3d66549849 fix: preference diff changed 2020-04-06 22:15:44 +08:00
Dr_rOot 47ca535268 fix: main engine client add catch 2020-04-06 22:15:12 +08:00
Dr_rOot 7d102f9fcb fix: constants duplicate declaration 2020-04-06 22:11:22 +08:00
Dr_rOot edf350adf3 Merge pull request #596 from agalwood/hotfix/task_dir_202004061122
fix: several file path related issues

closed #575
2020-04-06 16:56:03 +08:00
Dr_rOot 651f28e7e8 refactor: add task type constant 2020-04-06 16:36:36 +08:00
Dr_rOot 4d7acb7c0a refactor: app theme constant 2020-04-06 16:31:42 +08:00
Dr_rOot b75e969a01 refactor: move task files to trash 2020-04-06 14:46:55 +08:00
Dr_rOot 0b6f5e7d43 refactor: show item in folder 2020-04-06 14:46:45 +08:00
Dr_rOot a82000a13b refactor: temp disabled prettifyDir 2020-04-06 11:27:44 +08:00
Dr_rOot edee889a1a docs: update travis-ci build status badge url 2020-04-05 23:19:29 +08:00
Dr_rOot afd2fdeabf Merge pull request #594 from agalwood/feature/proxy_setting_20200405227
feat: improve proxy setting
2020-04-05 23:18:43 +08:00
Dr_rOot 34011d7bc8 refactor: move rename utils location 2020-04-05 22:50:30 +08:00
Dr_rOot 6cf6b69f8e chore: i18n add task proxy 2020-04-05 22:49:58 +08:00
Dr_rOot a386c704e4 feat: add task support use proxy 2020-04-05 22:49:40 +08:00
Dr_rOot 0994244b0e chore: i18n no proxy input tip 2020-04-05 22:48:37 +08:00
Dr_rOot 777977e001 feat: advanced preference no proxy setting 2020-04-05 22:48:07 +08:00
Dr_rOot af5ac44dc8 Merge pull request #592 from agalwood/hotfix/update_ci_conf_202004052048
chore: update ci conf
2020-04-05 21:46:02 +08:00
Dr_rOot 23382a9415 chore: update ci conf 2020-04-05 20:50:55 +08:00
Dr_rOot 7b2da0f35b Merge pull request #590 from agalwood/feature/tracker_source_202002091515
feat: sync tracker add more source and support auto sync tracker data daily
2020-04-05 12:36:19 +08:00
Dr_rOot 4037dad582 docs: update readme add install electron guide 2020-03-22 23:32:45 +08:00
Dr_rOot 353ee23cfc feat: preference show last sync tracker time 2020-02-23 22:19:45 +08:00
Dr_rOot 29b0d90bc7 fix: Application showPage fn may cause memory leak
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 ready-to-show listeners added to [BrowserWindow]. Use emitter.setMaxListeners() to increase limit
2020-02-23 12:08:41 +08:00
Jiaqi Gu 073e514f95 feat: Automatically hide window when losing focus (#557)
Automatically hide window when losing focus
2020-02-23 11:59:19 +08:00
Dr_rOot a35fba4820 fix: i18n uk transfer settings 2020-02-22 15:47:28 +08:00
Dr_rOot 828d854eb5 chore: i18n sync tracker 2020-02-22 15:46:04 +08:00
Dr_rOot 5dbe157170 feat: auto sync tracker when app launch 2020-02-21 22:26:22 +08:00
Dr_rOot cdc196c2b0 refactor: save preference config 2020-02-21 22:21:05 +08:00
Dr_rOot 3d26445953 refactor: app updater auto check 2020-02-21 22:15:41 +08:00
Dr_rOot f887878b9e feat: main init engine client 2020-02-21 22:11:07 +08:00
Dr_rOot 908f60df1a feat: advanced preference auto sync tracker 2020-02-21 22:04:45 +08:00
Dr_rOot 56c9b58d87 refactor: advanced preference sync tracker 2020-02-20 19:29:54 +08:00
Dr_rOot d56983d45d refactor: fetch bt tracker data 2020-02-20 19:23:48 +08:00
Dr_rOot 8775e12587 refactor: launcher callback 2020-02-19 20:45:48 +08:00
Dr_rOot df2e01813e feat: add trackers blacklist constant 2020-02-18 17:08:01 +08:00
Dr_rOot d77a6faf36 fix: aria2 bt conf 2020-02-16 13:42:46 +08:00
Dr_rOot 5e735b513d feat: task show connections 2020-02-12 16:12:57 +08:00
Dr_rOot 64f0a3db80 fix: sync old data when tracker source changed 2020-02-10 11:05:38 +08:00
Dr_rOot e470ed00d6 refactor: engine rpc config 2020-02-09 15:51:01 +08:00
Dr_rOot 36a27bae46 feat: preference select sync tracker source 2020-02-09 15:44:55 +08:00
Dr_rOot 5d900806e8 fix: system engine config keys 2020-02-09 15:34:45 +08:00
Dr_rOot ace14c85dc refactor: improve ui style 2020-02-09 15:33:13 +08:00
Dr_rOot 3ec4bd26e6 refactor: update manager last check update time 2020-02-09 15:32:04 +08:00
Dr_rOot b9bc5e6c07 feat: auto remove aria2c unrecognized options 2020-02-09 15:23:00 +08:00
Dr_rOot 021fbc243a refactor: rename & add tracker source 2020-02-09 15:21:55 +08:00
Dr_rOot 8b66f2ea6e refactor: make tracker unique 2020-02-09 15:18:11 +08:00
Dr_rOot 7703c28c6e Merge pull request #544 from agalwood/feature/win_title_bar_202002081321
feat: improve win & linux title bar style

Closes #461
2020-02-08 16:07:08 +08:00
Dr_rOot 26db88ec51 refactor: adjust close btn color for win & linux 2020-02-08 13:23:35 +08:00
Dr_rOot 51b7ea4030 refactor: remove title bar button spacing 2020-02-08 13:22:02 +08:00
Dr_rOot 1e2368dd3b docs: update contribution guide 2020-02-08 12:50:04 +08:00
Dr_rOot f28c3ae5c5 fix: adapt the new api of Electron's TouchBar 2020-02-06 22:22:00 +08:00
Dr_rOot ebdd125d91 Merge pull request #529 from agalwood/feature/proxy_tip_202001311802
feat: Perference advanced panel add proxy tip

close #488
2020-01-31 18:50:14 +08:00
Dr_rOot 9bcc386269 feat: perference advanced proxy tip i18n 2020-01-31 18:16:04 +08:00
Dr_rOot 27c48af278 feat: advanced perference add proxy tip 2020-01-31 18:15:37 +08:00
Dr_rOot 4b4df884dc Merge pull request #528 from agalwood/feature/run_mode_202001311505
feature: Preferences add Run Mode setting

close #345 #350
2020-01-31 16:02:10 +08:00
Dr_rOot 64082ddd70 fix: i18n rename appLocalePtBr to appLocalePtBR 2020-01-31 15:45:12 +08:00
Dr_rOot 188a39d0d2 refactor: i18n rename ru-RU to ru 2020-01-31 15:44:30 +08:00
Dr_rOot 44f8f23a7c feat: run mode i18n 2020-01-31 15:37:56 +08:00
Dr_rOot 32340218e2 refactor: change dock state use DockManager 2020-01-31 15:20:01 +08:00
Dr_rOot 85a8430c3f refactor: ipc change update menu state to command 2020-01-31 15:17:45 +08:00
Dr_rOot e47816e273 refactor: save preference use ipc message 2020-01-31 15:15:55 +08:00
Dr_rOot b7356702fc feat: add DockManager 2020-01-31 15:10:51 +08:00
Dr_rOot a61c857e11 feat: add run mode config 2020-01-31 15:09:31 +08:00
Dr_rOot d3ef30d943 refactor: speed options i18n 2020-01-31 15:07:49 +08:00
Dr_rOot b8d5eb5ac1 fix: add task out i18n 2020-01-31 15:06:14 +08:00
Dr_rOot aeaf0fe9ca Merge pull request #527 from agalwood/feature/improve_responsive_202001311239
feature: improve responsive 202001311239
2020-01-31 14:20:24 +08:00
Dr_rOot 8bebb942ca fix: remove TaskSwitch 2020-01-31 14:11:25 +08:00
Dr_rOot f0e795f00c refactor: code format 2020-01-31 12:49:24 +08:00
Dr_rOot 7d4eec6b02 feat: preference responsive subnav switcher 2020-01-31 12:45:30 +08:00
Dr_rOot fe2dc7a541 refactor: task subnav switcher 2020-01-31 12:42:39 +08:00
Dr_rOot 848b9e78e1 Merge pull request #525 from agalwood/hotfix/fix_open_dialog_202001301122
fix: electron v7 dialog showOpenDialog promisify
2020-01-30 15:14:00 +08:00
Dr_rOot 2fa33f75e5 fix: electron v7 dialog showOpenDialog promisify 2020-01-30 11:25:34 +08:00
Dr_rOot 1f6c2a6ff0 Merge pull request #524 from agalwood/hotfix/upgrade_deps_202001232019
fix: upgrade deps 202001232019
2020-01-30 00:05:09 +08:00
Dr_rOot a8e3c7843c fix: ci node sass 2020-01-29 23:52:04 +08:00
Dr_rOot 8b1ba2425c chore: update ci 2020-01-29 23:37:19 +08:00
Dr_rOot 47acf4fad1 fix: remove select torrent checkbox ellipsis 2020-01-28 13:55:53 +08:00
Dr_rOot 9beb48be92 fix: wrong eslint rule place 2020-01-28 13:55:17 +08:00
Dr_rOot bbe52a2a18 chore: update chrome ua 2020-01-28 13:54:27 +08:00
Dr_rOot 0b73028412 refactor: app info engine title style 2020-01-26 23:21:33 +08:00
Dr_rOot 2311a7ed86 fix: catch vue router NavigationDuplicated error 2020-01-25 02:41:46 +08:00
Dr_rOot 95ed300d1b refactor: nativeTheme.shouldUseDarkColors
systemPreferences.isDarkMode()
**Deprecated:** Should use the new `nativeTheme.shouldUseDarkColors` API.
2020-01-25 02:37:28 +08:00
Dr_rOot dcd2d50c83 refactor: dialog.showMessageBox promisify 2020-01-24 22:17:06 +08:00
Dr_rOot 57ed6c7941 chore: upgrade deps 2020-01-23 21:40:12 +08:00
Dr_rOot 870c4089fb refactor: replace babili with terser 2020-01-23 21:39:00 +08:00
Dr_rOot 1082f9330e refactor: upgrade sass loader 2020-01-23 21:37:15 +08:00
Dr_rOot a7f33869a0 chore: daysUntilLock increase to 60 2020-01-05 17:12:01 +08:00
han 89336dda37 feat: make Motrix layout more responsive (#505) 2020-01-05 17:07:09 +08:00
Dr_rOot 4240dee426 Merge pull request #472 from kant/patch-6
fix: Typos fixed and some translation redone
2019-12-12 16:20:33 +08:00
Dr_rOot 83c1c1340e Merge pull request #471 from kant/patch-5
fix: Typos fixed and some translations redone
2019-12-12 16:20:24 +08:00
Dr_rOot 408e33adb1 Merge pull request #470 from kant/patch-4
fix: Typos and bad translations redone
2019-12-12 16:20:15 +08:00
Dr_rOot d2dde274d3 Merge pull request #469 from kant/patch-2
fix: Typo fixed on line 02
2019-12-12 16:20:03 +08:00
Darío Hereñú 7b27f82f1e Typos fixed and some translation redone 2019-11-11 01:49:12 -03:00
Darío Hereñú 2d32a2848c Typos fixed and some translations redone 2019-11-11 01:39:32 -03:00
Darío Hereñú c128689b2e Typos and translation redone 2019-11-11 01:32:57 -03:00
Darío Hereñú 7702aa6ca1 Typos and bad translations redone 2019-11-11 01:29:28 -03:00
Darío Hereñú 2fb32fa347 Typo fixed on line 02 2019-11-11 01:24:48 -03:00
Dr_rOot 2744db2d75 docs: update readme i18n add ca 2019-11-05 23:15:31 +08:00
Dr_rOot adb060b076 Merge pull request #467 from marcizhu/master
feat: add Catalan translation
2019-11-05 23:07:21 +08:00
marcizhu 561d7608d8 feat: add Catalan translation 2019-11-05 11:53:01 +01:00
Dr_rOot 06d9a95827 Merge pull request #424 from agalwood/hotfix/webpack_config_4node12_201909161132
fix: process is not defined at node 12.x #267
2019-09-16 12:08:32 +08:00
Dr_rOot 9c386c4bdc fix: process is not defined at node 12.x #267
https://github.com/SimulatedGREG/electron-vue/issues/871#issuecomment-490370237
2019-09-16 11:34:12 +08:00
Dr_rOot a1eb48926a Merge pull request #420 from agalwood/feature/custom_tracker_source_201909091524
feat: user config custom tracker source
2019-09-09 16:03:58 +08:00
Dr_rOot c1ed827244 feat: add custom tracker source to user config 2019-09-09 15:49:28 +08:00
Dr_rOot 663e1a2db1 refactor: empty string constant 2019-09-09 15:47:56 +08:00
Dr_rOot c0a2b50b9f Merge pull request #419 from agalwood/hotfix/fix_energy_manager_201909091450
fix: stopPowerSaveBlocker when psbId = 0

closed #418
2019-09-09 15:22:04 +08:00
Dr_rOot a843ae4553 fix: stopPowerSaveBlocker when psbId = 0 2019-09-09 14:49:35 +08:00
Rodolfo Robles d195b23512 feat: Spanish Translation (#385) 2019-08-08 11:16:39 +08:00
Zaoqi f6c84b7e57 docs: add extra/README.md 2019-08-06 10:41:46 +08:00
Dr_rOot 98df9c3f2a fix: magnet and thunder protocol handle 2019-07-22 20:04:36 +08:00
Dr_rOot 7e703eb552 chore: update license copyright 2019-07-21 12:38:34 +08:00
Dr_rOot 87bcac6122 fix: update copyright #365
Closed #365
2019-07-21 12:38:27 +08:00
Dr_rOot 6935a12289 chore: readme i18n add ru 2019-07-13 22:49:40 +08:00
Dr_rOot 39688b667e Merge pull request #358 from bladeaweb/feature/ru
feat: Added Russian localisation.
2019-07-13 22:43:53 +08:00
Alexander Sharkov f174887f9f fix: Removed not requirement changes. 2019-07-13 17:08:37 +03:00
Alexander Sharkov caba086651 fix: Fixed some required changes of language short name. 2019-07-13 16:06:41 +03:00
Dr_rOot b627b38985 Merge pull request #357 from bladeaweb/feature/uk
fix: Fixed spelling issue.
2019-07-13 20:31:12 +08:00
Alexander Sharkov 1c35d72aa5 fix: Fixed spelling issue. 2019-07-13 15:06:17 +03:00
Alexander Sharkov 8ecbfdd66d feat: Added Russian localisation. 2019-07-13 15:03:39 +03:00
Dr_rOot 3be568f6ab Merge pull request #354 from agalwood/hotfix/preferences_changed_201907042031
fix: preferences changed data outdated
2019-07-11 11:35:01 +08:00
Dr_rOot fa29c11c73 Merge pull request #353 from agalwood/feature/shift_delete_201907032126
feat: shift delete task with files
2019-07-10 21:42:00 +08:00
Dr_rOot 6b153d68b4 docs: add tips of first launch in linux 2019-07-08 15:55:18 +08:00
Dr_rOot 852266dc16 refactor: preferences function 2019-07-04 21:09:39 +08:00
Dr_rOot 4170cd3419 refactor: lab preferences 2019-07-04 21:04:34 +08:00
Dr_rOot a15870871f fix: advanced preferences changed 2019-07-04 20:57:24 +08:00
Dr_rOot 571499caad fix: basic preferences changed 2019-07-04 20:37:56 +08:00
Dr_rOot 766c2c26b8 feat: shift trash task auto checked remove files 2019-07-03 21:34:27 +08:00
Dr_rOot 1f27f88aa7 feat: shift delete task auto checked remove files 2019-07-03 21:34:11 +08:00
Dr_rOot e06888e998 chore: add pull request template 2019-07-02 20:21:11 +08:00
Dr_rOot 91a2d0a270 Merge pull request #341 from agalwood/feature/download_outs_201907011638
feat: add task out support rule #326

Closed #326
2019-07-01 20:33:06 +08:00
Dr_rOot 8e3fe4c980 refactor: buildRule operator default PLUS 2019-07-01 20:16:26 +08:00
Dr_rOot f3724107f0 refactor: rule operators 2019-07-01 20:14:02 +08:00
Dr_rOot 580c32a2b9 Merge pull request #340 from agalwood/feature/save_preferences_201906271147
fix: check changed preferences is need restart
2019-07-01 18:56:10 +08:00
Dr_rOot 575712ba9f feat: add task support out rule #326
Out rule sample:
abc_(001+).jpg
xyz_(100-2).html
2019-07-01 18:35:10 +08:00
Dr_rOot 84006f348c feat: add buildOuts util 2019-07-01 18:22:04 +08:00
Dr_rOot a9759441d3 chore: update readme 2019-06-30 10:44:11 +08:00
Dr_rOot 728f8e9019 fix: readme i18n typo #338
closed #338
2019-06-30 10:43:27 +08:00
Dr_rOot e814210896 chore: update getLanguage comments 2019-06-29 00:24:54 +08:00
Dr_rOot a0c6877524 fix: remove useless fallback 2019-06-29 00:24:44 +08:00
Dr_rOot 29b0dd627d Merge pull request #334 from bladeaweb/feature/uk
feat: added Ukrainian localisation.
2019-06-29 00:10:16 +08:00
Alexander Sharkov dc48cad7e8 Added: Ukrainian localisation. 2019-06-28 12:47:26 +03:00
Dr_rOot 35df1c799b fix: check changed preferences is need restart 2019-06-27 15:03:08 +08:00
Dr_rOot 912e661c02 chore: update developer tools tips 2019-06-27 11:32:58 +08:00
Dr_rOot 1a2de2ad88 Merge pull request #323 from agalwood/feature/prepare_v4_201906201052
chore: prepare for release v1.4.x
2019-06-24 00:08:19 +08:00
Dr_rOot e44587035d fix: bump version to 1.4.1 2019-06-23 22:58:59 +08:00
Dr_rOot 43f1adcd84 fix: electron 5.0 performance is low revert to 424 2019-06-22 20:46:29 +08:00
Dr_rOot 8a900459b5 refactor: auto copy changed rpc secret 2019-06-22 20:39:38 +08:00
Dr_rOot d2f8a4599d feat: auto copy rpc url when dice changed secret 2019-06-21 15:46:11 +08:00
Dr_rOot 9159fb36ab chore: bump version to v1.4.0 2019-06-21 14:58:07 +08:00
Dr_rOot 5be05395f5 chore: upgrade dependencies 2019-06-21 14:57:45 +08:00
Dr_rOot fba76df945 fix: change app update url 2019-06-21 14:43:32 +08:00
Dr_rOot 5bb4f259cd fix: set bt-detach-seed-only=true 2019-06-21 14:42:57 +08:00
Dr_rOot 4b093a1a4f fix: increase the number of egine process restarts 2019-06-21 14:41:28 +08:00
Dr_rOot 134d81b205 fix: task stop seeding 2019-06-21 14:40:15 +08:00
Dr_rOot d5fc962bca fix: change task option 2019-06-21 14:40:04 +08:00
Dr_rOot 0d1b76d523 fix: checkTaskIsSeeder util 2019-06-20 15:28:28 +08:00
Dr_rOot 6499ce91b8 refactor: update element ui theme chalk 2019-06-20 11:49:30 +08:00
Dr_rOot 2d7907f218 chore: improve npm scripts postinstall 2019-06-20 11:19:54 +08:00
Dr_rOot 97c1cb0418 fix: change rpc doc link 2019-06-20 11:17:16 +08:00
Dr_rOot be585ef102 refactor: move bt-tracker config manager to file 2019-06-20 10:57:48 +08:00
Dr_rOot 03002221e7 Merge branch 'feature/task_list_201905312258'
# Conflicts:
#	src/renderer/components/Native/EngineClient.vue
2019-06-20 10:38:58 +08:00
Dr_rOot 4b8de781a4 refactor: improve download error message #293 2019-06-19 19:56:07 +08:00
Dr_rOot 8224423d8c refactor: update panel content padding 2019-06-18 21:07:14 +08:00
Dr_rOot 1e05e1e4f3 fix: element ui message link color 2019-06-17 20:27:51 +08:00
Dr_rOot bfd1e1b6fa refactor: removeTaskRecord error complete removed 2019-06-17 19:48:57 +08:00
Dr_rOot 79495cbde5 refactor: auto save session when save preferences 2019-06-16 23:44:49 +08:00
Dr_rOot a93d183988 fix: disabled certificate check 2019-06-16 21:30:24 +08:00
Dr_rOot cf082b20d8 fix: there is no localhost rule in /etc/hosts 2019-06-15 23:09:29 +08:00
Dr_rOot 8110409402 feat: empty addTaskOptions when task added 2019-06-15 20:23:11 +08:00
Dr_rOot 37b446b6f0 feat: add parseHeader util for restart task dialog 2019-06-14 23:22:36 +08:00
Dr_rOot 97801fff32 refactor: task item actions restart & stop seeding 2019-06-14 22:38:07 +08:00
Dr_rOot 4ca4f5e606 refactor: add task to support addTaskOptions 2019-06-14 22:20:34 +08:00
Dr_rOot e9caf1b0b4 refactor: transform add options keys to kebab case 2019-06-13 20:47:33 +08:00
Dr_rOot d67dca00b5 feat: add getTaskOption action 2019-06-12 20:36:03 +08:00
Dr_rOot 038536259e feat: add task restart icon 2019-06-12 20:34:22 +08:00
Dr_rOot ec21cc57bc Merge pull request #314 from theweavrs/patch-1
Add code of conduct for the project
2019-06-12 17:03:28 +08:00
thecodrr 5a42e4014b chore: add code of conduct for the project 2019-06-12 00:15:04 -07:00
Dr_rOot 02d4032283 fix: form-actions background color 2019-06-12 09:28:40 +08:00
Dr_rOot d676dbe213 Merge pull request #309 from theweavrs/master
feat: add background under form-actions in preferences
2019-06-12 09:08:31 +08:00
Dr_rOot 02d83534d1 refactor: check is exist before delete task file 2019-06-11 22:41:07 +08:00
Dr_rOot 8b531c76b8 fix: eslint no-empty-pattern error 2019-06-10 19:35:45 +08:00
Dr_rOot 22f92df299 fix: remove useless lab form.protocols key 2019-06-10 19:02:21 +08:00
Dr_rOot eaf91e15e8 Merge pull request #310 from agalwood/feature/protocol_setting_201906091107
feat: add option to set default protocols client #305
2019-06-10 18:34:05 +08:00
Dr_rOot 4535cb706a fix: setup-protocols-client command logic 2019-06-10 17:47:51 +08:00
Dr_rOot a093f3beca chore: i18n tw protocols 2019-06-10 17:47:12 +08:00
Dr_rOot 287c9038b1 Merge pull request #308 from theweavrs/feature/protocol_setting_201906091107
feat: add option to set default protocols
2019-06-10 17:12:25 +08:00
thecodrr 72aac9c0c6 feat: add background under form-actions 2019-06-10 01:48:20 -07:00
thecodrr cdac88371c refactor: remove change handlers 2019-06-10 00:52:30 -07:00
thecodrr 678bed53dc feat: add localization for protocol settings 2019-06-10 00:49:33 -07:00
thecodrr 1f805c3440 refactor: remove unused localized string 2019-06-10 00:22:31 -07:00
thecodrr c8dcb1023f feat: handle setup-protocols-client command 2019-06-10 00:17:55 -07:00
thecodrr a0e7eb84ca feat: send setup-protocols-client command 2019-06-10 00:03:10 -07:00
thecodrr fdf0bb8320 refactor: move protocol settings to advanced menu 2019-06-09 22:53:21 -07:00
thecodrr e2338757de refactor: merge magnet & thunder protocol handling 2019-06-09 22:07:09 -07:00
Dr_rOot c0cbfb5cb2 refactor: preferences lab protocol client settings 2019-06-10 11:35:48 +08:00
Dr_rOot fddaa72ac6 refactor: protocol manager init setup 2019-06-09 23:09:59 +08:00
Dr_rOot 1e531f166b feat: handle thunder protocol 2019-06-09 23:09:27 +08:00
Dr_rOot 97f54adc49 feat: add protocols to user config 2019-06-09 23:08:30 +08:00
Dr_rOot e6548d5548 Merge pull request #306 from agalwood/feature/rpc_secret_201906071137
feat: preferences add rpc-secret setting #138
2019-06-09 22:54:58 +08:00
Dr_rOot 137fdf2b26 fix: npm add randomatic deps 2019-06-09 22:35:41 +08:00
Dr_rOot 10ef4f7318 feat: i18n preferences rpc-secret 2019-06-09 22:33:52 +08:00
Dr_rOot bdd5e56c2a feat: preferences add rpc-secret setting 2019-06-08 22:53:13 +08:00
Dr_rOot a851ec5830 feat: add icon dice 2019-06-08 22:52:20 +08:00
Dr_rOot 2ae3642c62 feat: add check task is seeder util 2019-06-07 20:07:20 +08:00
Dr_rOot 7b41a9e1c6 docs: update scoop install guide 2019-06-06 12:38:29 +08:00
Dr_rOot 012e5ece00 Merge pull request #301 from agalwood/feature/preferences_layout_201905301105
refactor: improve preferences layout
2019-06-05 14:59:09 +08:00
Dr_rOot db8d3d1aec feat: i18n check for update messages 2019-06-05 12:27:18 +08:00
Dr_rOot 8e35dde082 feat: add check for update at preference #298
closed #298
2019-06-05 12:26:45 +08:00
Dr_rOot 5c2acf12ee feat: tray menu support disable item 2019-06-05 11:58:23 +08:00
Dr_rOot e710ccdb34 feat: add check for update to tray menu 2019-06-05 11:57:37 +08:00
Dr_rOot 5ecc08d66d refactor: clean up useless code 2019-06-04 22:05:51 +08:00
Dr_rOot e7b1a898fa feat: add task history icon 2019-06-03 19:57:04 +08:00
Dr_rOot 93acf1ba63 fix: el-progress status value for element ui 2.9.x 2019-06-02 02:22:13 +08:00
Dr_rOot 1164df87e3 fix: i18n add missing ja translates 2019-06-01 11:47:24 +08:00
Dr_rOot 71232603a5 refactor: rename updateStates to updateMenuStates 2019-06-01 11:44:55 +08:00
Dr_rOot 286013b2f0 refacotr: clean code 2019-05-31 19:42:53 +08:00
Dr_rOot a5f0236661 Merge pull request #296 from agalwood/feature/transfer_speed_setting_201905282346
fix: refactor transfer settings
2019-05-30 20:44:28 +08:00
Dr_rOot 87857eba94 refactor: move auto update setting to advanced 2019-05-30 20:43:45 +08:00
Dr_rOot 3059d1a0b7 refactor: preferences move mock ua to security 2019-05-30 15:47:45 +08:00
Dr_rOot 5029f98153 refactor: preferences form item style 2019-05-30 14:25:56 +08:00
Dr_rOot ce80af7ead fix: increase mo-speedometer z-index 2019-05-30 14:25:23 +08:00
Dr_rOot 6df52988b0 chore: i18n preferences transfer settings 2019-05-29 23:57:42 +08:00
Dr_rOot 6359c729ad fix: horizontal scrollbar height 2019-05-29 23:53:58 +08:00
Dr_rOot 04db94daa6 refactor: i18n calc form label width with locale 2019-05-29 23:50:33 +08:00
Dr_rOot d41d809f00 Merge pull request #295 from gee1k/master
fix: remove the button in the aside panel to drag and drop
2019-05-29 15:25:37 +08:00
Svend efdfae37b5 fix:remove the button in the aside panel to drag and drop 2019-05-29 14:01:30 +08:00
Dr_rOot 1a097c02e3 refactor: transfer speed setting to select options 2019-05-28 23:51:34 +08:00
Dr_rOot 0217b5573a fix: theme merge code error 2019-05-28 23:27:57 +08:00
Dr_rOot 86611604d5 Merge branch 'feature/theme_switch_lang_201905232132'
# Conflicts:
#	src/renderer/components/Preference/Advanced.vue
#	src/renderer/components/Preference/Basic.vue
2019-05-28 23:24:08 +08:00
Dr_rOot 0bd8ab3d11 Merge pull request #294 from agalwood/feature/change_global_options_201905241932
feat: change preferences without relaunch app #24 #172 #197
2019-05-28 23:14:05 +08:00
Dr_rOot e9eadb2eba feat: i18n save preferences message 2019-05-28 22:52:50 +08:00
Dr_rOot 72afd845ba fix: default enable check auto update on macOS 2019-05-28 22:35:19 +08:00
Gary Li 91670fac37 fix: updated en-US translation (#290)
* Updated translation: en-US

* Update: en-US translation
2019-05-27 22:38:58 +08:00
Dr_rOot bc14e5b287 Merge pull request #292 from jjandxa/master
feat: add transfer speed setting
2019-05-27 22:33:11 +08:00
jjandxa 2d01431e7d feat: add transfer speed setting 2019-05-26 22:13:38 +08:00
Dr_rOot 81531ef9fc feat: change preference show message 2019-05-26 19:40:13 +08:00
Dr_rOot 04126363ca refactor: change preference without relaunch app 2019-05-25 17:17:00 +08:00
Dr_rOot bcb07656b9 refactor: rename isSyncTracker to trackerSyncing 2019-05-24 19:49:34 +08:00
Dr_rOot b9cd991fd5 refactor: delayed engine client call 2019-05-24 19:45:56 +08:00
Dr_rOot 1b2b22f039 feat: api add changeGlobalOption 2019-05-24 19:45:01 +08:00
Dr_rOot 170a481d48 feat: add diffConfig util 2019-05-24 19:43:53 +08:00
Dr_rOot 48bf7c9e2e refactor: move theme switcher & lang to basic 2019-05-23 21:46:58 +08:00
Dr_rOot 03cfb013e5 docs: fix cn readme typo 2019-05-22 10:31:43 +08:00
Dr_rOot b4e23d8805 chore: add feature request cn issue template 2019-05-22 10:31:25 +08:00
Dr_rOot 43965c5740 chore: update bug report issue template 2019-05-21 10:56:50 +08:00
Dr_rOot 5c8d2e4ca4 fix: unified scrollbar style 2019-05-20 15:01:44 +08:00
Dr_rOot b51c144ace fix: i18n task code format 2019-05-20 14:58:55 +08:00
Dr_rOot feb839b7fa Merge pull request #273 from agalwood/feature/selective_torrent_201905142048
feat: torrent selective download #253 #229 #211
2019-05-19 16:09:09 +08:00
Dr_rOot fa36397afa fix: i18n add task style 2019-05-19 15:48:53 +08:00
Dr_rOot 583fe0ffe2 feat: i18n select torrent 2019-05-19 15:48:03 +08:00
Dr_rOot 8b3a5fbaa8 fix: select torrent reset 2019-05-19 15:45:39 +08:00
Dr_rOot 85493c263b fix: select torrent layout 2019-05-19 15:45:20 +08:00
Dr_rOot 78e106abe4 fix: add selective torrent list utils 2019-05-19 11:44:49 +08:00
Dr_rOot bbf90e9344 fix: torrent file list dark theme style 2019-05-19 11:44:21 +08:00
Dr_rOot dc30c25a83 refactor: select torrent to support selective 2019-05-19 11:42:47 +08:00
Dr_rOot e1cce4f50c refactor: add task to support selective torrent 2019-05-18 21:11:03 +08:00
Dr_rOot 61654ff0ff refactor: remove add task iLoveEggFeatures 2019-05-17 22:39:27 +08:00
Dr_rOot 0142aedfa5 feat: element dialog & table dark theme style 2019-05-17 23:11:24 +08:00
Dr_rOot 323f85ca40 feat: add video audio image files filter utils 2019-05-17 23:08:47 +08:00
Dr_rOot f35e696c6a feat: add file type icon 2019-05-16 20:05:13 +08:00
Dr_rOot d49cbcdc00 feat: add seed-time to system config 2019-05-16 19:54:35 +08:00
Dr_rOot c85ac4e895 feat: set bt-remove-unselected-file to true 2019-05-15 22:06:05 +08:00
Dr_rOot f831cc51ed fix: add task number input text overflow 2019-05-14 20:51:57 +08:00
Dr_rOot d47eb9ba0f refactor: subnav li style 2019-05-14 20:51:04 +08:00
Dr_rOot 119a374db6 fix: clean subnav code 2019-05-13 19:34:47 +08:00
Dr_rOot d26808e43a Merge pull request #262 from agalwood/feature/open_source_license_201905102203
feat: add open source license link to about panel
2019-05-12 11:36:34 +08:00
Dr_rOot 8cb3e54be2 fix: i18n add missing fa about license translate 2019-05-11 10:38:40 +08:00
Dr_rOot c55902cda7 fix: about pannel add license link 2019-05-10 22:33:16 +08:00
Dr_rOot 426b54201b Merge pull request #258 from agalwood/feature/keep_window_size_201905072013
feat: keep window size & position #232 #224 #48
2019-05-09 16:58:40 +08:00
Dr_rOot 6c032cde2d feat: i18n preference keep window state 2019-05-09 12:23:43 +08:00
Dr_rOot eb42ac6cfd feat: preference basic add keep window state chk 2019-05-08 11:40:49 +08:00
Dr_rOot 90f0a7c5f6 feat: restore window state at init 2019-05-08 00:04:53 +08:00
Dr_rOot 9b61dad2c3 feat: store window state 2019-05-08 00:03:25 +08:00
Dr_rOot 671fb82e6a feat: window manager emit resized, moved, closed 2019-05-07 23:56:38 +08:00
Dr_rOot b8f444ca4d fix: detect thunder resource uris add default val 2019-05-06 23:05:56 +08:00
Dr_rOot 7509442e4e refactor: thunder link tip improve 2019-05-05 12:01:11 +08:00
Dr_rOot ee2e3de782 Merge pull request #246 from agalwood/feature/auto_launch_201905031132
feat: auto open at login #164 #210 #237
2019-05-04 20:18:08 +08:00
Dr_rOot c6dd1e333e docs: add fixUserConfig comment 2019-05-04 20:02:16 +08:00
Dr_rOot fba761a29c feat: auto fix user config open-at-login value
Auto fix user config `open-at-login` value when user delete Motrix in OS startup manage
2019-05-04 11:50:51 +08:00
Dr_rOot 4fb94ae8bb fix: second instance could not restore window #233 2019-05-03 22:21:08 +08:00
Dr_rOot 79721822c2 feat: hide window when app launch at login 2019-05-03 15:40:00 +08:00
Dr_rOot 556f58f6b3 chore: i18n open at login 2019-05-03 15:39:18 +08:00
Dr_rOot e690f15335 feat: preference open at login 2019-05-03 15:20:34 +08:00
Dr_rOot 1876587973 feat: auto launch manager 2019-05-03 15:18:57 +08:00
Dr_rOot b89c651132 refactor: auto check update 2019-05-02 15:37:46 +08:00
zhtw ad9d3ed15a fix: some zh-TW typos (#242)
* Update preferences.js

* Update subnav.js

* Update task.js

* Update task.js
2019-05-01 17:54:17 +08:00
Dr_rOot 6aa362332a feat: add dir class watch 2019-05-01 17:09:49 +08:00
Dr_rOot 18d107c062 feat: detect text direction 2019-05-01 17:03:52 +08:00
Dr_rOot ebeba4663c docs: update readme 2019-04-30 21:01:05 +08:00
FloatingShuYin 9bff4257a8 docs: Add tips on how to install package management tools on Windows (#241)
* Add tips on how to install package management tools on Windows

* Remove extra spaces

* Layout revision
2019-04-30 20:16:41 +08:00
Dr_rOot e07ef7dd11 fix: bump version to 1.3.8 2019-04-29 09:49:33 +08:00
Dr_rOot ebb0926d1d fix: preference basic & lab save config fail #128
v1.3.7 btTracker.trim()
2019-04-29 09:46:52 +08:00
Dr_rOot 5333438825 fix: screenshots file name add @2x suffix 2019-04-28 17:23:28 +08:00
Dr_rOot 3664341822 docs: add app screenshots 2019-04-28 17:21:32 +08:00
Dr_rOot d3cbff6dd1 fix: preference link color in dark mode 2019-04-28 17:08:51 +08:00
Dr_rOot 5668b0773d fix: sync icon stroke color 2019-04-28 12:41:25 +08:00
Dr_rOot b757112c30 fix: update readme supported languages 2019-04-28 11:49:32 +08:00
Dr_rOot dc3a01fb3c fix: bump version to 1.3.7 2019-04-27 22:02:23 +08:00
KOZ39 591de11072 fix: Improve Korean translation (#238) 2019-04-27 21:54:46 +08:00
Dr_rOot 853c361e6d fix: bump version to 1.3.6 2019-04-27 19:37:35 +08:00
Dr_rOot b0ebc737e2 fix: i18n rename and add some keys 2019-04-27 19:36:02 +08:00
Dr_rOot bc9db25dfd fix: position of the proxy input is incorrect 2019-04-27 19:34:52 +08:00
KOZ39 08c9902759 feat: Add Korean translation (#236)
* Add Korean translation

* Fix typo
2019-04-27 18:31:10 +08:00
Nima Rasooli 8d2f52710d feat: Translated to Persian/Farsi (#235)
* Create about.js

* Rename src/shared/locales/fa-IR/about.js to src/shared/locales/fa/about.js

* Translated

* Translated

* Translated

* Translated

* Create index.js

* Translated

* Translated

* Translated

* translated

* Translated
2019-04-27 18:30:46 +08:00
Dr_rOot dd48fd79db fix: bump version to 1.3.5 2019-04-27 18:03:34 +08:00
Dr_rOot 9e7ad10309 Merge branch 'feature/bt_experience_opt_201904262310' 2019-04-27 18:02:19 +08:00
Dr_rOot 6e17102210 fix: mo protocol new-bt-task 2019-04-27 17:54:27 +08:00
Dr_rOot 5ed3b68a57 fix: handle launch argv 2019-04-27 17:31:56 +08:00
Dr_rOot a705427ce2 fix: open url in win & linux 2019-04-27 15:55:34 +08:00
Dr_rOot c37f7c73ce doc: change Manual link to github wiki 2019-04-27 12:14:05 +08:00
Dr_rOot efcf01d59b feat: handle magnet protocol 2019-04-27 12:13:02 +08:00
Dr_rOot 324b61567d fix: typo tip => tips 2019-04-26 23:57:55 +08:00
Dr_rOot d1e24fced0 fix: i18n preference bt tracker 2019-04-26 23:57:11 +08:00
Dr_rOot cb50d6709b feat: sync bt tracker from github
An updated list of public BitTorrent trackers
https://github.com/ngosang/trackerslist
2019-04-26 23:27:23 +08:00
Dr_rOot 900ac4c8d1 feat: preference advanced add bt tracker input 2019-04-26 23:19:10 +08:00
Dr_rOot 6696b0a538 refactor: move bt-tracker to config manager 2019-04-26 23:15:01 +08:00
Dr_rOot 110c83bcb8 fix: dht config optimization 2019-04-26 23:13:58 +08:00
Dr_rOot 136b4969bd chore: update readme
Add dark mode
2019-04-25 15:45:58 +08:00
weearc a901fdd2b6 docs: readme added linux installation guide (#228)
* add aur helper command in readme

* add aur helper command in readme
2019-04-25 15:07:56 +08:00
Dr_rOot 215bdbc416 fix: prepare for electron 5.0.x
Set webPreferences nodeIntegration to true
2019-04-25 10:53:25 +08:00
Dr_rOot 4e8d226460 fix: optimized for small screen users #48 #224 2019-04-25 10:16:16 +08:00
Dr_rOot 23f3357d27 fix: bump version to 1.3.3 2019-04-24 21:56:38 +08:00
Dr_rOot 7adafab7fe fix: i18n ja 2019-04-24 21:55:39 +08:00
HBKRKZK e3afb14e4a feat: Add Japanese language translation (#225)
* Create darwin.json

* Add files via upload

* Create about.js

* Add files via upload

* Update all.js

* Update app.js

* Update index.js

* fix

* fix preferences.js
2019-04-24 21:48:41 +08:00
Dr_rOot 228cd1fa7d fix: bump version to 1.3.2 2019-04-24 16:29:41 +08:00
Dr_rOot 47a7464bf9 doc: update translation guide 2019-04-24 16:28:04 +08:00
Dr_rOot 8efd86af3d feat: remove similar unuse config key 2019-04-24 11:35:31 +08:00
Dr_rOot ee78ae262e fix: bump version v1.3.1 2019-04-24 10:22:52 +08:00
Dr_rOot 7562f6a7d1 fix: downgrade electron-store 2019-04-24 10:22:32 +08:00
Dr_rOot defacd50e8 fix: build script —experimental-worker 2019-04-24 00:06:01 +08:00
Dr_rOot f5ed0d89cc fix: bump version to 1.3.x 2019-04-23 23:47:14 +08:00
Dr_rOot a3bb1c7ff1 Merge branch 'feature/dark_mode_201904201437' 2019-04-23 23:43:04 +08:00
Dr_rOot d0085b295d refactor: bt complete show seeding tips #179 #134 2019-04-23 23:40:01 +08:00
Dr_rOot 6cb278fd9e chore: manual update tracker 2019-04-23 18:14:50 +08:00
Dr_rOot aeeb9813ed refactor: lint fix 2019-04-23 17:56:45 +08:00
Dr_rOot 359da895e7 fix: migration electron-log from v2 to v3 2019-04-23 17:23:52 +08:00
Dr_rOot 8a3f510c38 refactor: check pid is running before kill it 2019-04-23 17:22:57 +08:00
Dr_rOot 1345994402 feat: add config schema valid 2019-04-23 17:21:56 +08:00
Dr_rOot c770108a6c refactor: electron store sort config key 2019-04-23 17:21:27 +08:00
Dr_rOot 178f2103f1 fix: destroy tray when app exit 2019-04-23 10:41:11 +08:00
Dr_rOot d5c71b50e8 fix: change application module init order 2019-04-23 10:40:30 +08:00
Dr_rOot ce09e76ffb refactor: theme style improve 2019-04-23 10:38:44 +08:00
Dr_rOot 4688b521fa fix: trim after split task link text rows #221
closed #221
2019-04-22 20:52:33 +08:00
Dr_rOot 33960dc264 fix: decrease theme switcher theme text font size 2019-04-22 20:49:15 +08:00
Dr_rOot d29d0d3321 fix: add task dialog background color 2019-04-22 15:42:09 +08:00
Dr_rOot f4c3e7be69 feat: preference advanced add theme switcher 2019-04-22 15:17:48 +08:00
Dr_rOot 338b51975c feat: preference theme switcher i18n 2019-04-22 15:17:23 +08:00
Dr_rOot e1a287350d feat: add preference theme thumb 2019-04-22 15:16:53 +08:00
Dr_rOot afeee1fc86 fix: change theme config 2019-04-21 23:42:52 +08:00
Dr_rOot a39820f8ab refactor: app style 2019-04-21 22:29:27 +08:00
Dr_rOot aea604278c fix: copyright link color 2019-04-21 22:28:40 +08:00
Dr_rOot 0b92e6b96e fix: app info style 2019-04-21 22:28:19 +08:00
Dr_rOot 2ba0040bdd feat: title bar close btn 2019-04-21 22:28:01 +08:00
Dr_rOot 04bf2b6b9d fix: logo svg fill 2019-04-21 22:26:36 +08:00
Dr_rOot cc367f4c5c fix: change show in folder icon size 2019-04-21 22:24:40 +08:00
Dr_rOot 73809a6501 refactor: app theme & add dark theme 2019-04-21 22:23:39 +08:00
Dr_rOot 5067ad7306 feat: app ui respond to system theme changed 2019-04-21 21:36:37 +08:00
Dr_rOot d5b3ad5933 fix: tray icon adapts to the dark mode #206 #207
close #206
close #207
2019-04-21 21:30:07 +08:00
Dr_rOot 7a903e112c feat: theme manager 2019-04-21 21:26:45 +08:00
Dr_rOot 829eb83a4c fix: get task full path error when file path empty 2019-04-17 15:45:20 +08:00
Dr_rOot 886acc2486 fix: thunder link decoding error #201 #209
close #209
2019-04-17 15:12:13 +08:00
Dr_rOot 87440701ab fix: block some ui text selections when drag app 2019-04-10 21:11:10 +08:00
Dr_rOot e880430e3a fix: html tpl 2019-04-07 13:31:00 +08:00
Dr_rOot 2febff883b fix: add missing auto check update TR translation 2019-04-01 21:11:07 +08:00
Bo Yuan 7d8bb443b8 feat: preferences add auto check updates setting
* add auto check update, time out: 1 min.

* fix: add auto check update, check interval: 30 min.

* no message

* no message

* fix: modify update check interval to 7 days, add display of [last check update time] to preference.

* no message

* fix: modified the group of auto-check-update, fix the display of last-check-update-time

* no message

* fix: hide last-check-update-time when never check.
2019-04-01 20:55:30 +08:00
Dr_rOot 1489d58a63 chore: rebuild snap for snapcraft 2019-03-31 11:45:54 +08:00
Dr_rOot 00fdafe824 fix: upgrade electron-builder 2019-03-30 11:46:55 +08:00
Dr_rOot 81c91e8cb1 fix: update readme badges 2019-03-28 22:58:28 +08:00
Dr_rOot 0fd34254de chore: add latest release badge 2019-03-26 20:58:22 +08:00
Dr_rOot d9298f0d46 fix: read me typo 2019-03-25 00:15:34 +08:00
Dr_rOot 83e12a699e docs: update readme add new feature 2019-03-24 21:54:28 +08:00
459 changed files with 29014 additions and 27296 deletions
+7 -17
View File
@@ -2,19 +2,11 @@
"comments": false,
"env": {
"main": {
"presets": [
["env", {
"targets": { "node": 7 }
}],
"stage-0"
]
"presets": ["@babel/preset-env"]
},
"renderer": {
"presets": [
["env", {
"modules": false
}],
"stage-0"
"@babel/preset-env"
],
"plugins": [
[
@@ -27,12 +19,7 @@
]
},
"web": {
"presets": [
["env", {
"modules": false
}],
"stage-0"
],
"presets": ["@babel/preset-env"],
"plugins": [
[
"component",
@@ -44,5 +31,8 @@
]
}
},
"plugins": ["transform-runtime"]
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-runtime"
]
}
+26 -19
View File
@@ -5,10 +5,8 @@ process.env.NODE_ENV = 'production'
const { say } = require('cfonts')
const chalk = require('chalk')
const del = require('del')
const { spawn } = require('child_process')
const webpack = require('webpack')
const Multispinner = require('multispinner')
const Webpack = require('webpack')
const Multispinner = require('@motrix/multispinner')
const mainConfig = require('./webpack.main.config')
const rendererConfig = require('./webpack.renderer.config')
@@ -19,12 +17,16 @@ const errorLog = chalk.bgRed.white(' ERROR ') + ' '
const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
const isCI = process.env.CI || false
if (process.env.BUILD_TARGET === 'clean') clean()
else if (process.env.BUILD_TARGET === 'web') web()
else build()
if (process.env.BUILD_TARGET === 'clean') {
clean()
} else if (process.env.BUILD_TARGET === 'web') {
web()
} else {
build()
}
function clean () {
del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
del.sync(['release/*', '!.gitkeep'])
console.log(`\n${doneLog}\n`)
process.exit()
}
@@ -73,9 +75,10 @@ function build () {
function pack (config) {
return new Promise((resolve, reject) => {
config.mode = 'production'
webpack(config, (err, stats) => {
if (err) reject(err.stack || err)
else if (stats.hasErrors()) {
Webpack(config, (err, stats) => {
if (err) {
reject(err.stack || err)
} else if (stats.hasErrors()) {
let err = ''
stats.toString({
@@ -99,9 +102,9 @@ function pack (config) {
}
function web () {
del.sync(['dist/web/*', '!.gitkeep'])
deleteSync(['dist/web/*', '!.gitkeep'])
webConfig.mode = 'production'
webpack(webConfig, (err, stats) => {
Webpack(webConfig, (err, stats) => {
if (err || stats.hasErrors()) console.log(err)
console.log(stats.toString({
@@ -117,16 +120,20 @@ function greeting () {
const cols = process.stdout.columns
let text = ''
if (cols > 85) text = 'lets-build'
else if (cols > 60) text = 'lets-|build'
else text = false
if (cols > 85) {
text = 'lets-build'
} else if (cols > 60) {
text = 'lets-|build'
} else {
text = false
}
if (text && !isCI) {
say(text, {
colors: ['yellow'],
colors: ['magentaBright'],
font: 'simple3d',
space: false
})
} else console.log(chalk.yellow.bold('\n lets-build'))
} else console.log(chalk.magentaBright.bold('\n lets-build'))
console.log()
}
}
+25 -42
View File
@@ -5,16 +5,14 @@ const electron = require('electron')
const path = require('path')
const { say } = require('cfonts')
const { spawn } = require('child_process')
const webpack = require('webpack')
const Webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server')
const webpackHotMiddleware = require('webpack-hot-middleware')
const mainConfig = require('./webpack.main.config')
const rendererConfig = require('./webpack.renderer.config')
let electronProcess = null
let manualRestart = false
let hotMiddleware
function logStats (proc, data) {
let log = ''
@@ -39,41 +37,22 @@ function logStats (proc, data) {
}
function startRenderer () {
return new Promise((resolve, reject) => {
rendererConfig.entry.index = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.index)
return new Promise(async (resolve, reject) => {
rendererConfig.entry.index = rendererConfig.entry.index
rendererConfig.mode = 'development'
const compiler = webpack(rendererConfig)
hotMiddleware = webpackHotMiddleware(compiler, {
log: false,
heartbeat: 2500
})
compiler.hooks.compilation.tap('compilation', compilation => {
compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
const compiler = Webpack(rendererConfig)
const devServerOptions = {
...rendererConfig.devServer,
port: 9080,
static: {
directory: path.resolve(__dirname, "../"),
},
};
compiler.hooks.done.tap('done', stats => {
logStats('Renderer', stats)
})
const server = new WebpackDevServer(
compiler,
{
contentBase: path.join(__dirname, '../'),
quiet: true,
before (app, ctx) {
app.use(hotMiddleware)
ctx.middleware.waitUntilValid(() => {
resolve()
})
}
}
)
server.listen(9080)
const server = new WebpackDevServer(devServerOptions, compiler)
await server.start()
resolve()
})
}
@@ -81,11 +60,11 @@ function startMain () {
return new Promise((resolve, reject) => {
mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
mainConfig.mode = 'development'
const compiler = webpack(mainConfig)
const compiler = Webpack(mainConfig)
compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
logStats('Main', chalk.white.bold('compiling...'))
hotMiddleware.publish({ action: 'compiling' })
// hotMiddleware.publish({ action: 'compiling' })
done()
})
@@ -149,17 +128,21 @@ function greeting () {
const cols = process.stdout.columns
let text = ''
if (cols > 104) text = 'electron-vue'
else if (cols > 76) text = 'electron-|vue'
else text = false
if (cols > 104) {
text = 'motrix-dev'
} else if (cols > 76) {
text = 'motrix-|dev'
} else {
text = false
}
if (text) {
say(text, {
colors: ['yellow'],
colors: ['magentaBright'],
font: 'simple3d',
space: false
})
} else console.log(chalk.yellow.bold('\n electron-vue'))
} else console.log(chalk.magentaBright.bold('\n motrix-dev'))
console.log(chalk.blue(' getting ready...') + '\n')
}
+22 -22
View File
@@ -4,10 +4,11 @@ process.env.BABEL_ENV = 'main'
const devMode = process.env.NODE_ENV !== 'production'
const path = require('path')
const { dependencies, build } = require('../package.json')
const webpack = require('webpack')
const BabiliWebpackPlugin = require('babili-webpack-plugin')
const { dependencies } = require('../package.json')
const { appId } = require('../electron-builder.json')
const Webpack = require('webpack')
const TerserPlugin = require('terser-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
let mainConfig = {
entry: {
@@ -18,17 +19,6 @@ let mainConfig = {
],
module: {
rules: [
{
test: /\.(js)$/,
enforce: 'pre',
exclude: /node_modules/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter')
}
}
},
{
test: /\.js$/,
use: 'babel-loader',
@@ -50,7 +40,10 @@ let mainConfig = {
path: path.join(__dirname, '../dist/electron')
},
plugins: [
new webpack.NoEmitOnErrorsPlugin()
new Webpack.NoEmitOnErrorsPlugin(),
new ESLintPlugin({
formatter: require('eslint-friendly-formatter')
})
],
resolve: {
alias: {
@@ -59,7 +52,15 @@ let mainConfig = {
},
extensions: ['.js', '.json', '.node']
},
target: 'electron-main'
target: 'electron-main',
optimization: {
minimize: !devMode,
minimizer: [
new TerserPlugin({
extractComments: false,
})
],
},
}
/**
@@ -67,9 +68,9 @@ let mainConfig = {
*/
if (devMode) {
mainConfig.plugins.push(
new webpack.DefinePlugin({
new Webpack.DefinePlugin({
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`,
'appId': `"${build.appId}"`
'appId': `"${appId}"`
})
)
}
@@ -79,10 +80,9 @@ if (devMode) {
*/
if (!devMode) {
mainConfig.plugins.push(
new BabiliWebpackPlugin(),
new webpack.DefinePlugin({
new Webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"',
'appId': `"${build.appId}"`
'appId': `"${appId}"`
})
)
}
+51 -60
View File
@@ -5,14 +5,14 @@ process.env.BABEL_ENV = 'renderer'
const devMode = process.env.NODE_ENV !== 'production'
const path = require('path')
const { dependencies } = require('../package.json')
const webpack = require('webpack')
const BabiliWebpackPlugin = require('babili-webpack-plugin')
const Webpack = require('webpack')
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const ESLintPlugin = require('eslint-webpack-plugin');
/**
* List of node_modules to include in webpack bundle
@@ -24,7 +24,6 @@ const { VueLoaderPlugin } = require('vue-loader')
let whiteListedModules = ['vue']
let rendererConfig = {
devtool: '#cheap-module-eval-source-map',
entry: {
index: path.join(__dirname, '../src/renderer/pages/index/main.js')
},
@@ -34,14 +33,10 @@ let rendererConfig = {
module: {
rules: [
{
test: /\.(js|vue)$/,
enforce: 'pre',
exclude: /node_modules/,
test: /\.worker\.js$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter')
}
loader: 'worker-loader',
options: { filename: '[name].js' }
}
},
{
@@ -52,8 +47,11 @@ let rendererConfig = {
{
loader: 'sass-loader',
options: {
data: '@import "@/components/Theme/Variables.scss";',
includePaths:[__dirname, 'src']
implementation: require('sass'),
additionalData: '@import "@/components/Theme/Variables.scss";',
sassOptions: {
includePaths:[__dirname, 'src']
}
},
}
]
@@ -66,9 +64,12 @@ let rendererConfig = {
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
indentedSyntax: true,
data: '@import "@/components/Theme/Variables.scss";',
includePaths:[__dirname, 'src']
additionalData: '@import "@/components/Theme/Variables.scss";',
sassOptions: {
includePaths:[__dirname, 'src']
}
},
}
]
@@ -88,10 +89,6 @@ let rendererConfig = {
'css-loader'
]
},
{
test: /\.html$/,
use: 'vue-html-loader'
},
{
test: /\.js$/,
use: 'babel-loader',
@@ -117,31 +114,15 @@ let rendererConfig = {
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'imgs/[name]--[folder].[ext]'
}
}
type: 'asset/inline'
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name]--[folder].[ext]'
}
type: 'asset/resource'
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'fonts/[name]--[folder].[ext]'
}
}
type: 'asset/inline'
}
]
},
@@ -155,12 +136,6 @@ let rendererConfig = {
filename: '[name].css',
chunkFilename: '[id].css'
}),
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true,
discardComments: { removeAll: true }
}
}),
new HtmlWebpackPlugin({
title: 'Motrix',
filename: 'index.html',
@@ -171,17 +146,25 @@ let rendererConfig = {
// removeAttributeQuotes: true,
// removeComments: true
// },
isBrowser: false,
isDev: process.env.NODE_ENV !== 'production',
nodeModules: devMode
? path.resolve(__dirname, '../node_modules')
: false
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
new Webpack.HotModuleReplacementPlugin(),
new Webpack.NoEmitOnErrorsPlugin(),
new ESLintPlugin({
extensions: ['js', 'vue'],
formatter: require('eslint-friendly-formatter')
})
],
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../dist/electron')
path: path.join(__dirname, '../dist/electron'),
globalObject: 'this',
publicPath: ''
},
resolve: {
alias: {
@@ -191,15 +174,26 @@ let rendererConfig = {
},
extensions: ['.js', '.vue', '.json', '.css', '.node']
},
target: 'electron-renderer'
target: 'electron-renderer',
optimization: {
minimize: !devMode,
minimizer: [
new TerserPlugin({
extractComments: false,
}),
new CssMinimizerPlugin(),
],
},
}
/**
* Adjust rendererConfig for development settings
*/
if (devMode) {
rendererConfig.devtool = 'eval-cheap-module-source-map'
rendererConfig.plugins.push(
new webpack.DefinePlugin({
new Webpack.DefinePlugin({
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
})
)
@@ -209,21 +203,18 @@ if (devMode) {
* Adjust rendererConfig for production settings
*/
if (!devMode) {
rendererConfig.devtool = ''
rendererConfig.plugins.push(
new BabiliWebpackPlugin(),
new CopyWebpackPlugin([
{
new CopyWebpackPlugin({
patterns: [{
from: path.join(__dirname, '../static'),
to: path.join(__dirname, '../dist/electron/static'),
ignore: ['.*']
}
]),
new webpack.DefinePlugin({
globOptions: { ignore: [ '.*' ] }
}]
}),
new Webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new webpack.LoaderOptionsPlugin({
new Webpack.LoaderOptionsPlugin({
minimize: false
})
)
+67 -50
View File
@@ -5,14 +5,14 @@ process.env.BABEL_ENV = 'web'
const devMode = process.env.NODE_ENV !== 'production'
const path = require('path')
const { dependencies } = require('../package.json')
const webpack = require('webpack')
const BabiliWebpackPlugin = require('babili-webpack-plugin')
const Webpack = require('webpack')
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const ESLintPlugin = require('eslint-webpack-plugin');
/**
* List of node_modules to include in webpack bundle
@@ -24,7 +24,6 @@ const { VueLoaderPlugin } = require('vue-loader')
let whiteListedModules = ['vue']
let webConfig = {
devtool: '#cheap-module-eval-source-map',
entry: {
index: path.join(__dirname, '../src/renderer/pages/index/main.js')
},
@@ -34,14 +33,10 @@ let webConfig = {
module: {
rules: [
{
test: /\.(js|vue)$/,
enforce: 'pre',
exclude: /node_modules/,
test: /\.worker\.js$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter')
}
loader: 'worker-loader',
options: { filename: '[name].js' }
}
},
{
@@ -49,7 +44,16 @@ let webConfig = {
use: [
devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
additionalData: '@import "@/components/Theme/Variables.scss";',
sassOptions: {
includePaths:[__dirname, 'src']
}
},
}
]
},
{
@@ -57,7 +61,17 @@ let webConfig = {
use: [
devMode ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader?indentedSyntax'
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
indentedSyntax: true,
additionalData: '@import "@/components/Theme/Variables.scss";',
sassOptions: {
includePaths:[__dirname, 'src']
}
},
}
]
},
{
@@ -97,23 +111,11 @@ let webConfig = {
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'imgs/[name].[ext]'
}
}
type: 'asset/inline'
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'fonts/[name].[ext]'
}
}
type: 'asset/inline'
}
]
},
@@ -123,12 +125,6 @@ let webConfig = {
filename: '[name].css',
chunkFilename: '[id].css'
}),
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true,
discardComments: { removeAll: true }
}
}),
new HtmlWebpackPlugin({
title: 'Motrix',
filename: 'index.html',
@@ -139,19 +135,27 @@ let webConfig = {
// removeAttributeQuotes: true,
// removeComments: true
// },
isBrowser: true,
isDev: process.env.NODE_ENV !== 'production',
nodeModules: devMode
? path.resolve(__dirname, '../node_modules')
: false
}),
new webpack.DefinePlugin({
new Webpack.DefinePlugin({
'process.env.IS_WEB': 'true'
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
new Webpack.HotModuleReplacementPlugin(),
new Webpack.NoEmitOnErrorsPlugin(),
new ESLintPlugin({
extensions: ['js', 'vue'],
formatter: require('eslint-friendly-formatter')
})
],
output: {
filename: '[name].js',
path: path.join(__dirname, '../dist/web')
path: path.join(__dirname, '../dist/web'),
globalObject: 'this',
publicPath: ''
},
resolve: {
alias: {
@@ -161,28 +165,41 @@ let webConfig = {
},
extensions: ['.js', '.vue', '.json', '.css']
},
target: 'web'
target: 'web',
optimization: {
minimize: !devMode,
minimizer: [
new TerserPlugin({
extractComments: false,
}),
new CssMinimizerPlugin(),
],
},
}
/**
* Adjust webConfig for development settings
*/
if (devMode) {
webConfig.devtool = 'eval-cheap-module-source-map'
}
/**
* Adjust webConfig for production settings
*/
if (!devMode) {
webConfig.devtool = ''
webConfig.plugins.push(
new BabiliWebpackPlugin(),
new CopyWebpackPlugin([
{
new CopyWebpackPlugin({
patterns: [{
from: path.join(__dirname, '../static'),
to: path.join(__dirname, '../dist/web/static'),
ignore: ['.*']
}
]),
new webpack.DefinePlugin({
to: path.join(__dirname, '../dist/electron/static'),
globOptions: { ignore: [ '.*' ] }
}]
}),
new Webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new webpack.LoaderOptionsPlugin({
new Webpack.LoaderOptionsPlugin({
minimize: true
})
)
+7
View File
@@ -0,0 +1,7 @@
src/renderer/components/Icons/*.js
src/shared/locales/*
!src/shared/locales/all.js
!src/shared/locales/app.js
!src/shared/locales/index.js
!src/shared/locales/LocalManager.js
+24 -17
View File
@@ -1,27 +1,34 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
node: true
},
extends: 'standard',
extends: [
'plugin:vue/essential',
'@vue/standard'
],
parserOptions: {
parser: 'babel-eslint'
},
globals: {
appId: true,
__static: true
},
plugins: [
'html'
],
'rules': {
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}
rules: {
'no-console': 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'indent': ['error', 2],
'vue/script-indent': ['error', 2, {
'baseIndent': 1
}],
},
overrides: [
{
'files': ['*.vue'],
'rules': {
'indent': 'off'
}
}
]
};
+76
View File
@@ -0,0 +1,76 @@
name: 🐛 [NEW] Bug Report
description: File a bug report here
title: "[BUG]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report 🤗
Make sure there aren't any open/closed issues for this topic 😃
- type: textarea
id: bug-description
attributes:
label: Description of the bug
description: Give us a brief description of what happened and what should have happened
validations:
required: true
- type: textarea
id: app-version
attributes:
label: Motrix Version
description: Please provide detailed version information and installation method, such as macOS Apple silicon dmg, Windows Universal installation file, etc.
validations:
required: true
- type: textarea
attributes:
label: Environment
description: |
Run this command in your project's root folder and paste the result:
```sh
npx envinfo --system --binaries --browsers
```
add `| pbcopy` if you're in macOS for easy copy paste.
Alternatively, you can manually gather the version information from your environment.
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
More info: A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is **required**, otherwise the issue might be closed without further notice. [**Why & How?**](https://antfu.me/posts/why-reproductions-are-required)
validations:
required: true
- type: textarea
id: additional-information
attributes:
label: Additional Information
description: |
Provide any additional information such as logs, screenshots, likes, scenarios in which the bug occurs so that it facilitates resolving the issue.
- type: checkboxes
id: checkboxes
attributes:
label: Validations
description: Before submitting the issue, please make sure you do the following
options:
- label: Follow our [Code of Conduct](https://github.com/agalwood/Motrix/blob/master/CODE_OF_CONDUCT.md)
required: true
- label: Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
required: true
- label: Check that this is a concrete bug. For Q&A, please open a [GitHub Discussion](https://github.com/agalwood/Motrix/discussions) instead.
required: true
- label: The provided reproduction is a [minimal reproducible](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
required: true
@@ -0,0 +1,76 @@
name: 🐛 [新] Bug 报告
description: 在这里提交 Bug 报告
title: "[BUG]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
感谢您抽出时间来填写这份 Bug 报告 🤗
请确保此问题没有已存在的开放/关闭问题 😃
- type: textarea
id: bug-description
attributes:
label: Bug 描述
description: 给我们一个简短的描述,说明发生了什么以及应该发生什么。
validations:
required: true
- type: textarea
id: app-version
attributes:
label: Motrix 版本
description: 请提供详细的版本信息以及安装的方式,如 macOS Apple silicon dmg、Windows Universal 安装文件等
validations:
required: true
- type: textarea
attributes:
label: 环境
description: |
在项目的根目录下运行以下命令,并将结果粘贴到下方:
```sh
npx envinfo --system --binaries --browsers
```
在 macOS 中,如果您需要轻松复制粘贴,可以添加 `| pbcopy`。
或者,您也可以手动收集您的环境版本信息。
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: 复现步骤
description: 复现该问题的步骤。
placeholder: |
1. 前往 '...'
2. 点击 '...'
3. 滚动到 '...'
4. 查看错误
更多信息:[最小复现例子](https://stackoverflow.com/help/minimal-reproducible-example) 是必需的,否则该问题可能会被关闭而没有进一步的通知。[**为什么 & 如何?**](https://antfu.me/posts/why-reproductions-are-required)
validations:
required: true
- type: textarea
id: additional-information
attributes:
label: 额外信息
description: |
提供任何额外的信息,例如日志、截图、喜欢、发生该 Bug 的场景,以便有助于解决问题。
- type: checkboxes
id: checkboxes
attributes:
label: 验证
description: 在提交问题之前,请确保您完成了以下操作
options:
- label: 遵循我们的[行为准则](https//github.com/agalwood/Motrix/blob/master/CODE_OF_CONDUCT.md)
required: true
- label: 确认是否已经有一个报告了相同的 Bug,以避免创建重复的问题。
required: true
- label: 确认此问题是一个具体的 Bug。若要进行问答,请开启 [GitHub 讨论](https://github.com/agalwood/Motrix/discussions)。
required: true
- label: 提供的复现是该 Bug 的 [最小复现例子](https://stackoverflow.com/help/minimal-reproducible-example)。
required: true
-38
View File
@@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Before feedback**
Before you feedback, please search for the issues to see if there are similar problems that can solve your problem.
**Please delete the above and the contents of this line, then fill in the feedback form in the following format, Thanks.**
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- OS & Version: [e.g. macOS, Windows, Linux]
- Version: [e.g. macOS 10.14.2, Windows 10, Ubuntu 18.04]
- Motrix Version: [e.g. v1.1.3, v1.1.0]
- Installation package type: [e.g. dmg, AppImage]
**Additional context**
Add any other context about the problem here.
-40
View File
@@ -1,40 +0,0 @@
---
name: 错误反馈
about: 创建一个错误报告帮助改进「请按照模板提交,提供详细的信息,方便我们复现之后处理」
title: ''
labels: ''
assignees: ''
---
**反馈之前**
反馈之前请搜索一下已有 issues 和 帮助文档,看是否有类似问题可以解决你的问题
https://github.com/agalwood/Motrix/issues
http://motrix.app/support
**请删除上面和本行的内容,然后按以下格式填写反馈信息,谢谢**
**错误描述**
清楚简洁地描述错误,方便我们复现之后处理。
**如何重现**
重现步骤,如:
1. 点击新建任务按钮
2. 黏贴链接(如链接不涉及到隐私和版权问题,请顺便提供)
3. 点击提交
4. 发现报错
**预期的行为**
清楚简洁地描述您期望发生的事情。
**截图**
请添加屏幕截图以帮助解释您的问题:
打开应用菜单中的「帮助」——「开发者工具」—— 切换到 console,然后**完整**截图。
**运行环境**
- 操作系统类型: [如 macOS, Windows, Linux]
- 具体版本: [如 macOS 10.14.2, Windows 10, Ubuntu 18.04]
- Motrix 版本: [如 v1.1.3, v1.1.0]
- 安装包类型:[如 dmg, AppImage]
**更多信息**
添加有关此问题的任何其他上下文信息。
@@ -0,0 +1,28 @@
---
name: 新功能请求
about: 你期望 Motrix 未来添加的新功能
title: ''
labels: enhancement ✨
assignees: ''
---
<!--
反馈之前请搜索一下已有 issues 和 帮助文档,看是否已经有人提交了类似的新功能请求
https://github.com/agalwood/Motrix/issues
http://motrix.app/support
按以下格式填写反馈信息,谢谢
-->
**请描述一下你的新功能请求是否与已知问题有关?**
简明扼要地描述了问题所在。
**描述你想要的解决方案**
简明扼要地描述你想要的解决方案。
**描述你考虑过的替代方案**
简明扼要地描述你考虑过的任何替代解决方案或功能。
**更多信息**
补充有关该新功能的其他信息。
+16
View File
@@ -0,0 +1,16 @@
<!-- You can erase any parts of this template not applicable to your Pull Request. -->
## Description
<!-- Write a brief description of the changes introduced by this PR -->
## Related Issues
<!--
Link to the issue that is fixed by this PR (if there is one)
e.g. Fixes #1234, Addresses #1234, Related to #1234, etc.
-->
### Checklist:
* [ ] Have you checked to ensure there aren't other open [Pull Requests](../../../pulls) for the same update/change?
* [ ] Have you linted your code locally prior to submission?
* [ ] Have you successfully ran app with your changes locally?
+1 -1
View File
@@ -1,7 +1,7 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 30
daysUntilLock: 60
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
+71
View File
@@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '23 8 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+62
View File
@@ -0,0 +1,62 @@
name: Build/release
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
release:
runs-on: ${{ matrix.os }}
# Platforms to build on/for
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v3
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install Snapcraft
uses: samuelmeuli/action-snapcraft@v2
# Only install Snapcraft on Ubuntu
if: startsWith(matrix.os, 'ubuntu')
env:
# Snapcraft
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.snapcraft_token }}
- name: Test Snapcraft
if: startsWith(matrix.os, 'ubuntu')
run: snapcraft --help
- name: Build/release Electron app
uses: motrixapp/action-electron-builder@v2
with:
build_script_name: 'build:github'
# GitHub token, automatically provided to the action
# (No need to define this secret in the repo settings)
github_token: ${{ secrets.github_token }}
# macOS code signing certificate
mac_certs: ${{ secrets.mac_certs }}
mac_certs_password: ${{ secrets.mac_certs_password }}
# If the commit is tagged with a version (e.g. "v1.0.0"),
# release the app after building
release: ${{ vars.skip_publish != 'true' }}
env:
# Snapcraft
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.snapcraft_token }}
# macOS notarization API key
API_KEY_ID: ${{ secrets.api_key_id }}
API_KEY_ISSUER_ID: ${{ secrets.api_key_issuer_id }}
TEAM_ID: ${{ secrets.team_id }}
APPLE_ID: ${{ secrets.apple_id }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.apple_app_specific_password }}
+21 -7
View File
@@ -1,11 +1,25 @@
!.gitkeep
.DS_Store
dist/electron/*
dist/web/*
.env
.idea/
.vs/
.vscode/
*.log
node_modules/
thumbs.db
# npm package
.npmrc
npm-debug.log.*
# Eslint Cache
.eslintcache*
# electron builder
*.provisionprofile
build/*.plist
node_modules/
npm-debug.log
npm-debug.log.*
thumbs.db
!.gitkeep
dist/electron/*
dist/web/*
# release
release/*
+17 -5
View File
@@ -1,32 +1,44 @@
osx_image: xcode10.1
sudo: required
dist: trusty
language: c
matrix:
jobs:
include:
- os: osx
osx_image: xcode11.3
- os: linux
env: CC=clang CXX=clang++ npm_config_clang=1
compiler: clang
cache:
directories:
- node_modules
- "$HOME/.electron"
- "$HOME/.cache"
- $HOME/.cache/electron
- $HOME/.cache/electron-builder
addons:
apt:
packages:
- libgnome-keyring-dev
- icnsutils
- rpm
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils; fi
install:
- nvm install 10
- nvm install 12.14.1
- source ~/.bashrc
- npm install -g xvfb-maybe
- npm install
script:
- npm run release
before_cache:
- rm -rf $HOME/.cache/electron-builder/wine
branches:
only:
- master
+76
View File
@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at agalwood.net@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
+19 -15
View File
@@ -1,30 +1,34 @@
# Motrix 贡献指南
## 🌍 翻译指南
首先你要确定一个语言的英文简写作为 **locale**,如 en-US,这个 locale 值请严格参考 [Electron 的 Locales 文档](https://electronjs.org/docs/api/locales)
开始贡献之前,确保你已经理解了 [GitHub 的协作流程](https://guides.github.com/introduction/flow/)。
## 🌍 翻译指南
首先你要确定一个语言的英文简写作为 **locale**,如 en-US,这个 locale 值请严格参考 [Electron 的 Locales 文档](https://www.electronjs.org/docs/api/app#appgetlocale) 和 [Chromium 源代码](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/l10n/l10n_util.cc)。
Motrix 的国际化分两部分:
Motrix 的国际化分三部分:
- Element UI
- 应用菜单
- 主界面
- 菜单和主界面
### Element UI
Element UI 的国际化由 [Element 社区](http://element.eleme.io/#/en-US/component/i18n)提供,找到 **locale** 对应的语言包文件「两者 locale 命名可能不一致」,在 `src/shared/locales/all.js` 中引入,如
```
```javascript
import eleLocaleEn from 'element-ui/lib/locale/lang/en'
import eleLocaleZhCN from 'element-ui/lib/locale/lang/zh-CN'
```
### 应用菜单
应用菜单的国际化文件按照语言进行目录划分,每个目录里有三大操作系统对应的 JSON 文件:
- darwin.json
- linux.json
- win32.json
### 菜单和主界面
Motrix 使用 i18next 作为翻译支持库,所以你可能需要简单了解一下它的[使用方法](https://www.i18next.com/overview/getting-started)。
配置文件按照语言 (**locale**) 划分目录:`src/shared/locales`,如:`src/shared/locales/en-US``src/shared/locales/zh-CN`
目录里面有按业务模块划分的语言文件
菜单模块经过重构之后,国际化已经打散到了以下文件里了,不再需要再复制 `src/main/menus` 里的配置。
### 主界面
主界面和 Element UI 都是用 i18next 作为翻译支持库,所以你可能需要简单了解一下它的[使用方法](https://www.i18next.com/overview/getting-started)。
主界面的配置同样按照语言划分目录:`src/shared/locales`,如:`src/shared/locales/en-US``src/shared/locales/zh-CN`
目录里面有按业务模块划分的语言文件:
- about.js
- app.js
- edit.js
+19 -15
View File
@@ -1,30 +1,34 @@
# Motrix Contributing Guide
## 🌍 Translation Guide
First you need to determine the English abbreviation of a language as **locale**, such as en-US, this locale value should strictly refer to the [electron's documentation](https://electronjs.org/docs/api/locales).
Before you start contributing, make sure you already understand [GitHub flow](https://guides.github.com/introduction/flow/).
## 🌍 Translation Guide
First you need to determine the English abbreviation of a language as **locale**, such as en-US, this locale value should strictly refer to the [Electron's Documentation](https://www.electronjs.org/docs/api/app#appgetlocale) and [Chromium Source Code](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/l10n/l10n_util.cc).
The internationalization of Motrix is divided into two parts:
The internationalization of Motrix is divided into three parts:
- Element UI
- Application Menu
- Main Interface
- Menu & Main Interface
### Element UI
The internationalization of Element UI is provided by the [Element community](http://element.eleme.io/#/en-US/component/i18n), then find the language pack file corresponding to **locale** (both locale naming may be inconsistent), which is import in `src/shared/locales/all.js`, such as
```
```javascript
import eleLocaleEn from 'element-ui/lib/locale/lang/en'
import eleLocaleZhCN from 'element-ui/lib/locale/lang/zh-CN'
```
### Application Menu
The internationalization files of the application menu are divided into directories according to the **locale**. Each directory has three JSON files corresponding to the OS:
- darwin.json
- linux.json
- win32.json
### Menu & Main Interface
Motrix uses the [i18next](https://www.i18next.com/overview/getting-started) library for internationalization, so you need a quick look at how to use it.
The configuration files are divided by **locale**: `src/shared/locales`, such as `src/shared/locales/en-US` and `src/shared/locales/zh-CN`.
There are language files in the directory according to the business module.
After the menu module is refactored, the internationalization of the menu has been dispersed into the following files, and there is no need to copy the configuration in `src/main/menus`.
### Main Interface
Both the main interface and the Element UI use [i18next](https://www.i18next.com/overview/getting-started) as the translation support library, so you may need to take a brief look at how to use it.
The configuration of the main interface is also divided into directories according to the **locale**: `src/shared/locales`, such as: `src/shared/locales/en-US` and `src/shared/locales/zh-CN`.
There are language files in the directory divided by business modules:
- about.js
- app.js
- edit.js
+3 -1
View File
@@ -1,4 +1,6 @@
Copyright 2018 Dr_rOot
The MIT License
Copyright 2018-present Dr_rOot
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:
+152 -24
View File
@@ -1,99 +1,227 @@
# Motrix
<a href="https://motrix.app">
<img src="https://cdn.nlark.com/yuque/0/2018/png/129147/1543735425232-a5d2c99f-d788-43e4-9781-558ff6d21027.png" width="256" alt="App Icon" />
<img src="./static/512x512.png" width="256" alt="App Icon" />
</a>
## 一款全能的下载工具
[![GitHub release](https://img.shields.io/github/v/release/agalwood/Motrix.svg)](https://github.com/agalwood/Motrix/releases) ![Build/release](https://github.com/agalwood/Motrix/workflows/Build/release/badge.svg) ![Total Downloads](https://img.shields.io/github/downloads/agalwood/Motrix/total.svg) ![Support Platforms](https://camo.githubusercontent.com/a50c47295f350646d08f2e1ccd797ceca3840e52/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667)
[English](./README.md) | 简体中文
## 一款全能的下载工具
[![Build Status](https://travis-ci.org/agalwood/Motrix.svg?branch=master)](https://travis-ci.org/agalwood/Motrix) [![Build status](https://ci.appveyor.com/api/projects/status/l11d5h05xwwcvoux/branch/master?svg=true)](https://ci.appveyor.com/project/agalwood/motrix/branch/master) ![Total Downloads](https://img.shields.io/github/downloads/agalwood/Motrix/total.svg) ![Support Platforms](https://camo.githubusercontent.com/a50c47295f350646d08f2e1ccd797ceca3840e52/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667)
我是个兴趣使然的桌面应用开发者🤓,利用搬砖之余开发了 Motrix。
Motirx 是一款全能的下载工具,支持下载 HTTP、FTP、BT、磁力链、百度网盘等资源。它的界面简洁易用,希望大家喜欢 👻。
Motrix 是一款全能的下载工具,支持下载 HTTP、FTP、BT、磁力链等资源。它的界面简洁易用,希望大家喜欢 👻。
✈️ 去 [官网](https://motrix.app/zh-CN) 逛逛 | 📖 查看 [帮助手册](http://motrix.app/support/issues)
## 💽 安装稳定版
[GitHub](https://github.com/agalwood/Motrix/releases) 和 [官网](https://motrix.app/zh-CN) 提供了已经编译好的稳定版安装包,当然你也可以自己克隆代码编译打包。
更新:macOS 用户支持 `brew cask` 安装,感谢 [Mitscherlich](https://github.com/Mitscherlich) 的 [PR](https://github.com/Homebrew/homebrew-cask/pull/59494)。
### Windows
建议使用安装包(Motrix-Setup-x.y.z.exe)安装 Motrix 以确保完整的体验,例如关联 torrent 文件,捕获磁力链等。
如果你在 Windows 是用包管理工具来管理应用,如 [Chocolatey](https://chocolatey.org)、[scoop](https://github.com/lukesampson/scoop),你可以使用它们安装 Motrix。
#### Chocolatey
感谢 [@Yato](https://github.com/iYato) 持续维护着 [Motrix Chocolatey](https://community.chocolatey.org/packages/motrix) 包。要安装 Motrix,请从 `命令行``PowerShell` 中运行以下命令:
```bash
brew update && brew cask install motrix
# 安装
choco install motrix
# 升级
choco upgrade motrix
```
#### scoop
如果你更喜欢便携版,你可以使用 [scoop](https://github.com/lukesampson/scoop)(需要 Windows 7+,天朝用户可能需要设置 Git 代理)安装最新便携版本的 Motrix。
```bash
scoop bucket add extras
scoop install motrix
```
### macOS
macOS 用户可以使用 `brew cask` 安装 Motrix,感谢 [@Mitscherlich](https://github.com/Mitscherlich) 的 [PR](https://github.com/Homebrew/homebrew-cask/pull/59494)。
```bash
brew update && brew install --cask motrix
```
### Linux
你可以下载 `AppImage` (适用于所有 Linux 发行版)或 `snap` 来安装 Motrix,更多 Linux 安装包格式请查看 [GitHub/release](https://github.com/agalwood/Motrix/releases) 。
Motrix 在 Linux 中首次启动可能需要使用 `sudo` 运行,因为可能没有创建下载会话文件的权限 (`/var/cache/aria2.session`)。
如果你想自己通过编译源码来安装,请阅读 **编译打包** 部分。
#### AppImage
最新版的 Motrix AppImage 需要自己手动进执行桌面集成。请查看 [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) 的文档进行操作。
> 桌面集成
> electron-builder v21 之后,桌面集成不再是 AppImage 文件的一部分。
> 推荐使用 [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) 集成 AppImage。
Deepin 20 Beta 用户安装 Motrix 失败的问题,请按照以下方法处理:
打开`终端`,黏贴运行如下命令之后再次安装 Motrix。
```bash
sudo apt --fix-broken install
```
#### Snap
Motrix 已经上架 [Snapcraft](https://snapcraft.io/motrix) Ubuntu 用户推荐从 Snap 商店下载。
v1.5.10 提示
系统托盘可能无法正常显示指示器,导致退出应用程序不方便。
请取消勾选 偏好设置——基本设置——隐藏应用程序菜单(仅限Windows和Linux),点击保存并应用。然后点击 "文件 "菜单中的 "退出",退出应用程序。
请更新到 v1.5.12 及以上版本,可以使用键盘组合快捷键 <kbd>Ctrl</kbd> + <kbd>q</kbd> 快速退出应用。
#### AUR
对于 Arch Linux 用户,可以使用 [aur](https://aur.archlinux.org/packages/motrix/) 安装 Motrix,感谢维护者 [@weearc](https://github.com/weearc)。
运行以下命令进行安装:
```bash
yay -S motrix
```
#### Flatpak
感谢 [@proletarius101](https://github.com/proletarius101) 的 [PR](https://github.com/flathub/flathub/pull/2334)Motrix 已经上架 [Flathub](https://flathub.org/apps/details/net.agalwood.Motrix),喜欢 Flatpak 的 Linux 用户可以尝试。
```bash
# 安装
flatpak install flathub net.agalwood.Motrix
# 运行
flatpak run net.agalwood.Motrix
```
## ✨ 特性
- 🕹 简洁明了的图形操作界面
- 🦄 支持BT和磁力链任务
- 💾 支持下载百度云盘资源
- ☑️ 支持选择性下载BT部分文件
- 📡 每天自动更新 Tracker 服务器列表
- 🔌 UPnP & NAT-PMP 端口映射
- 🎛 最高支持 10 个任务同时下载
- 🚀 单任务最高支持 64 线程下载
- 🚥 设置上传/下载限速
- 🕶 模拟用户代理UA
- 🔔 下载完成后通知
- 💻 支持触控栏快捷 (Mac 专享)
- 💻 支持触控栏快捷 (Mac 专享)
- 🤖 常驻系统托盘,操作更加便捷
- 📟 系统托盘速度仪表显示实时速度 (Mac 专享)
- 🌑 深色模式
- 🗑 移除任务时可同时删除相关文件
- 🌍 国际化,[查看已可选的语言](#-国际化)
- 🎏 ...
- 🛠 更多特性开发中
## 🖥 应用界面
![motrix-screenshot-task-cn.png](https://cdn.nlark.com/yuque/0/2019/png/129147/1550151234585-e513bd4f-e127-402f-accb-1ebbba9b3c41.png)
![motrix-screenshot-task-cn.png](https://cdn.nlark.com/yuque/0/2020/png/129147/1589782239990-fecb9065-19ac-4c35-938b-0be45621ca3a.png)
## ⌨️ 本地开发
### 克隆代码
```bash
git clone git@github.com:agalwood/Motrix.git
```
### 安装依赖
```bash
cd Motrix
npm install
yarn
```
天朝大陆用户建议使用淘宝的npm源
天朝大陆用户建议使用淘宝的 npm 源
```bash
npm config set registry 'https://registry.npm.taobao.org'
yarn config set registry 'https://registry.npmmirror.com'
npm config set registry 'https://registry.npmmirror.com'
export ELECTRON_MIRROR='https://npm.taobao.org/mirrors/electron/'
export SASS_BINARY_SITE='https://npm.taobao.org/mirrors/node-sass'
```
如果喜欢 [Yarn](https://yarnpkg.com/),也可以使用 `yarn` 安装依赖
> Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
`Electron` 下载安装失败的问题,解决方式请参考 https://github.com/electron/electron/issues/8466#issuecomment-571425574
### 开发模式
```bash
npm run dev
yarn run dev
```
### 编译打包
```bash
npm run build
yarn run build
```
#### 编译 Apple Silicon 版本
```bash
yarn run build:applesilicon
```
完成之后可以在项目的 `release` 目录看到编译打包好的应用文件
## 🛠 技术栈
- [Electron](https://electronjs.org/)
- [Vue](https://vuejs.org/) + [VueX](https://vuex.vuejs.org/) + [Element](https://element.eleme.io)
- [Aria2](https://aria2.github.io/) (注:macOS 和 Linux 版本使用的是 64 位的 aria2cWindows 版使用的 32 位的)
- [Aria2](https://aria2.github.io/)
## ☑️ TODO
开发计划请移步 [Trello](https://trello.com/b/qNUzA0bv/motrix) 查看
## 🤝 参与共建 [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
## 🤝 参与共建 [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
如果你有兴趣参与共同开发,欢迎 FORK 和 PR。
## 🌍 国际化
欢迎大家将 Motrix 翻译成更多的语言版本 🧐,开工之前请先阅读一下 [翻译指南](./CONTRIBUTING-CN.md#-翻译指南)。
| Key | Name | Status |
|-------|:--------------------|:-------------|
| de | German | 下版本发布 [@Schloemicher](https://github.com/Schloemicher) |
| ar | Arabic | ✔️ [@hadialqattan](https://github.com/hadialqattan), [@AhmedElTabarani](https://github.com/AhmedElTabarani) |
| bg | Българският език | ✔️ [@null-none](https://github.com/null-none) |
| ca | Català | ✔️ [@marcizhu](https://github.com/marcizhu) |
| de | Deutsch | ✔️ [@Schloemicher](https://github.com/Schloemicher) |
| el | Ελληνικά | ✔️ [@Likecinema](https://github.com/Likecinema) |
| en-US | English | ✔️ |
| fr | Français | 下版本发布 [@gpatarin](https://github.com/gpatarin) |
| pt-BR | Portuguese (Brazil) | 下版本发布 [@andrenoberto](https://github.com/andrenoberto) |
| tr | Türkçe | 下版本发布 [@abdullah](https://github.com/abdullah) |
| es | Español | ✔️ [@Chofito](https://github.com/Chofito)|
| fa | فارسی | ✔️ [@Nima-Ra](https://github.com/Nima-Ra) |
| fr | Français | ✔️ [@gpatarin](https://github.com/gpatarin) |
| hu | Hungarian | ✔️ [@zalnaRs](https://github.com/zalnaRs) |
| id | Indonesia | ✔️ [@aarestu](https://github.com/aarestu) |
| it | Italiano | ✔️ [@blackcat-917](https://github.com/blackcat-917) |
| ja | 日本語 | ✔️ [@hbkrkzk](https://github.com/hbkrkzk) |
| ko | 한국어 | ✔️ [@KOZ39](https://github.com/KOZ39) |
| nb | Norsk Bokmål | ✔️ [@rubjo](https://github.com/rubjo) |
| nl | Nederlands | ✔️ [@nickbouwhuis](https://github.com/nickbouwhuis) |
| pl | Polski | ✔️ [@KanarekLife](https://github.com/KanarekLife) |
| pt-BR | Portuguese (Brazil) | ✔️ [@andrenoberto](https://github.com/andrenoberto) |
| ro | Română | ✔️ [@alyn3d](https://github.com/alyn3d) |
| ru | Русский | ✔️ [@bladeaweb](https://github.com/bladeaweb) |
| th | แบบไทย | ✔️ [@nxanywhere](https://github.com/nxanywhere) |
| tr | Türkçe | ✔️ [@abdullah](https://github.com/abdullah) |
| uk | Українська | ✔️ [@bladeaweb](https://github.com/bladeaweb) |
| vi | Tiếng Việt | ✔️ [@duythanhvn](https://github.com/duythanhvn) |
| zh-CN | 简体中文 | ✔️ |
| zh-TW | 繁體中文 | 下版本发布 [@Yukaii](https://github.com/Yukaii) |
| zh-TW | 繁體中文 | ✔️ [@Yukaii](https://github.com/Yukaii) [@5idereal](https://github.com/5idereal) |
## 📜 开源许可
基于 [MIT license](https://opensource.org/licenses/MIT) 许可进行开源。
+149 -21
View File
@@ -1,93 +1,221 @@
# Motrix
<a href="https://motrix.app">
<img src="https://cdn.nlark.com/yuque/0/2018/png/129147/1543735425232-a5d2c99f-d788-43e4-9781-558ff6d21027.png" width="256" alt="App Icon" />
<img src="./static/512x512.png" width="256" alt="App Icon" />
</a>
## A full-featured download manager.
[![Build Status](https://travis-ci.org/agalwood/Motrix.svg?branch=master)](https://travis-ci.org/agalwood/Motrix) [![Build status](https://ci.appveyor.com/api/projects/status/l11d5h05xwwcvoux/branch/master?svg=true)](https://ci.appveyor.com/project/agalwood/motrix/branch/master) ![Total Downloads](https://img.shields.io/github/downloads/agalwood/Motrix/total.svg) ![Support Platforms](https://camo.githubusercontent.com/a50c47295f350646d08f2e1ccd797ceca3840e52/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667)
## A full-featured download manager
[![GitHub release](https://img.shields.io/github/v/release/agalwood/Motrix.svg)](https://github.com/agalwood/Motrix/releases) ![Build/release](https://github.com/agalwood/Motrix/workflows/Build/release/badge.svg) ![Total Downloads](https://img.shields.io/github/downloads/agalwood/Motrix/total.svg) ![Support Platforms](https://camo.githubusercontent.com/a50c47295f350646d08f2e1ccd797ceca3840e52/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f5325323025374325323057696e646f77732532302537432532304c696e75782d6c69676874677265792e737667)
English | [简体中文](./README-CN.md)
Motrix is a full-featured download manager that supports downloading HTTP, FTP, BitTorrent, Magnet, Baidu Net Disk, etc.
Motrix is a full-featured download manager that supports downloading HTTP, FTP, BitTorrent, Magnet, etc.
Motrix has a clean and easy to use interface. I hope you will like it 👻.
✈️ [Official Website](https://motrix.app) | 📖 [Manual](http://motrix.app/support/issues) (zh-CN)
✈️ [Official Website](https://motrix.app) | 📖 [Manual](https://github.com/agalwood/Motrix/wiki)
## 💽 Installation
Download from [GitHub Releases](https://github.com/agalwood/Motrix/releases) and install it.
Update: macOS user support `brew cask` installation, thanks to [PR](https://github.com/Homebrew/homebrew-cask/pull/59494) of [Mitscherlich](https://github.com/Mitscherlich).
### Windows
It is recommended to install Motrix using the installation package (Motrix-Setup-x.y.z.exe) to ensure a complete experience, such as associating torrent files, capturing magnet links, etc.
If you use package management tools to manage applications on Windows, such as [Chocolatey](https://chocolatey.org), [scoop](https://github.com/lukesampson/scoop). You can use them to install Motrix.
#### Chocolatey
Thanks to [@Yato](https://github.com/iYato) for continuing to maintain the [Motrix Chocolatey](https://community.chocolatey.org/packages/motrix) package. To install motrix, run the following command from the `command line` or from `PowerShell`:
```bash
brew update && brew cask install motrix
# Install
choco install motrix
# Upgrade
choco upgrade motrix
```
#### scoop
If you prefer the portable version, you can use [scoop](https://github.com/lukesampson/scoop) (need Windows 7+) to install Motrix.
```bash
scoop bucket add extras
scoop install motrix
```
### macOS
The macOS users can install Motrix using `brew cask`, thanks to [PR](https://github.com/Homebrew/homebrew-cask/pull/59494) of [@Mitscherlich](https://github.com/Mitscherlich).
```bash
brew update && brew install --cask motrix
```
### Linux
You can download the `AppImage` (for all Linux distributions) or `snap` to install Motrix, see [GitHub/release](https://github.com/agalwood/Motrix/releases) for more Linux installation package formats.
Motrix may need to run with `sudo` for the first time in Linux because there is no permission to create the download session file (`/var/cache/aria2.session`).
If you want to build from source code, please read the **Build** section.
#### AppImage
The latest version of Motrix AppImage requires you to manually perform desktop integration. Please check the documentation of [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) .
> Desktop Integration
> Since electron-builder 21 desktop integration is not a part of produced AppImage file.
> [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) is the recommended way to integrate AppImages.
Deepin 20 Beta users failed to install Motrix, please follow the steps below:
Open the `Terminal`, paste and run the following command to install Motrix again.
```bash
sudo apt --fix-broken install
```
#### Snap
Motrix has been listed on [Snapcraft](https://snapcraft.io/motrix) , Ubuntu users recommend downloading from the Snap Store.
Tips for v1.5.10
The tray may not display the indicator normally, which makes it inconvenient to exit the application.
Please unchecked Preferences--Basic Settings--Hide App Menu (Windows & Linux Only), click Save & Apply. Then click "Exit" in the File menu to exit the application.
Please update to v1.5.12 and above, you can use the keyboard shortcut <kbd>Ctrl</kbd> + <kbd>q</kbd> to quickly exit the application.
#### AUR
For Arch Linux users, Motrix is available in [aur](https://aur.archlinux.org/packages/motrix/), thanks to the maintainer [@weearc](https://github.com/weearc).
Run the following command to install:
```bash
yay -S motrix
```
#### Flatpak
Thanks to the [PR](https://github.com/flathub/flathub/pull/2334) of [@proletarius101](https://github.com/proletarius101), Motrix has been listed [Flathub](https://flathub.org/apps/details/net.agalwood.Motrix), Linux users who like the Flatpak can try it.
```bash
# Install
flatpak install flathub net.agalwood.Motrix
# Run
flatpak run net.agalwood.Motrix
```
## ✨ Features
- 🕹 Simple and clear user interface
- 🦄 Supports BitTorrent & Magnet
- 💾 Supports downloading Baidu Net Disk
- ☑️ BitTorrent selective download
- 📡 Update tracker list every day automatically
- 🔌 UPnP & NAT-PMP Port Mapping
- 🎛 Up to 10 concurrent download tasks
- 🚀 Supports 64 threads in a single task
- 🚥 Supports speed limit
- 🕶 Mock User-Agent
- 🔔 Download completed Notification
- 💻 Ready for Touch Bar (Mac only)
- 🤖 Resident system tray for quick operation
- 📟 Tray speed meter displays real-time speed (Mac only)
- 🌑 Dark mode
- 🗑 Delete related files when removing tasks (optional)
- 🌍 I18n, [View supported languages](#-internationalization).
- 🎏 ...
- 🛠 More features in development
## 🖥 User Interface
![motrix-screenshot-task-en.png](https://cdn.nlark.com/yuque/0/2019/png/129147/1550151166169-94b4bfb0-746e-42b8-aad7-0b6890f89abb.png)
![motrix-screenshot-task-en.png](https://cdn.nlark.com/yuque/0/2020/png/129147/1589782238501-e7b39166-da58-4152-ae34-65a061cafa48.png)
## ⌨️ Development
### Clone Code
```bash
git clone git@github.com:agalwood/Motrix.git
```
### Install Dependencies
```bash
cd Motrix
npm install
yarn
```
If you like [Yarn](https://yarnpkg.com/), you can also use `yarn` to install dependencies.
> Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
`Electron` failed to install correctly, please refer to https://github.com/electron/electron/issues/8466#issuecomment-571425574
### Dev Mode
```bash
npm run dev
yarn run dev
```
### Build Release
```bash
npm run build
yarn run build
```
#### Build for Apple Silicon
```bash
yarn run build:applesilicon
```
After building, the application will be found in the project's `release` directory.
## 🛠 Technology Stack
- [Electron](https://electronjs.org/)
- [Vue](https://vuejs.org/) + [VueX](https://vuex.vuejs.org/) + [Element](https://element.eleme.io)
- [Aria2](https://aria2.github.io/) (Note: macOS and Linux versions use 64-bit aria2c, Windows version uses 32-bit)
- [Aria2](https://aria2.github.io/)
## ☑️ TODO
Development Roadmap see: [Trello](https://trello.com/b/qNUzA0bv/motrix)
## 🤝 Contribute [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
## 🤝 Contribute [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
If you are interested in participating in joint development, PR and Forks are welcome!
## 🌍 Internationalization
Translations into versions for other languages are welcome 🧐! Please read the [translation guide](./CONTRIBUTING.md#-translation-guide) before starting translations.
| Key | Name | Status |
|-------|:--------------------|:-------------|
| de | German | Next Release [@Schloemicher](https://github.com/Schloemicher) |
| ar | Arabic | ✔️ [@hadialqattan](https://github.com/hadialqattan), [@AhmedElTabarani](https://github.com/AhmedElTabarani) |
| bg | Българският език | ✔️ [@null-none](https://github.com/null-none) |
| ca | Català | ✔️ [@marcizhu](https://github.com/marcizhu) |
| de | Deutsch | ✔️ [@Schloemicher](https://github.com/Schloemicher) |
| el | Ελληνικά | ✔️ [@Likecinema](https://github.com/Likecinema) |
| en-US | English | ✔️ |
| fr | Français | Next Release [@gpatarin](https://github.com/gpatarin) |
| pt-BR | Portuguese (Brazil) | Next Release [@andrenoberto](https://github.com/andrenoberto) |
| tr | Türkçe | Next Release [@abdullah](https://github.com/abdullah) |
| es | Español | ✔️ [@Chofito](https://github.com/Chofito)|
| fa | فارسی | ✔️ [@Nima-Ra](https://github.com/Nima-Ra) |
| fr | Français | ✔️ [@gpatarin](https://github.com/gpatarin) |
| hu | Hungarian | ✔️ [@zalnaRs](https://github.com/zalnaRs) |
| id | Indonesia | ✔️ [@aarestu](https://github.com/aarestu) |
| it | Italiano | ✔️ [@blackcat-917](https://github.com/blackcat-917) |
| ja | 日本語 | ✔️ [@hbkrkzk](https://github.com/hbkrkzk) |
| ko | 한국어 | ✔️ [@KOZ39](https://github.com/KOZ39) |
| nb | Norsk Bokmål | ✔️ [@rubjo](https://github.com/rubjo) |
| nl | Nederlands | ✔️ [@nickbouwhuis](https://github.com/nickbouwhuis) |
| pl | Polski | ✔️ [@KanarekLife](https://github.com/KanarekLife) |
| pt-BR | Portuguese (Brazil) | ✔️ [@andrenoberto](https://github.com/andrenoberto) |
| ro | Română | ✔️ [@alyn3d](https://github.com/alyn3d) |
| ru | Русский | ✔️ [@bladeaweb](https://github.com/bladeaweb) |
| th | แบบไทย | ✔️ [@nxanywhere](https://github.com/nxanywhere) |
| tr | Türkçe | ✔️ [@abdullah](https://github.com/abdullah) |
| uk | Українська | ✔️ [@bladeaweb](https://github.com/bladeaweb) |
| vi | Tiếng Việt | ✔️ [@duythanhvn](https://github.com/duythanhvn) |
| zh-CN | 简体中文 | ✔️ |
| zh-TW | 繁體中文 | Next Release [@Yukaii](https://github.com/Yukaii) |
| zh-TW | 繁體中文 | ✔️ [@Yukaii](https://github.com/Yukaii) [@5idereal](https://github.com/5idereal) |
## 📜 License
[MIT](https://opensource.org/licenses/MIT) Copyright (c) 2018-present Dr_rOot
+1 -1
View File
@@ -1,2 +1,2 @@
provider: generic
url: 'https://motrix.app/release/'
url: 'https://dl.motrix.app/releases/'
+6 -9
View File
@@ -1,24 +1,17 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
platform:
- x64
cache:
- node_modules
- '%APPDATA%\npm-cache'
- '%USERPROFILE%\.electron'
- '%USERPROFILE%\AppData\Local\Yarn\cache'
init:
- git config --global core.autocrlf input
install:
- ps: Install-Product node 10 x64
- ps: Install-Product node 12.14.1 x64
- git reset --hard HEAD
- npm install
- node --version
@@ -27,3 +20,7 @@ build_script:
- npm run release
test: off
branches:
only:
- master
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 24 KiB

+94
View File
@@ -0,0 +1,94 @@
// Forked from https://github.com/samuelmeuli/mini-diary/blob/master/scripts/after-pack.js
/**
* Source: https://github.com/patrikx3/redis-ui/blob/master/src/build/after-pack.js
*
* Copyright (c) 2019 Patrik Laszlo / P3X / Corifeus and contributors.
*
* MIT License
*
* 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.
*/
// TODO: Remove script once https://github.com/electron/electron/issues/17972 is solved by
// `electron-builder`
const fs = require('fs')
const { spawn } = require('child_process')
const { chdir } = require('process')
const pkg = require('../package.json')
const binName = `${pkg.name}`.toLowerCase()
const exec = async function exec (cmd, args = []) {
const child = spawn(cmd, args, { shell: true })
redirectOutputFor(child)
await waitFor(child)
}
const redirectOutputFor = child => {
const printStdout = data => {
process.stdout.write(data.toString())
}
const printStderr = data => {
process.stderr.write(data.toString())
}
child.stdout.on('data', printStdout)
child.stderr.on('data', printStderr)
child.once('close', () => {
child.stdout.off('data', printStdout)
child.stderr.off('data', printStderr)
})
}
const waitFor = async function (child) {
return new Promise(resolve => {
child.once('close', () => resolve())
})
}
const linuxTargets = [
'AppImage',
'deb',
'rpm',
'snap'
]
module.exports = async function (context) {
console.warn('after build; disable sandbox')
const isLinux = context.targets.find(
target => linuxTargets.includes(target)
)
if (!isLinux) {
return
}
const originalDir = process.cwd()
const dirname = context.appOutDir
chdir(dirname)
await exec('mv', [binName, binName + '.bin'])
const wrapperScript = `#!/bin/bash
"\${BASH_SOURCE%/*}"/${binName}.bin "$@" --no-sandbox
`
fs.writeFileSync(binName, wrapperScript)
await exec('chmod', ['+x', binName])
chdir(originalDir)
}
+36
View File
@@ -0,0 +1,36 @@
require('dotenv').config()
const { join } = require('path')
const { notarize } = require('@electron/notarize')
const { appId } = require('../electron-builder.json')
exports.default = async function (context) {
const { electronPlatformName, appOutDir } = context
if (electronPlatformName !== 'darwin') {
return
}
const skipNotarize = process.env.SKIP_NOTARIZE
if (skipNotarize === 'true') {
console.log('Skipping notarize')
return
}
const appBundleId = appId
const appName = context.packager.appInfo.productFilename
const appPath = join(appOutDir, `${appName}.app`)
try {
await notarize({
tool: 'notarytool',
appBundleId,
appPath,
teamId: process.env.TEAM_ID,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD
})
} catch (error) {
console.error(error)
}
console.log(`Done notarizing ${appId}`)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 62 KiB

+200
View File
@@ -0,0 +1,200 @@
{
"productName": "Motrix",
"appId": "app.motrix.native",
"afterPack": "./build/afterPackHook.js",
"afterSign": "./build/afterSignHook.js",
"fileAssociations": [
{
"ext": "torrent",
"mimeType": "application/x-bittorrent",
"name": "Torrent",
"role": "Viewer"
}
],
"asar": true,
"directories": {
"output": "release"
},
"files": [
"dist/electron/**/*"
],
"protocols": [
{
"name": "Motrix Protocol",
"schemes": [
"mo",
"motrix"
]
},
{
"name": "Magnet Protocol",
"schemes": [
"magnet"
]
},
{
"name": "Thunder Protocol",
"schemes": [
"thunder"
]
}
],
"dmg": {
"window": {
"width": 540,
"height": 380
},
"contents": [
{
"x": 410,
"y": 230,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 230,
"type": "file"
}
]
},
"mac": {
"target": [
{
"target": "dmg",
"arch": [
"x64",
"arm64",
"universal"
]
},
{
"target": "zip",
"arch": [
"x64",
"arm64",
"universal"
]
}
],
"type": "development",
"darkModeSupport": true,
"hardenedRuntime": false,
"notarize": false,
"extraResources": {
"from": "./extra/darwin/${arch}/",
"to": "./",
"filter": [
"**/*"
]
},
"category": "public.app-category.utilities"
},
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64",
"ia32"
]
},
{
"target": "appx",
"arch": [
"x64",
"ia32"
]
},
{
"target": "zip",
"arch": [
"x64",
"ia32"
]
},
{
"target": "portable",
"arch": [
"x64",
"ia32"
]
}
],
"extraResources": {
"from": "./extra/win32/${arch}/",
"to": "./",
"filter": [
"**/*"
]
}
},
"nsis": {
"artifactName": "${productName}-Setup-${version}.${ext}",
"oneClick": false,
"allowToChangeInstallationDirectory": true
},
"appx": {
"artifactName": "${productName}-${version}-${arch}.${ext}",
"applicationId": "app.motrix.native",
"identityName": "59744DrrOot.Motrix",
"publisher": "CN=5BB4961D-30D8-4993-9ADF-05E1E1F5A395",
"publisherDisplayName": "Dr_rOot"
},
"portable": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"linux": {
"category": "Network",
"mimeTypes": [
"application/x-bittorrent",
"x-scheme-handler/magnet"
],
"target": [
{
"target": "AppImage",
"arch": [
"x64",
"arm64",
"armv7l"
]
},
{
"target": "deb",
"arch": [
"x64",
"arm64",
"armv7l"
]
},
{
"target": "rpm",
"arch": [
"x64"
]
},
{
"target": "snap",
"arch": [
"x64"
]
}
],
"extraResources": {
"from": "./extra/linux/${arch}/",
"to": "./",
"filter": [
"**/*"
]
}
},
"publish": [
{
"provider": "generic",
"url": "https://dl.motrix.app/releases/"
},
{
"provider": "github"
}
]
}
+3
View File
@@ -0,0 +1,3 @@
# aria2
Source code: https://github.com/agalwood/aria2
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix macOS Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=none
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
BIN
View File
Binary file not shown.
-108
View File
@@ -1,108 +0,0 @@
## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ##
## 被注释的选项填写的是默认值, 建议在需要修改时再取消注释 ##
## 添加了@和默认启用的选项都是系统需要调用的,请不要随意改动否则可能无法正常运行
## 文件保存相关 ##
# 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置
# 此项 OS X 无法使用 $HOME 及 ~/ 设置路径 建议使用 /users/用户名/downloads
#@dir=$HOME/downloads
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
#@disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
# file-allocation=none
# 断点续传
#@continue=true
## 下载连接相关 ##
# 最大同时下载任务数, 运行时可修改, 默认:5
#@max-concurrent-downloads=10
# 同一服务器连接数, 添加时可指定, 默认:1
#@max-connection-per-server=15
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
#@min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
#@split=15
# 整体下载速度限制, 运行时可修改, 默认:0
#@max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#@max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
max-overall-upload-limit=128K
# 单个任务上传速度限制, 默认:0
#@max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=false
#运行覆盖已存在文件
#@allow-overwrite=true
#自动重命名
#@auto-file-renaming=true
## 进度保存相关 ##
# 从会话文件中读取下载任务
#@input-file=/Users/Shared/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
#@save-session=/Users/Shared/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
save-session-interval=30
## RPC相关设置 ##
# 启用RPC, 默认:false
enable-rpc=true
# 允许所有来源, 默认:false
rpc-allow-origin-all=true
# 允许非外部访问, 默认:false
rpc-listen-all=true
# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同
#event-poll=select
# RPC监听端口, 端口被占用时可以修改, 默认:6800
# 使用本客户端请勿修改此项
# rpc-listen-port=6800
# 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
#rpc-secret=token
## BT/PT下载相关 ##
# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
#follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51413
# 单个种子最大连接数, 默认:55
#bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
# enable-dht=false
# 打开IPv6 DHT功能, PT需要禁用
#enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
#dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
bt-enable-lpd=true
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=true
# 每个种子限速, 对少种的PT很有用, 默认:50K
#bt-request-peer-speed-limit=50K
# 客户端伪装, PT需要
peer-id-prefix=-TR2770-
user-agent=Transmission/2.94
# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=1.0
# 强制保存会话, 即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
#force-save=false
# BT校验相关, 默认:true
#bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=true
# bt-tracker数据来自https://github.com/ngosang/trackerslist/blob/master/trackers_best.txt
bt-tracker=udp://tracker.coppersurfer.tk:6969/announce,udp://tracker.opentrackr.org:1337/announce,udp://tracker.internetwarriors.net:1337/announce,udp://9.rarbg.to:2710/announce,udp://exodus.desync.com:6969/announce,udp://tracker2.itzmx.com:6961/announce,udp://tracker1.itzmx.com:8080/announce,udp://explodie.org:6969/announce,http://tracker.tfile.me:80/announce.php,http://tracker.tfile.me:80/announce,http://tracker.tfile.co:80/announce,http://peersteers.org:80/announce,udp://tracker.tiny-vps.com:6969/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://denis.stalker.upeer.me:6969/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.port443.xyz:6969/announce,udp://tracker.cyberia.is:6969/announce,udp://thetracker.org:80/announce,udp://retracker.lanta-net.ru:2710/announce
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix macOS Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=none
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
BIN
View File
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix Linux Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=trunc
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
BIN
View File
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix Linux Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=trunc
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
BIN
View File
Binary file not shown.
-108
View File
@@ -1,108 +0,0 @@
## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ##
## 被注释的选项填写的是默认值, 建议在需要修改时再取消注释 ##
## 添加了@和默认启用的选项都是系统需要调用的,请不要随意改动否则可能无法正常运行
## 文件保存相关 ##
# 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置
# 此项 OS X 无法使用 $HOME 及 ~/ 设置路径 建议使用 /users/用户名/downloads
#@dir=$HOME/downloads
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
#@disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
file-allocation=trunc
# 断点续传
#@continue=true
## 下载连接相关 ##
# 最大同时下载任务数, 运行时可修改, 默认:5
#@max-concurrent-downloads=10
# 同一服务器连接数, 添加时可指定, 默认:1
#@max-connection-per-server=15
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
#@min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
#@split=15
# 整体下载速度限制, 运行时可修改, 默认:0
#@max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#@max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
max-overall-upload-limit=128K
# 单个任务上传速度限制, 默认:0
#@max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=false
#运行覆盖已存在文件
#@allow-overwrite=true
#自动重命名
#@auto-file-renaming=true
## 进度保存相关 ##
# 从会话文件中读取下载任务
#@input-file=/Users/Shared/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
#@save-session=/Users/Shared/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
save-session-interval=30
## RPC相关设置 ##
# 启用RPC, 默认:false
enable-rpc=true
# 允许所有来源, 默认:false
rpc-allow-origin-all=true
# 允许非外部访问, 默认:false
rpc-listen-all=true
# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同
#event-poll=select
# RPC监听端口, 端口被占用时可以修改, 默认:6800
# 使用本客户端请勿修改此项
# rpc-listen-port=6800
# 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
#rpc-secret=token
## BT/PT下载相关 ##
# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
#follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51413
# 单个种子最大连接数, 默认:55
#bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
# enable-dht=false
# 打开IPv6 DHT功能, PT需要禁用
#enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
#dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
bt-enable-lpd=true
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=true
# 每个种子限速, 对少种的PT很有用, 默认:50K
#bt-request-peer-speed-limit=50K
# 客户端伪装, PT需要
peer-id-prefix=-TR2770-
user-agent=Transmission/2.94
# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=1.0
# 强制保存会话, 即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
#force-save=false
# BT校验相关, 默认:true
#bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=true
# bt-tracker数据来自https://github.com/ngosang/trackerslist/blob/master/trackers_best.txt
bt-tracker=udp://tracker.coppersurfer.tk:6969/announce,udp://tracker.opentrackr.org:1337/announce,udp://tracker.internetwarriors.net:1337/announce,udp://9.rarbg.to:2710/announce,udp://exodus.desync.com:6969/announce,udp://tracker2.itzmx.com:6961/announce,udp://tracker1.itzmx.com:8080/announce,udp://explodie.org:6969/announce,http://tracker.tfile.me:80/announce.php,http://tracker.tfile.me:80/announce,http://tracker.tfile.co:80/announce,http://peersteers.org:80/announce,udp://tracker.tiny-vps.com:6969/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://denis.stalker.upeer.me:6969/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.port443.xyz:6969/announce,udp://tracker.cyberia.is:6969/announce,udp://thetracker.org:80/announce,udp://retracker.lanta-net.ru:2710/announce
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix Linux Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=trunc
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
BIN
View File
Binary file not shown.
-108
View File
@@ -1,108 +0,0 @@
## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ##
## 被注释的选项填写的是默认值, 建议在需要修改时再取消注释 ##
## 添加了@和默认启用的选项都是系统需要调用的,请不要随意改动否则可能无法正常运行
## 文件保存相关 ##
# 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置
# 此项 OS X 无法使用 $HOME 及 ~/ 设置路径 建议使用 /users/用户名/downloads
#@dir=$HOME/downloads
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
#@disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
file-allocation=falloc
# 断点续传
#@continue=true
## 下载连接相关 ##
# 最大同时下载任务数, 运行时可修改, 默认:5
#@max-concurrent-downloads=10
# 同一服务器连接数, 添加时可指定, 默认:1
#@max-connection-per-server=15
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
#@min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
#@split=15
# 整体下载速度限制, 运行时可修改, 默认:0
#@max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#@max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
max-overall-upload-limit=128K
# 单个任务上传速度限制, 默认:0
#@max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=false
#运行覆盖已存在文件
#@allow-overwrite=true
#自动重命名
#@auto-file-renaming=true
## 进度保存相关 ##
# 从会话文件中读取下载任务
#@input-file=/Users/Shared/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
#@save-session=/Users/Shared/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
save-session-interval=30
## RPC相关设置 ##
# 启用RPC, 默认:false
enable-rpc=true
# 允许所有来源, 默认:false
rpc-allow-origin-all=true
# 允许非外部访问, 默认:false
rpc-listen-all=true
# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同
#event-poll=select
# RPC监听端口, 端口被占用时可以修改, 默认:6800
# 使用本客户端请勿修改此项
# rpc-listen-port=6800
# 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
#rpc-secret=token
## BT/PT下载相关 ##
# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
#follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51413
# 单个种子最大连接数, 默认:55
#bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
# enable-dht=false
# 打开IPv6 DHT功能, PT需要禁用
#enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
#dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
bt-enable-lpd=true
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=true
# 每个种子限速, 对少种的PT很有用, 默认:50K
#bt-request-peer-speed-limit=50K
# 客户端伪装, PT需要
peer-id-prefix=-TR2770-
user-agent=Transmission/2.94
# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=1.0
# 强制保存会话, 即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
#force-save=false
# BT校验相关, 默认:true
#bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=true
# bt-tracker数据来自https://github.com/ngosang/trackerslist/blob/master/trackers_best.txt
bt-tracker=udp://tracker.coppersurfer.tk:6969/announce,udp://tracker.opentrackr.org:1337/announce,udp://tracker.internetwarriors.net:1337/announce,udp://9.rarbg.to:2710/announce,udp://exodus.desync.com:6969/announce,udp://tracker2.itzmx.com:6961/announce,udp://tracker1.itzmx.com:8080/announce,udp://explodie.org:6969/announce,http://tracker.tfile.me:80/announce.php,http://tracker.tfile.me:80/announce,http://tracker.tfile.co:80/announce,http://peersteers.org:80/announce,udp://tracker.tiny-vps.com:6969/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://denis.stalker.upeer.me:6969/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.port443.xyz:6969/announce,udp://tracker.cyberia.is:6969/announce,udp://thetracker.org:80/announce,udp://retracker.lanta-net.ru:2710/announce
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix Windows Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=none
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
BIN
View File
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
###############################
# Motrix Windows Aria2 config file
#
# @see https://aria2.github.io/manual/en/html/aria2c.html
#
###############################
################ RPC ################
# Enable JSON-RPC/XML-RPC server.
enable-rpc=true
# Add Access-Control-Allow-Origin header field with value * to the RPC response.
rpc-allow-origin-all=true
# Listen incoming JSON-RPC/XML-RPC requests on all network interfaces.
rpc-listen-all=true
################ File system ################
# Save a control file(*.aria2) every SEC seconds.
auto-save-interval=10
# Enable disk cache.
disk-cache=64M
# Specify file allocation method.
file-allocation=falloc
# No file allocation is made for files whose size is smaller than SIZE
no-file-allocation-limit=64M
# Save error/unfinished downloads to a file specified by --save-session option every SEC seconds.
save-session-interval=10
################ Task ################
# Exclude seed only downloads when counting concurrent active downloads
bt-detach-seed-only=true
# Verify the peer using certificates specified in --ca-certificate option.
check-certificate=false
# If aria2 receives "file not found" status from the remote HTTP/FTP servers NUM times
# without getting a single byte, then force the download to fail.
max-file-not-found=10
# Set number of tries.
max-tries=0
# Set the seconds to wait between retries. When SEC > 0, aria2 will retry downloads when the HTTP server returns a 503 response.
retry-wait=10
# Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server. After the connection is established, this option makes no effect and --timeout option is used instead.
connect-timeout=10
# Set timeout in seconds.
timeout=10
# aria2 does not split less than 2*SIZE byte range.
min-split-size=1M
# Send Accept: deflate, gzip request header.
http-accept-gzip=true
# Retrieve timestamp of the remote file from the remote HTTP/FTP server and if it is available, apply it to the local file.
remote-time=true
# Set interval in seconds to output download progress summary. Setting 0 suppresses the output.
summary-interval=0
# Handle quoted string in Content-Disposition header as UTF-8 instead of ISO-8859-1, for example, the filename parameter, but not the extended version filename*.
content-disposition-default-utf8=true
################ BT Task ################
# Enable Local Peer Discovery.
bt-enable-lpd=true
# Requires BitTorrent message payload encryption with arc4.
# bt-force-encryption=true
# If true is given, after hash check using --check-integrity option and file is complete, continue to seed file.
bt-hash-check-seed=true
# Specify the maximum number of peers per torrent.
bt-max-peers=128
# Try to download first and last pieces of each file first. This is useful for previewing files.
bt-prioritize-piece=head
# Removes the unselected files when download is completed in BitTorrent.
bt-remove-unselected-file=true
# Seed previously downloaded files without verifying piece hashes.
bt-seed-unverified=false
# Set the connect timeout in seconds to establish connection to tracker. After the connection is established, this option makes no effect and --bt-tracker-timeout option is used instead.
bt-tracker-connect-timeout=10
# Set timeout in seconds.
bt-tracker-timeout=10
# Set host and port as an entry point to IPv4 DHT network.
dht-entry-point=dht.transmissionbt.com:6881
# Set host and port as an entry point to IPv6 DHT network.
dht-entry-point6=dht.transmissionbt.com:6881
# Enable IPv4 DHT functionality. It also enables UDP tracker support.
enable-dht=true
# Enable IPv6 DHT functionality.
enable-dht6=true
# Enable Peer Exchange extension.
enable-peer-exchange=true
# Specify the string used during the bitorrent extended handshake for the peer's client version.
peer-agent=Transmission/3.00
# Specify the prefix of peer ID.
peer-id-prefix=-TR3000-
+14
View File
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"./src/renderer/*"
],
"@shared/*": [
"./src/shared/*"
]
}
},
"exclude": ["node_modules", "dist"]
}
-22933
View File
File diff suppressed because it is too large Load Diff
+82 -207
View File
@@ -1,13 +1,13 @@
{
"name": "Motrix",
"version": "1.2.2",
"version": "1.8.15",
"description": "A full-featured download manager",
"homepage": "https://motrix.app",
"author": {
"name": "AGALWOOD",
"name": "Dr_rOot",
"email": "agalwood.net@gmail.com"
},
"copyright": "Copyright© AGALWOOD",
"copyright": "Copyright© Dr_rOot",
"license": "MIT",
"main": "./dist/electron/main.js",
"repository": {
@@ -17,223 +17,98 @@
"scripts": {
"release": "npm run build --publish onTagOrDraft",
"build": "node .electron-vue/build.js && electron-builder",
"build:applesilicon": "node .electron-vue/build.js && electron-builder --arm64 --mac",
"build:github": "node .electron-vue/build.js",
"build:dir": "node .electron-vue/build.js && electron-builder --dir",
"build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
"build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
"dev": "node .electron-vue/dev-runner.js",
"dev:renderer": "webpack-dev-server --hot --colors --config .electron-vue/webpack.renderer.config.js --port 9080 --content-base app/dist",
"dev:renderer": "webpack serve --node-env development --hot --color --config .electron-vue/webpack.renderer.config.js --port 9080 --content-base app/dist",
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src",
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src",
"pack": "npm run pack:main && npm run pack:renderer",
"pack:main": "cross-env NODE_ENV=production webpack --mode production --progress --colors --config .electron-vue/webpack.main.config.js",
"pack:renderer": "cross-env NODE_ENV=production webpack --mode production --progress --colors --config .electron-vue/webpack.renderer.config.js",
"postinstall": "npm run lint:fix"
"pack:main": "webpack --node-env production --progress --color --config .electron-vue/webpack.main.config.js",
"pack:renderer": "webpack --node-env production --progress --color --config .electron-vue/webpack.renderer.config.js",
"postinstall": "electron-builder install-app-deps && npm run lint:fix"
},
"build": {
"productName": "Motrix",
"appId": "net.agalwood.Motrix",
"fileAssociations": [
{
"ext": "torrent",
"mimeType": "application/x-bittorrent",
"name": "Torrent",
"role": "Viewer"
}
],
"asar": true,
"directories": {
"output": "release"
},
"files": [
"dist/electron/**/*"
],
"dmg": {
"window": {
"width": 540,
"height": 380
},
"contents": [
{
"x": 410,
"y": 230,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 230,
"type": "file"
}
]
},
"mac": {
"target": [
"dmg",
"zip"
],
"type": "distribution",
"darkModeSupport": true,
"extraResources": {
"from": "./extra/darwin/",
"to": "./",
"filter": [
"**/*"
]
},
"binaries": [
"./release/mac/Motrix.app/Contents/Resources/engine/aria2c"
],
"category": "public.app-category.utilities",
"protocols": [
{
"name": "Motrix Protocol",
"schemes": [
"mo",
"motrix"
]
}
]
},
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64",
"ia32"
]
},
{
"target": "zip",
"arch": [
"x64",
"ia32"
]
},
{
"target": "portable",
"arch": [
"x64",
"ia32"
]
}
],
"extraResources": {
"from": "./extra/win32/",
"to": "./",
"filter": [
"**/*"
]
}
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
},
"linux": {
"category": "Network",
"target": [
"deb",
"snap",
"AppImage"
],
"extraResources": {
"from": "./extra/linux/",
"to": "./",
"filter": [
"**/*"
]
}
},
"publish": [
{
"provider": "generic",
"url": "https://motrix.app/release/"
},
{
"provider": "github"
}
]
"engines": {
"node" : ">=16.0.0"
},
"dependencies": {
"@panter/vue-i18next": "^0.15.0",
"aria2": "^4.0.3",
"axios": "^0.18.0",
"blob-util": "^2.0.2",
"clipboard-polyfill": "^2.7.0",
"electron-debug": "^2.1.0",
"electron-is": "^3.0.0",
"electron-log": "^2.2.17",
"electron-updater": "^4.0.8",
"element-ui": "^2.6.2",
"forever-monitor": "^1.7.1",
"i18next": "^15.0.6",
"lodash": "^4.17.11",
"normalize.css": "^8.0.1",
"parse-torrent": "^6.1.2",
"svg-innerhtml": "^1.1.0",
"vue": "^2.6.10",
"vue-electron": "^1.0.6",
"vue-router": "^3.0.2",
"vuex": "^3.1.0",
"vuex-router-sync": "^5.0.0"
"node-fetch": "^2.6.1",
"ws": "^8.13.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.5.1",
"@vue/cli-plugin-eslint": "^3.5.1",
"@vue/cli-service": "^3.5.1",
"@vue/eslint-config-standard": "^4.0.0",
"ajv": "^6.10.0",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-loader": "^7.1.4",
"@babel/core": "^7.21.4",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-transform-runtime": "^7.21.4",
"@babel/preset-env": "^7.21.4",
"@babel/register": "^7.21.0",
"@babel/runtime": "^7.21.0",
"@bany/curl-to-json": "^1.2.7",
"@electron/notarize": "^1.2.3",
"@electron/osx-sign": "^1.0.4",
"@electron/remote": "^2.0.9",
"@motrix/multispinner": "^0.2.4",
"@motrix/nat-api": "^0.3.4",
"@panter/vue-i18next": "^0.15.2",
"@vue/eslint-config-standard": "^6.1.0",
"ajv": "^8.12.0",
"axios": "^1.4.0",
"babel-eslint": "^10.1.0",
"babel-loader": "^9.1.2",
"babel-plugin-component": "^1.1.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"babili-webpack-plugin": "^0.1.2",
"cfonts": "^2.4.2",
"chalk": "^2.4.2",
"copy-webpack-plugin": "^5.0.1",
"cross-env": "^5.1.6",
"css-loader": "^2.1.1",
"del": "^4.0.0",
"devtron": "^1.4.0",
"electron": "^4.1.1",
"electron-builder": "^20.38.5",
"electron-devtools-installer": "^2.2.4",
"electron-notarize": "^0.0.5",
"electron-osx-sign": "^0.4.11",
"electron-store": "^2.0.0",
"eslint": "^5.15.3",
"eslint-config-standard": "^12.0.0",
"bittorrent-peerid": "^1.3.6",
"blob-util": "^2.0.2",
"cfonts": "^3.1.1",
"chalk": "^4.1.2",
"copy-webpack-plugin": "^11.0.0",
"cross-env": "^7.0.3",
"css-loader": "^6.7.3",
"css-minimizer-webpack-plugin": "^5.0.0",
"del": "^6.1.1",
"electron": "^22.3.7",
"electron-builder": "^24.2.0",
"electron-devtools-installer": "^3.2.0",
"electron-is": "^3.0.0",
"electron-log": "^4.4.8",
"electron-store": "^8.1.0",
"electron-updater": "^5.3.0",
"element-ui": "^2.15.13",
"eslint": "^7.32.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.1.2",
"eslint-plugin-html": "^4.0.6",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.2",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "0.5.0",
"multispinner": "^0.2.1",
"node-loader": "^0.6.0",
"node-sass": "^4.10.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"vue-html-loader": "^1.2.4",
"vue-loader": "^15.7.0",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.2.1",
"webpack-hot-middleware": "^2.24.3",
"webpack-merge": "^4.2.1"
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.11.0",
"eslint-webpack-plugin": "^4.0.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.1",
"i18next": "^22.4.15",
"lodash": "^4.17.21",
"mini-css-extract-plugin": "2.7.5",
"node-loader": "^2.0.0",
"normalize.css": "^8.0.1",
"parse-torrent": "^9.1.5",
"randomatic": "^3.1.1",
"sass": "1.62.1",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.2",
"terser-webpack-plugin": "^5.3.7",
"vue": "^2.7.14",
"vue-electron": "^1.0.6",
"vue-loader": "^15.10.1",
"vue-router": "^3.6.5",
"vue-selectable": "^0.5.0",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.7.14",
"vuex": "^3.6.2",
"vuex-router-sync": "^5.0.0",
"webpack": "^5.81.0",
"webpack-cli": "^5.0.2",
"webpack-dev-server": "^4.13.3",
"webpack-hot-middleware": "^2.25.3",
"webpack-merge": "^5.8.0",
"worker-loader": "^3.0.8"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+35 -6
View File
@@ -10,22 +10,51 @@
</script>
<% } %>
</head>
<style>
.skeleton-aside {
background-color: rgba(0, 0, 0, 0.8);
width: 78px;
}
.skeleton-subnav {
background-color: #f4f5f7;
width: 200px;
}
.skeleton-main {
background-color: #fff;
}
@media (prefers-color-scheme: dark) {
.skeleton-aside {
background-color: rgba(0, 0, 0, 0.9);
}
.skeleton-subnav {
background-color: #2D2D2D;
}
.skeleton-main {
background-color: #343434;
}
}
</style>
<body>
<div id="app">
<div class="title-bar"></div>
<section class="el-container" id="container">
<aside class="el-aside aside" style="width: 78px;">
<aside class="el-aside skeleton-aside hidden-sm-and-down">
</aside>
<aside class="el-aside subnav" style="width: 200px;">
<aside class="el-aside skeleton-subnav hidden-xs-only">
</aside>
<section class="el-container main">
<section class="el-container skeleton-main">
</section>
</section>
</div>
<!-- Set `__static` path to static files in production -->
<script>
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
</script>
<% if (!htmlWebpackPlugin.options.isBrowser && !htmlWebpackPlugin.options.isDev) { %>
<script>
window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
</script>
<% } %>
<!-- webpack builds are automatically injected -->
</body>
+703 -68
View File
@@ -1,13 +1,29 @@
import { EventEmitter } from 'events'
import { app, shell, dialog, ipcMain } from 'electron'
import is from 'electron-is'
import { readFile } from 'fs'
import { readFile, unlink } from 'fs'
import { extname, basename } from 'path'
import { isEmpty, isEqual } from 'lodash'
import {
APP_RUN_MODE,
AUTO_SYNC_TRACKER_INTERVAL,
AUTO_CHECK_UPDATE_INTERVAL
} from '@shared/constants'
import { checkIsNeedRun } from '@shared/utils'
import {
convertTrackerDataToComma,
fetchBtTrackerFromSource,
reduceTrackerString
} from '@shared/utils/tracker'
import logger from './core/Logger'
import Context from './core/Context'
import ConfigManager from './core/ConfigManager'
import { setupLocaleManager } from '@/ui/Locale'
import { setupLocaleManager } from './ui/Locale'
import Engine from './core/Engine'
import EngineClient from './core/EngineClient'
import UPnPManager from './core/UPnPManager'
import AutoLaunchManager from './core/AutoLaunchManager'
import UpdateManager from './core/UpdateManager'
import EnergyManager from './core/EnergyManager'
import ProtocolManager from './core/ProtocolManager'
@@ -15,6 +31,8 @@ import WindowManager from './ui/WindowManager'
import MenuManager from './ui/MenuManager'
import TouchBarManager from './ui/TouchBarManager'
import TrayManager from './ui/TrayManager'
import DockManager from './ui/DockManager'
import ThemeManager from './ui/ThemeManager'
export default class Application extends EventEmitter {
constructor () {
@@ -24,41 +42,113 @@ export default class Application extends EventEmitter {
}
init () {
this.configManager = new ConfigManager()
this.initContext()
this.locale = this.configManager.getLocale()
this.localeManager = setupLocaleManager(this.locale)
this.i18n = this.localeManager.getI18n()
this.initConfigManager()
this.windowManager = new WindowManager({
userConfig: this.configManager.getUserConfig()
})
this.setupLogger()
this.initLocaleManager()
this.setupApplicationMenu()
this.initWindowManager()
this.initUPnPManager()
this.engine = new Engine({
systemConfig: this.configManager.getSystemConfig(),
userConfig: this.configManager.getUserConfig()
})
this.startEngine()
this.menuManager = new MenuManager()
this.menuManager.setup(this.locale)
this.initEngineClient()
this.touchBarManager = new TouchBarManager()
this.initTouchBarManager()
this.trayManager = new TrayManager()
this.initThemeManager()
this.energyManager = new EnergyManager()
this.initTrayManager()
this.initDockManager()
this.initAutoLaunchManager()
this.initEnergyManager()
this.initUpdaterManager()
this.initProtocolManager()
this.handleCommands()
this.handleEvents()
this.handleIpcMessages()
this.handleIpcInvokes()
this.emit('application:initialized')
}
initContext () {
this.context = new Context()
}
initConfigManager () {
this.configListeners = {}
this.configManager = new ConfigManager()
}
offConfigListeners () {
try {
Object.keys(this.configListeners).forEach((key) => {
this.configListeners[key]()
})
} catch (e) {
logger.warn('[Motrix] offConfigListeners===>', e)
}
this.configListeners = {}
}
setupLogger () {
const { userConfig } = this.configManager
const key = 'log-level'
const logLevel = userConfig.get(key)
logger.transports.file.level = logLevel
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info(`[Motrix] detected ${key} value change event:`, newValue, oldValue)
logger.transports.file.level = newValue
})
}
initLocaleManager () {
this.locale = this.configManager.getLocale()
this.localeManager = setupLocaleManager(this.locale)
this.i18n = this.localeManager.getI18n()
}
setupApplicationMenu () {
this.menuManager = new MenuManager()
this.menuManager.setup(this.locale)
}
adjustMenu () {
if (is.mas()) {
const visibleStates = {
'app.check-for-updates': false,
'task.new-bt-task': false
}
this.menuManager.updateMenuStates(visibleStates, null, null)
this.trayManager.updateMenuStates(visibleStates, null, null)
}
}
startEngine () {
const self = this
try {
this.engine = new Engine({
systemConfig: this.configManager.getSystemConfig(),
userConfig: this.configManager.getUserConfig()
})
this.engine.start()
} catch (err) {
const { message } = err
@@ -66,25 +156,353 @@ export default class Application extends EventEmitter {
type: 'error',
title: this.i18n.t('app.system-error-title'),
message: this.i18n.t('app.system-error-message', { message })
}, () => {
}).then(_ => {
setTimeout(() => {
app.quit()
self.quit()
}, 100)
})
}
}
start (page) {
this.showPage(page)
async stopEngine () {
logger.info('[Motrix] stopEngine===>')
try {
await this.engineClient.shutdown({ force: true })
logger.info('[Motrix] stopEngine.setImmediate===>')
setImmediate(() => {
this.engine.stop()
})
} catch (err) {
logger.warn('[Motrix] shutdown engine fail: ', err.message)
} finally {
// no finally
}
}
showPage (page) {
const win = this.windowManager.openWindow(page)
initEngineClient () {
const port = this.configManager.getSystemConfig('rpc-listen-port')
const secret = this.configManager.getSystemConfig('rpc-secret')
this.engineClient = new EngineClient({
port,
secret
})
}
initAutoLaunchManager () {
this.autoLaunchManager = new AutoLaunchManager()
}
initEnergyManager () {
this.energyManager = new EnergyManager()
}
initTrayManager () {
this.trayManager = new TrayManager({
theme: this.configManager.getUserConfig('tray-theme'),
systemTheme: this.themeManager.getSystemTheme(),
speedometer: this.configManager.getUserConfig('tray-speedometer'),
runMode: this.configManager.getUserConfig('run-mode')
})
this.watchTraySpeedometerEnabledChange()
this.trayManager.on('mouse-down', ({ focused }) => {
this.sendCommandToAll('application:update-tray-focused', { focused })
})
this.trayManager.on('mouse-up', ({ focused }) => {
this.sendCommandToAll('application:update-tray-focused', { focused })
})
this.trayManager.on('drop-files', (files = []) => {
this.handleFile(files[0])
})
this.trayManager.on('drop-text', (text) => {
this.handleProtocol(text)
})
}
watchTraySpeedometerEnabledChange () {
const { userConfig } = this.configManager
const key = 'tray-speedometer'
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info(`[Motrix] detected ${key} value change event:`, newValue, oldValue)
this.trayManager.handleSpeedometerEnableChange(newValue)
})
}
initDockManager () {
this.dockManager = new DockManager({
runMode: this.configManager.getUserConfig('run-mode')
})
}
watchOpenAtLoginChange () {
const { userConfig } = this.configManager
const key = 'open-at-login'
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info(`[Motrix] detected ${key} value change event:`, newValue, oldValue)
if (is.linux()) {
return
}
if (newValue) {
this.autoLaunchManager.enable()
} else {
this.autoLaunchManager.disable()
}
})
}
watchProtocolsChange () {
const { userConfig } = this.configManager
const key = 'protocols'
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info(`[Motrix] detected ${key} value change event:`, newValue, oldValue)
if (!newValue || isEqual(newValue, oldValue)) {
return
}
logger.info('[Motrix] setup protocols client:', newValue)
this.protocolManager.setup(newValue)
})
}
watchRunModeChange () {
const { userConfig } = this.configManager
const key = 'run-mode'
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info(`[Motrix] detected ${key} value change event:`, newValue, oldValue)
this.trayManager.handleRunModeChange(newValue)
if (newValue !== APP_RUN_MODE.TRAY) {
this.dockManager.show()
} else {
this.dockManager.hide()
// Hiding the dock icon will trigger the entire app to hide.
this.show()
}
})
}
watchShowProgressBarChange () {
const { userConfig } = this.configManager
const key = 'show-progress-bar'
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info(`[Motrix] detected ${key} value change event:`, newValue, oldValue)
if (newValue) {
this.bindProgressChange()
} else {
this.unbindProgressChange()
}
})
}
initUPnPManager () {
this.upnp = new UPnPManager()
this.watchUPnPEnabledChange()
this.watchUPnPPortsChange()
const enabled = this.configManager.getUserConfig('enable-upnp')
if (!enabled) {
return
}
this.startUPnPMapping()
}
async startUPnPMapping () {
const btPort = this.configManager.getSystemConfig('listen-port')
const dhtPort = this.configManager.getSystemConfig('dht-listen-port')
const promises = [
this.upnp.map(btPort),
this.upnp.map(dhtPort)
]
try {
await Promise.allSettled(promises)
} catch (e) {
logger.warn('[Motrix] start UPnP mapping fail', e.message)
}
}
async stopUPnPMapping () {
const btPort = this.configManager.getSystemConfig('listen-port')
const dhtPort = this.configManager.getSystemConfig('dht-listen-port')
const promises = [
this.upnp.unmap(btPort),
this.upnp.unmap(dhtPort)
]
try {
await Promise.allSettled(promises)
} catch (e) {
logger.warn('[Motrix] stop UPnP mapping fail', e)
}
}
watchUPnPPortsChange () {
const { systemConfig } = this.configManager
const watchKeys = ['listen-port', 'dht-listen-port']
watchKeys.forEach((key) => {
this.configListeners[key] = systemConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info('[Motrix] detected port change event:', key, newValue, oldValue)
const enable = this.configManager.getUserConfig('enable-upnp')
if (!enable) {
return
}
const promises = [
this.upnp.unmap(oldValue),
this.upnp.map(newValue)
]
try {
await Promise.allSettled(promises)
} catch (e) {
logger.info('[Motrix] change UPnP port mapping failed:', e)
}
})
})
}
watchUPnPEnabledChange () {
const { userConfig } = this.configManager
const key = 'enable-upnp'
this.configListeners[key] = userConfig.onDidChange(key, async (newValue, oldValue) => {
logger.info('[Motrix] detected enable-upnp value change event:', newValue, oldValue)
if (newValue) {
this.startUPnPMapping()
} else {
await this.stopUPnPMapping()
this.upnp.closeClient()
}
})
}
async shutdownUPnPManager () {
const enable = this.configManager.getUserConfig('enable-upnp')
if (enable) {
await this.stopUPnPMapping()
}
this.upnp.closeClient()
}
autoSyncTracker () {
const enable = this.configManager.getUserConfig('auto-sync-tracker')
const lastTime = this.configManager.getUserConfig('last-sync-tracker-time')
const result = checkIsNeedRun(enable, lastTime, AUTO_SYNC_TRACKER_INTERVAL)
logger.info('[Motrix] auto sync tracker checkIsNeedRun:', result)
if (!result) {
return
}
const source = this.configManager.getUserConfig('tracker-source')
if (isEmpty(source)) {
return
}
setTimeout(() => {
fetchBtTrackerFromSource(source).then((data) => {
logger.warn('[Motrix] auto sync tracker data:', data)
if (!data || data.length === 0) {
return
}
let tracker = convertTrackerDataToComma(data)
tracker = reduceTrackerString(tracker)
this.savePreference({
system: {
'bt-tracker': tracker
},
user: {
'last-sync-tracker-time': Date.now()
}
})
}).catch((err) => {
logger.warn('[Motrix] auto sync tracker failed:', err.message)
})
}, 500)
}
autoResumeTask () {
const enabled = this.configManager.getUserConfig('resume-all-when-app-launched')
if (!enabled) {
return
}
this.engineClient.call('unpauseAll')
}
initWindowManager () {
this.windowManager = new WindowManager({
userConfig: this.configManager.getUserConfig()
})
this.windowManager.on('window-resized', (data) => {
this.storeWindowState(data)
})
this.windowManager.on('window-moved', (data) => {
this.storeWindowState(data)
})
this.windowManager.on('window-closed', (data) => {
this.storeWindowState(data)
})
this.windowManager.on('enter-full-screen', (window) => {
this.dockManager.show()
})
this.windowManager.on('leave-full-screen', (window) => {
const mode = this.configManager.getUserConfig('run-mode')
if (mode === APP_RUN_MODE.TRAY) {
this.dockManager.hide()
}
})
}
storeWindowState (data = {}) {
const enabled = this.configManager.getUserConfig('keep-window-state')
if (!enabled) {
return
}
const state = this.configManager.getUserConfig('window-state', {})
const { page, bounds } = data
const newState = {
...state,
[page]: bounds
}
this.configManager.setUserConfig('window-state', newState)
}
start (page, options = {}) {
const win = this.showPage(page, options)
win.once('ready-to-show', () => {
this.isReady = true
this.emit('ready')
})
this.touchBarManager.setup(page, win)
if (is.macOS()) {
this.touchBarManager.setup(page, win)
}
}
showPage (page, options = {}) {
const { openedAtLogin } = options
const autoHideWindow = this.configManager.getUserConfig('auto-hide-window')
return this.windowManager.openWindow(page, {
hidden: openedAtLogin || autoHideWindow
})
}
show (page = 'index') {
@@ -108,8 +526,27 @@ export default class Application extends EventEmitter {
}
stop () {
this.engine.stop()
this.energyManager.stopPowerSaveBlocker()
try {
const promises = [
this.stopEngine(),
this.shutdownUPnPManager(),
this.energyManager.stopPowerSaveBlocker(),
this.trayManager.destroy()
]
return promises
} catch (err) {
logger.warn('[Motrix] stop error: ', err.message)
}
}
async stopAllSettled () {
await Promise.allSettled(this.stop())
}
async quit () {
await this.stopAllSettled()
app.exit()
}
sendCommand (command, ...args) {
@@ -135,18 +572,30 @@ export default class Application extends EventEmitter {
})
}
initProtocolManager () {
if (is.dev() || is.mas()) {
initThemeManager () {
this.themeManager = new ThemeManager()
this.themeManager.on('system-theme-change', (theme) => {
this.trayManager.handleSystemThemeChange(theme)
this.sendCommandToAll('application:update-system-theme', { theme })
})
}
initTouchBarManager () {
if (!is.macOS()) {
return
}
this.protocolManager = new ProtocolManager()
this.touchBarManager = new TouchBarManager()
}
initProtocolManager () {
const protocols = this.configManager.getUserConfig('protocols', {})
this.protocolManager = new ProtocolManager({
protocols
})
}
handleProtocol (url) {
if (is.dev() || is.mas()) {
return
}
this.show()
this.protocolManager.handle(url)
@@ -163,15 +612,17 @@ export default class Application extends EventEmitter {
this.show()
const fileName = basename(filePath)
const name = basename(filePath)
readFile(filePath, (err, data) => {
if (err) {
logger.warn(`[Motrix] read file error: ${filePath}`, err.message)
return
}
const file = Buffer.from(data).toString('base64')
const args = [fileName, file]
this.sendCommandToAll('application:new-bt-task-with-file', ...args)
const dataURL = Buffer.from(data).toString('base64')
this.sendCommandToAll('application:new-bt-task-with-file', {
name,
dataURL
})
})
}
@@ -179,13 +630,20 @@ export default class Application extends EventEmitter {
if (is.mas()) {
return
}
this.updateManager = new UpdateManager()
const enabled = this.configManager.getUserConfig('auto-check-update')
const lastTime = this.configManager.getUserConfig('last-check-update-time')
this.updateManager = new UpdateManager({
autoCheck: checkIsNeedRun(enabled, lastTime, AUTO_CHECK_UPDATE_INTERVAL)
})
this.handleUpdaterEvents()
}
handleUpdaterEvents () {
this.updateManager.on('checking', (event) => {
this.menuManager.updateMenuItemEnabledState('app.check-for-updates', false)
this.trayManager.updateMenuItemEnabledState('app.check-for-updates', false)
this.configManager.setUserConfig('last-check-update-time', Date.now())
})
this.updateManager.on('download-progress', (event) => {
@@ -195,55 +653,97 @@ export default class Application extends EventEmitter {
this.updateManager.on('update-not-available', (event) => {
this.menuManager.updateMenuItemEnabledState('app.check-for-updates', true)
this.trayManager.updateMenuItemEnabledState('app.check-for-updates', true)
})
this.updateManager.on('update-downloaded', (event) => {
this.menuManager.updateMenuItemEnabledState('app.check-for-updates', true)
this.trayManager.updateMenuItemEnabledState('app.check-for-updates', true)
const win = this.windowManager.getWindow('index')
win.setProgressBar(0)
})
this.updateManager.on('will-updated', (event) => {
this.updateManager.on('update-cancelled', (event) => {
this.menuManager.updateMenuItemEnabledState('app.check-for-updates', true)
this.trayManager.updateMenuItemEnabledState('app.check-for-updates', true)
const win = this.windowManager.getWindow('index')
win.setProgressBar(-1)
})
this.updateManager.on('will-updated', async (event) => {
this.windowManager.setWillQuit(true)
await this.stopAllSettled()
})
this.updateManager.on('update-error', (event) => {
this.menuManager.updateMenuItemEnabledState('app.check-for-updates', true)
this.trayManager.updateMenuItemEnabledState('app.check-for-updates', true)
})
}
relaunch (page = 'index') {
this.stop()
async relaunch () {
await this.stopAllSettled()
app.relaunch()
app.exit()
// this.closePage(page)
// if (page === 'index') {
// this.engine.restart()
// }
// setTimeout(() => {
// this.showPage(page)
// }, 500)
}
async resetSession () {
await this.stopEngine()
app.clearRecentDocuments()
const sessionPath = this.context.get('session-path')
setTimeout(() => {
unlink(sessionPath, function (err) {
logger.info('[Motrix] Removed the download seesion file:', err)
})
this.engine.start()
}, 3000)
}
savePreference (config = {}) {
logger.info('[Motrix] save preference:', config)
const { system, user } = config
if (!isEmpty(system)) {
console.info('[Motrix] main save system config: ', system)
this.configManager.setSystemConfig(system)
this.engineClient.changeGlobalOption(system)
}
if (!isEmpty(user)) {
console.info('[Motrix] main save user config: ', user)
this.configManager.setUserConfig(user)
}
}
handleCommands () {
this.on('application:save-preference', this.savePreference)
this.on('application:update-tray', (tray) => {
this.trayManager.updateTrayByImage(tray)
})
this.on('application:relaunch', () => {
this.relaunch()
})
this.on('application:exit', () => {
this.engine.stop()
app.exit()
this.on('application:quit', () => {
this.quit()
})
this.on('application:show', (page) => {
this.on('application:show', ({ page }) => {
this.show(page)
})
this.on('application:hide', (page) => {
this.on('application:hide', ({ page }) => {
this.hide(page)
})
this.on('application:reset-session', () => this.resetSession())
this.on('application:reset', () => {
this.offConfigListeners()
this.configManager.reset()
this.relaunch()
})
@@ -252,15 +752,42 @@ export default class Application extends EventEmitter {
this.updateManager.check()
})
this.on('application:change-theme', (theme) => {
this.themeManager.updateSystemTheme(theme)
this.sendCommandToAll('application:update-theme', { theme })
})
this.on('application:change-locale', (locale) => {
logger.info('[Motrix] application:change-locale===>', locale)
this.localeManager.changeLanguageByLocale(locale)
.then(() => {
this.menuManager.setup(locale)
this.trayManager.setup(locale)
this.menuManager.handleLocaleChange(locale)
this.trayManager.handleLocaleChange(locale)
})
})
this.on('application:toggle-dock', (visible) => {
if (visible) {
this.dockManager.show()
} else {
this.dockManager.hide()
// Hiding the dock icon will trigger the entire app to hide.
this.show()
}
})
this.on('application:auto-hide-window', (hide) => {
if (hide) {
this.windowManager.handleWindowBlur()
} else {
this.windowManager.unbindWindowBlur()
}
})
this.on('application:change-menu-states', (visibleStates, enabledStates, checkedStates) => {
this.menuManager.updateMenuStates(visibleStates, enabledStates, checkedStates)
this.trayManager.updateMenuStates(visibleStates, enabledStates, checkedStates)
})
this.on('application:open-file', (event) => {
dialog.showOpenDialog({
properties: ['openFile'],
@@ -270,8 +797,8 @@ export default class Application extends EventEmitter {
extensions: ['torrent']
}
]
}, (filePaths) => {
if (!filePaths || filePaths.length === 0) {
}).then(({ canceled, filePaths }) => {
if (canceled || filePaths.length === 0) {
return
}
@@ -284,39 +811,147 @@ export default class Application extends EventEmitter {
app.clearRecentDocuments()
})
this.on('application:setup-protocols-client', (protocols) => {
if (is.dev() || is.mas() || !protocols) {
return
}
logger.info('[Motrix] setup protocols client:', protocols)
this.protocolManager.setup(protocols)
})
this.on('application:open-external', (url) => {
this.openExternal(url)
})
this.on('help:official-website', () => {
const url = 'https://motrix.app/'
shell.openExternal(url)
this.openExternal(url)
})
this.on('help:manual', () => {
const url = 'https://motrix.app/manual'
shell.openExternal(url)
this.openExternal(url)
})
this.on('help:release-notes', () => {
const url = 'https://motrix.app/release'
shell.openExternal(url)
this.openExternal(url)
})
this.on('help:report-problem', () => {
const url = 'https://motrix.app/report'
shell.openExternal(url)
this.openExternal(url)
})
}
openExternal (url) {
if (!url) {
return
}
shell.openExternal(url)
}
handleConfigChange (configName) {
this.sendCommandToAll('application:update-preference-config', { configName })
}
handleEvents () {
this.once('application:initialized', () => {
this.autoSyncTracker()
this.autoResumeTask()
this.adjustMenu()
})
this.configManager.userConfig.onDidAnyChange(() => this.handleConfigChange('user'))
this.configManager.systemConfig.onDidAnyChange(() => this.handleConfigChange('system'))
this.watchOpenAtLoginChange()
this.watchProtocolsChange()
this.watchRunModeChange()
this.watchShowProgressBarChange()
this.on('download-status-change', (downloading) => {
this.trayManager.handleDownloadStatusChange(downloading)
if (downloading) {
this.energyManager.startPowerSaveBlocker()
} else {
this.energyManager.stopPowerSaveBlocker()
}
})
this.on('speed-change', (speed) => {
this.dockManager.handleSpeedChange(speed)
this.trayManager.handleSpeedChange(speed)
})
this.on('task-download-complete', (task, path) => {
this.dockManager.openDock(path)
if (is.linux()) {
return
}
app.addRecentDocument(path)
})
if (this.configManager.userConfig.get('show-progress-bar')) {
this.bindProgressChange()
}
}
handleProgressChange (progress) {
if (this.updateManager.isChecking) {
return
}
if (!is.windows() && progress === 2) {
progress = 0
}
this.windowManager.getWindow('index').setProgressBar(progress)
}
bindProgressChange () {
if (this.listeners('progress-change').length > 0) {
return
}
this.on('progress-change', this.handleProgressChange)
}
unbindProgressChange () {
if (this.listeners('progress-change').length === 0) {
return
}
this.off('progress-change', this.handleProgressChange)
this.windowManager.getWindow('index').setProgressBar(-1)
}
handleIpcMessages () {
ipcMain.on('command', (event, command, ...args) => {
logger.log('receive command', command, ...args)
logger.log('[Motrix] ipc receive command', command, ...args)
this.emit(command, ...args)
})
ipcMain.on('update-menu-states', (event, visibleStates, enabledStates, checkedStates) => {
this.menuManager.updateStates(visibleStates, enabledStates, checkedStates)
ipcMain.on('event', (event, eventName, ...args) => {
logger.log('[Motrix] ipc receive event', eventName, ...args)
this.emit(eventName, ...args)
})
}
ipcMain.on('download-status-change', (event, status) => {
this.trayManager.updateStatus(status)
handleIpcInvokes () {
ipcMain.handle('get-app-config', async () => {
const systemConfig = this.configManager.getSystemConfig()
const userConfig = this.configManager.getUserConfig()
const context = this.context.get()
const result = {
...systemConfig,
...userConfig,
...context
}
return result
})
}
}
+94 -43
View File
@@ -5,9 +5,12 @@ import is from 'electron-is'
import ExceptionHandler from './core/ExceptionHandler'
import logger from './core/Logger'
import Application from './Application'
import { parseArgv } from './utils'
const EMPTY_STRING = ''
import {
splitArgv,
parseArgvAsUrl,
parseArgvAsFile
} from './utils'
import { EMPTY_STRING } from '@shared/constants'
export default class Launcher extends EventEmitter {
constructor () {
@@ -23,7 +26,7 @@ export default class Launcher extends EventEmitter {
makeSingleInstance (callback) {
// Mac App Store Sandboxed App not support requestSingleInstanceLock
if (is.mas()) {
callback()
callback && callback()
return
}
@@ -34,23 +37,33 @@ export default class Launcher extends EventEmitter {
} else {
app.on('second-instance', (event, argv, workingDirectory) => {
global.application.showPage('index')
if (!is.macOS() && argv.length > 1) { // Windows, Linux
this.file = parseArgv(argv)
this.sendFileToApplication()
if (!is.macOS() && argv.length > 1) {
this.handleAppLaunchArgv(argv)
}
})
callback()
callback && callback()
}
}
init () {
this.exceptionHandler = new ExceptionHandler()
this.openedAtLogin = is.macOS()
? app.getLoginItemSettings().wasOpenedAtLogin
: false
if (process.argv.length > 1) {
this.handleAppLaunchArgv(process.argv)
}
logger.info('[Motrix] openedAtLogin:', this.openedAtLogin)
this.handleAppEvents()
}
handleAppEvents () {
this.handleRendererRemote()
this.handleOpenUrl()
this.handleOpenFile()
@@ -58,42 +71,80 @@ export default class Launcher extends EventEmitter {
this.handleAppWillQuit()
}
/**
* handleOpenUrl
* "name": "Motrix Protocol",
* "schemes": ["mo", "motrix"]
*/
handleOpenUrl () {
if (is.mas()) {
return
}
app.on('open-url', (event, url) => {
logger.info(`[Motrix] open-url path: ${url}`)
event.preventDefault()
this.url = url
if (this.url && global.application && global.application.isReady) {
global.application.handleProtocol(this.url)
this.url = EMPTY_STRING
}
handleRendererRemote () {
app.on('browser-window-created', (_, window) => {
require('@electron/remote/main').enable(window.webContents)
})
}
/**
* handleOpenFile [WIP]
* handleOpenUrl
* Event 'open-url' macOS only
* "name": "Motrix Protocol",
* "schemes": ["mo", "motrix"]
*/
handleOpenUrl () {
if (is.mas() || !is.macOS()) {
return
}
app.on('open-url', (event, url) => {
logger.info(`[Motrix] open-url: ${url}`)
event.preventDefault()
this.url = url
this.sendUrlToApplication()
})
}
/**
* handleOpenFile
* Event 'open-file' macOS only
* handle open torrent file
*/
handleOpenFile () {
// macOS
if (is.macOS()) {
app.on('open-file', (event, path) => {
logger.info(`[Motrix] open-file path: ${path}`)
event.preventDefault()
this.file = path
this.sendFileToApplication()
})
} else if (process.argv.length > 1) { // Windows, Linux
this.file = parseArgv(process.argv)
if (!is.macOS()) {
return
}
app.on('open-file', (event, path) => {
logger.info(`[Motrix] open-file: ${path}`)
event.preventDefault()
this.file = path
this.sendFileToApplication()
})
}
/**
* handleAppLaunchArgv
* For Windows, Linux
* @param {array} argv
*/
handleAppLaunchArgv (argv) {
logger.info('[Motrix] handleAppLaunchArgv:', argv)
// args: array, extra: map
const { args, extra } = splitArgv(argv)
logger.info('[Motrix] split argv args:', args)
logger.info('[Motrix] split argv extra:', extra)
if (extra['--opened-at-login'] === '1') {
this.openedAtLogin = true
}
const file = parseArgvAsFile(args)
if (file) {
this.file = file
this.sendFileToApplication()
}
const url = parseArgvAsUrl(args)
if (url) {
this.url = url
this.sendUrlToApplication()
}
}
sendUrlToApplication () {
if (this.url && global.application && global.application.isReady) {
global.application.handleProtocol(this.url)
this.url = EMPTY_STRING
}
}
@@ -108,16 +159,15 @@ export default class Launcher extends EventEmitter {
app.on('ready', () => {
global.application = new Application()
global.application.start('index')
const { openedAtLogin } = this
global.application.start('index', {
openedAtLogin
})
global.application.on('ready', () => {
if (this.url) {
global.application.handleProtocol(this.url)
}
this.sendUrlToApplication()
if (this.file) {
global.application.handleFile(this.file)
}
this.sendFileToApplication()
})
})
@@ -133,6 +183,7 @@ export default class Launcher extends EventEmitter {
app.on('will-quit', () => {
logger.info('[Motrix] will-quit')
if (global.application) {
logger.info('[Motrix] will-quit.application.stop')
global.application.stop()
}
})
+21 -4
View File
@@ -1,5 +1,22 @@
export default {
'darwin': 'aria2c',
'win32': 'aria2c.exe',
'linux': 'aria2c'
export const engineBinMap = {
darwin: 'aria2c',
win32: 'aria2c.exe',
linux: 'aria2c'
}
export const engineArchMap = {
darwin: {
x64: 'x64',
arm64: 'arm64'
},
win32: {
ia32: 'ia32',
x64: 'x64',
arm64: 'x64'
},
linux: {
x64: 'x64',
arm: 'armv7l',
arm64: 'arm64'
}
}
+4 -4
View File
@@ -6,12 +6,12 @@ export default {
title: 'Motrix',
width: 1024,
height: 768,
minWidth: 840,
minWidth: 478,
minHeight: 420,
// backgroundColor: '#FFFFFF',
transparent: !is.windows()
transparent: is.macOS()
},
bindCloseToHide: true,
url: is.dev() ? `http://localhost:9080` : `file://${__dirname}/index.html`
openDevTools: is.dev(),
url: is.dev() ? 'http://localhost:9080' : require('path').join('file://', __dirname, '/index.html')
}
}
+2
View File
@@ -1,6 +1,8 @@
/* eslint quote-props: ["error", "always"] */
export default {
'task-list': 'application:task-list',
'new-task': 'application:new-task',
'new-bt-task': 'application:new-bt-task',
'pause-all-task': 'application:pause-all-task',
'resume-all-task': 'application:resume-all-task',
'preferences': 'application:preferences',
+34
View File
@@ -0,0 +1,34 @@
import { app } from 'electron'
import { LOGIN_SETTING_OPTIONS } from '@shared/constants'
export default class AutoLaunchManager {
enable () {
return new Promise((resolve, reject) => {
const enabled = app.getLoginItemSettings(LOGIN_SETTING_OPTIONS).openAtLogin
if (enabled) {
resolve()
}
app.setLoginItemSettings({
...LOGIN_SETTING_OPTIONS,
openAtLogin: true
})
resolve()
})
}
disable () {
return new Promise((resolve, reject) => {
app.setLoginItemSettings({ openAtLogin: false })
resolve()
})
}
isEnabled () {
return new Promise((resolve, reject) => {
const enabled = app.getLoginItemSettings(LOGIN_SETTING_OPTIONS).openAtLogin
resolve(enabled)
})
}
}
+124 -25
View File
@@ -1,11 +1,24 @@
import { app } from 'electron'
import is from 'electron-is'
import Store from 'electron-store'
import {
getLogPath,
getSessionPath,
getUserDownloadsPath
getDhtPath,
getUserDownloadsPath,
getMaxConnectionPerServer
} from '../utils/index'
import {
APP_RUN_MODE,
APP_THEME,
EMPTY_STRING,
IP_VERSION,
LOGIN_SETTING_OPTIONS,
NGOSANG_TRACKERS_BEST_IP_URL_CDN,
NGOSANG_TRACKERS_BEST_URL_CDN
} from '@shared/constants'
import { CHROME_UA } from '@shared/ua'
import { separateConfig } from '@shared/utils'
import { reduceTrackerString } from '@shared/utils/tracker'
export default class ConfigManager {
constructor () {
@@ -21,52 +34,138 @@ export default class ConfigManager {
}
/**
* some aria2 conf
* Some aria2 conf
* https://aria2.github.io/manual/en/html/aria2c.html
*
* Best bt trackers
* @see https://github.com/ngosang/trackerslist
*
* @see https://github.com/XIU2/TrackersListCollection
*/
initSystemConfig () {
this.systemConfig = new Store({
name: 'system',
/* eslint-disable quote-props */
defaults: {
dir: getUserDownloadsPath(),
// 断点续传
continue: true,
pause: true,
split: 16,
'rpc-listen-port': 16800,
'rpc-secret': '',
'all-proxy': EMPTY_STRING,
'allow-overwrite': false,
'auto-file-renaming': true,
'allow-overwrite': true,
'bt-exclude-tracker': EMPTY_STRING,
'bt-force-encryption': false,
'bt-load-saved-metadata': true,
'bt-save-metadata': true,
'bt-tracker': EMPTY_STRING,
'continue': true,
'dht-file-path': getDhtPath(IP_VERSION.V4),
'dht-file-path6': getDhtPath(IP_VERSION.V6),
'dht-listen-port': 26701,
'dir': getUserDownloadsPath(),
'enable-dht6': true,
'follow-metalink': true,
'follow-torrent': true,
'listen-port': 21301,
'max-concurrent-downloads': 5,
// macOS 版本修改过源码自己编译的,Linux 和 Windows 版本 暂未处理
'max-connection-per-server': is.macOS() ? 64 : 16,
'min-split-size': '1M',
'max-connection-per-server': getMaxConnectionPerServer(),
'max-download-limit': 0,
'max-overall-download-limit': 0,
'max-overall-upload-limit': 0,
'max-download-limit': 0,
'all-proxy': '',
'user-agent': 'Transmission/2.94'
'no-proxy': EMPTY_STRING,
'pause-metadata': false,
'pause': true,
'rpc-listen-port': 16800,
'rpc-secret': EMPTY_STRING,
'seed-ratio': 1,
'seed-time': 60,
'split': getMaxConnectionPerServer(),
'user-agent': CHROME_UA
}
/* eslint-enable quote-props */
})
this.fixSystemConfig()
}
initUserConfig () {
this.userConfig = new Store({
name: 'user',
// Schema need electron-store upgrade to 3.x.x,
// but it will cause the application build to fail.
// schema: {
// theme: {
// type: 'string',
// enum: ['auto', 'light', 'dark']
// }
// },
/* eslint-disable quote-props */
defaults: {
'resume-all-when-app-launched': false,
'task-notification': true,
'all-proxy-backup': EMPTY_STRING,
'auto-check-update': is.macOS(),
'auto-hide-window': false,
'auto-sync-tracker': true,
'enable-upnp': true,
'engine-max-connection-per-server': getMaxConnectionPerServer(),
'favorite-directories': [],
'hide-app-menu': is.windows() || is.linux(),
'history-directories': [],
'keep-seeding': false,
'keep-window-state': false,
'last-check-update-time': 0,
'last-sync-tracker-time': 0,
'locale': app.getLocale(),
'log-level': 'warn',
'new-task-show-downloading': true,
'auto-check-for-updates': false,
'no-confirm-before-delete-task': false,
'open-at-login': false,
'protocols': { 'magnet': true, 'thunder': false },
'resume-all-when-app-launched': false,
'run-mode': APP_RUN_MODE.STANDARD,
'show-progress-bar': true,
'task-notification': true,
'theme': APP_THEME.AUTO,
'tracker-source': [
NGOSANG_TRACKERS_BEST_IP_URL_CDN,
NGOSANG_TRACKERS_BEST_URL_CDN
],
'tray-theme': APP_THEME.AUTO,
'tray-speedometer': is.macOS(),
'update-channel': 'latest',
'use-proxy': false,
'all-proxy-backup': '',
'log-path': getLogPath(),
'session-path': getSessionPath(),
'locale': app.getLocale()
'window-state': {}
}
/* eslint-enable quote-props */
})
this.fixUserConfig()
}
fixSystemConfig () {
// Remove aria2c unrecognized options
const { others } = separateConfig(this.systemConfig.store)
if (!others) {
return
}
Object.keys(others).forEach(key => {
this.systemConfig.delete(key)
})
// Fix spawn ENAMETOOLONG on Windows
const tracker = reduceTrackerString(this.systemConfig.get('bt-tracker'))
this.setSystemConfig('bt-tracker', tracker)
}
fixUserConfig () {
// Fix the value of open-at-login when the user delete
// the Motrix self-starting item through startup management.
const openAtLogin = app.getLoginItemSettings(LOGIN_SETTING_OPTIONS).openAtLogin
if (this.getUserConfig('open-at-login') !== openAtLogin) {
this.setUserConfig('open-at-login', openAtLogin)
}
if (this.getUserConfig('tracker-source').length === 0) {
this.setUserConfig('tracker-source', [
NGOSANG_TRACKERS_BEST_IP_URL_CDN,
NGOSANG_TRACKERS_BEST_URL_CDN
])
}
}
getSystemConfig (key, defaultValue) {
+37 -1
View File
@@ -1,3 +1,39 @@
export default class Context {
import logger from './Logger'
import {
getEnginePath,
getAria2BinPath,
getAria2ConfPath,
getLogPath,
getSessionPath
} from '../utils'
const { platform, arch } = process
export default class Context {
constructor () {
this.init()
}
init () {
// The key of Context cannot be the same as that of userConfig and systemConfig.
this.context = {
platform: platform,
arch: arch,
'log-path': getLogPath(),
'session-path': getSessionPath(),
'engine-path': getEnginePath(platform, arch),
'aria2-bin-path': getAria2BinPath(platform, arch),
'aria2-conf-path': getAria2ConfPath(platform, arch)
}
logger.info('[Motrix] Context.init===>', this.context)
}
get (key) {
if (typeof key === 'undefined') {
return this.context
}
return this.context[key]
}
}
+9 -5
View File
@@ -1,23 +1,27 @@
import { powerSaveBlocker } from 'electron'
let psbId = null
import logger from './Logger'
let psbId
export default class EnergyManager {
startPowerSaveBlocker () {
logger.info('[Motrix] EnergyManager.startPowerSaveBlocker', psbId)
if (psbId && powerSaveBlocker.isStarted(psbId)) {
return
}
psbId = powerSaveBlocker.start('prevent-app-suspension')
console.log('startPowerSaveBlocker===>', psbId)
logger.info('[Motrix] start power save blocker:', psbId)
}
stopPowerSaveBlocker () {
if (!psbId || !powerSaveBlocker.isStarted(psbId)) {
logger.info('[Motrix] EnergyManager.stopPowerSaveBlocker', psbId)
if (typeof psbId === 'undefined' || !powerSaveBlocker.isStarted(psbId)) {
return
}
powerSaveBlocker.stop(psbId)
console.log('stopPowerSaveBlocker===>', psbId)
psbId = null
logger.info('[Motrix] stop power save blocker:', psbId)
psbId = undefined
}
}
+92 -87
View File
@@ -1,19 +1,21 @@
'use strict'
import { app } from 'electron'
import is from 'electron-is'
import { existsSync } from 'fs'
import { resolve, join } from 'path'
import forever from 'forever-monitor'
import { existsSync, writeFile, unlink } from 'fs'
import { spawn } from 'child_process'
import logger from './Logger'
import { getI18n } from '@/ui/Locale'
import { getI18n } from '../ui/Locale'
import {
getEngineBin,
getEnginePidPath,
getAria2BinPath,
getAria2ConfPath,
getSessionPath,
transformConfig
} from '../utils/index'
const { platform, arch } = process
export default class Engine {
// ChildProcess | null
static instance = null
constructor (options = {}) {
@@ -24,103 +26,106 @@ export default class Engine {
this.userConfig = options.userConfig
}
getStartSh () {
const { platform } = process
let basePath = resolve(app.getAppPath(), '..')
start () {
const pidPath = getEnginePidPath()
logger.info('[Motrix] Engie pid path:', pidPath)
if (this.instance) {
return
}
const binPath = this.getEngineBinPath()
const args = this.getStartArgs()
this.instance = spawn(binPath, args, {
windowsHide: false,
stdio: is.dev() ? 'pipe' : 'ignore'
})
const pid = this.instance.pid.toString()
this.writePidFile(pidPath, pid)
this.instance.once('close', function () {
try {
unlink(pidPath, function (err) {
if (err) {
logger.warn(`[Motrix] Unlink engine process pid file failed: ${err}`)
}
})
} catch (err) {
logger.warn(`[Motrix] Unlink engine process pid file failed: ${err}`)
}
})
if (is.dev()) {
basePath = resolve(__dirname, `../../../extra/${platform}`)
}
this.instance.stdout.on('data', function (data) {
logger.log('[Motrix] engine stdout===>', data.toString())
})
const binName = getEngineBin(platform)
if (!binName) {
throw new Error(this.i18n.t('app.engine-damaged-message'))
this.instance.stderr.on('data', function (data) {
logger.log('[Motrix] engine stderr===>', data.toString())
})
}
}
let binPath = join(basePath, `/engine/${binName}`)
const binIsExist = existsSync(binPath)
stop () {
logger.info('[Motrix] engine.stop.instance')
if (this.instance) {
this.instance.kill()
this.instance = null
}
}
writePidFile (pidPath, pid) {
writeFile(pidPath, pid, (err) => {
if (err) {
logger.error(`[Motrix] Write engine process pid failed: ${err}`)
}
})
}
getEngineBinPath () {
const result = getAria2BinPath(platform, arch)
const binIsExist = existsSync(result)
if (!binIsExist) {
logger.error('[Motrix] engine bin is not exist===>', binPath)
logger.error('[Motrix] engine bin is not exist:', result)
throw new Error(this.i18n.t('app.engine-missing-message'))
}
let confPath = join(basePath, '/engine/aria2.conf')
let sessionPath = this.userConfig['session-path'] || getSessionPath()
const sessionIsExist = existsSync(sessionPath)
let result = [`${binPath}`, `--conf-path=${confPath}`, `--save-session=${sessionPath}`]
if (sessionIsExist) {
result = [...result, `--input-file=${sessionPath}`]
}
const extraConfig = transformConfig(this.systemConfig)
result = [...result, ...extraConfig]
return result
}
start () {
const sh = this.getStartSh()
logger.info('[Motrix] Engine start sh===>', sh)
this.instance = forever.start(sh, {
max: 10,
parser: function (command, args) {
return {
command: command,
args: args
}
},
silent: !is.dev()
})
getStartArgs () {
const confPath = getAria2ConfPath(platform, arch)
const { child } = this.instance
logger.info('[Motrix] Engine pid===>', child.pid)
const sessionPath = getSessionPath()
const sessionIsExist = existsSync(sessionPath)
this.instance.on('error', (err) => {
logger.info(`[Motrix] Engine error===> ${err}`)
})
this.instance.on('start', function (process, data) {
logger.info(`[Motrix] Engine started===>`)
})
this.instance.on('stop', function (process) {
logger.info(`[Motrix] Engine stopped===>`)
})
this.instance.on('restart', function (forever) {
logger.info(`[Motrix] Engine exit===>`)
})
this.instance.on('exit:code', function (code) {
logger.info(`[Motrix] Engine exit===> ${code}`)
})
// this.instance.on('stderr', (data) => {
// logger.info(`[Motrix] Engine stderr===> ${data}`)
// })
}
stop () {
const { pid } = this.instance.child
try {
logger.info('[Motrix] Engine stopping===>')
this.instance.stop()
} catch (err) {
logger.error('[Motrix] Engine stop fail===>', err.message)
this.forceStop(pid)
} finally {
let result = [`--conf-path=${confPath}`, `--save-session=${sessionPath}`]
if (sessionIsExist) {
result = [...result, `--input-file=${sessionPath}`]
}
const extraConfig = {
...this.systemConfig
}
const keepSeeding = this.userConfig['keep-seeding']
const seedRatio = this.systemConfig['seed-ratio']
if (keepSeeding || seedRatio === 0) {
extraConfig['seed-ratio'] = 0
delete extraConfig['seed-time']
}
console.log('extraConfig===>', extraConfig)
const extra = transformConfig(extraConfig)
result = [...result, ...extra]
return result
}
forceStop (pid) {
isRunning (pid) {
try {
if (pid) {
process.kill(pid)
}
} catch (err) {
logger.warn('[Motrix] Engine forceStop fail===>', err)
return process.kill(pid, 0)
} catch (e) {
return e.code === 'EPERM'
}
}
+70
View File
@@ -0,0 +1,70 @@
'use strict'
import { Aria2 } from '@shared/aria2'
import logger from './Logger'
import {
compactUndefined,
formatOptionsForEngine
} from '@shared/utils'
import {
ENGINE_RPC_HOST,
ENGINE_RPC_PORT,
EMPTY_STRING
} from '@shared/constants'
const defaults = {
host: ENGINE_RPC_HOST,
port: ENGINE_RPC_PORT,
secret: EMPTY_STRING
}
export default class EngineClient {
static instance = null
static client = null
constructor (options = {}) {
this.options = {
...defaults,
...options
}
this.init()
}
init () {
this.connect()
}
connect () {
logger.info('[Motrix] main engine client connect', this.options)
const { host, port, secret } = this.options
this.client = new Aria2({
host,
port,
secret
})
}
async call (method, ...args) {
return this.client.call(method, ...args).catch((err) => {
logger.warn('[Motrix] call client fail:', err.message)
})
}
async changeGlobalOption (options) {
logger.info('[Motrix] change engine global option:', options)
const args = formatOptionsForEngine(options)
return this.call('changeGlobalOption', args)
}
async shutdown (options = {}) {
const { force = false } = options
const { secret } = this.options
const method = force ? 'forceShutdown' : 'shutdown'
const args = compactUndefined([secret])
return this.call(method, ...args)
}
}
+1
View File
@@ -1,5 +1,6 @@
import { app, dialog } from 'electron'
import is from 'electron-is'
import logger from './Logger'
const defaults = {
+2 -2
View File
@@ -1,8 +1,8 @@
import is from 'electron-is'
import logger from 'electron-log'
logger.transports.file.level = is.production() ? 'warn' : 'info'
logger.info('Logger init')
logger.transports.file.level = is.production() ? 'info' : 'silly'
logger.info('[Motrix] Logger init')
logger.warn('[Motrix] Logger init')
export default logger
+65 -13
View File
@@ -1,31 +1,85 @@
import { EventEmitter } from 'events'
import { app } from 'electron'
import is from 'electron-is'
import { parse } from 'querystring'
import logger from './Logger'
import protocolMap from '../configs/protocol'
import { ADD_TASK_TYPE } from '@shared/constants'
export default class ProtocolManager extends EventEmitter {
constructor (options = {}) {
super()
this.options = options
// package.json:build.protocols[].schemes[]
// options.protocols: { 'magnet': true, 'thunder': false }
this.protocols = {
mo: true,
motrix: true,
...options.protocols
}
this.init()
}
init () {
// package.json:build.mac.protocols[].schemes[]
if (!app.isDefaultProtocolClient('mo')) {
app.setAsDefaultProtocolClient('mo')
}
if (!app.isDefaultProtocolClient('motrix')) {
app.setAsDefaultProtocolClient('motrix')
const { protocols } = this
this.setup(protocols)
}
setup (protocols = {}) {
if (is.dev() || is.mas()) {
return
}
Object.keys(protocols).forEach((protocol) => {
const enabled = protocols[protocol]
if (enabled) {
if (!app.isDefaultProtocolClient(protocol)) {
app.setAsDefaultProtocolClient(protocol)
}
} else {
app.removeAsDefaultProtocolClient(protocol)
}
})
}
handle (url) {
logger.info(`[Motrix] protocol url: ${url}`)
if (
url.toLowerCase().startsWith('ftp:') ||
url.toLowerCase().startsWith('http:') ||
url.toLowerCase().startsWith('https:') ||
url.toLowerCase().startsWith('magnet:') ||
url.toLowerCase().startsWith('thunder:')
) {
return this.handleResourceProtocol(url)
}
if (
url.toLowerCase().startsWith('mo:') ||
url.toLowerCase().startsWith('motrix:')
) {
return this.handleMoProtocol(url)
}
}
handleResourceProtocol (url) {
if (!url) {
return
}
global.application.sendCommandToAll('application:new-task', {
type: ADD_TASK_TYPE.URI,
uri: url
})
}
handleMoProtocol (url) {
const parsed = new URL(url)
const { host } = parsed
const { host, search } = parsed
logger.info('[Motrix] protocol parsed:', parsed, host)
const command = protocolMap[host]
@@ -33,10 +87,8 @@ export default class ProtocolManager extends EventEmitter {
return
}
// @TODO 没想明白怎么传参数好
// 如果按顺序传递,那 url 的 query string 就要求有序的了
// const query = queryString.parse(parsed.query)
const args = []
global.application.sendCommandToAll(command, ...args)
const query = search.startsWith('?') ? search.replace('?', '') : search
const args = parse(query)
global.application.sendCommandToAll(command, args)
}
}
+99
View File
@@ -0,0 +1,99 @@
import NatAPI from '@motrix/nat-api'
import logger from './Logger'
let client = null
const mappingStatus = {}
export default class UPnPManager {
constructor (options = {}) {
this.options = {
...options
}
}
init () {
if (client) {
return
}
client = new NatAPI({
autoUpdate: true
})
}
map (port) {
this.init()
return new Promise((resolve, reject) => {
logger.info('[Motrix] UPnPManager port mapping: ', port)
if (!port) {
reject(new Error('[Motrix] port was not specified'))
return
}
try {
client.map(port, (err) => {
if (err) {
logger.warn(`[Motrix] UPnPManager map ${port} failed, error: `, err.message)
reject(err.message)
return
}
mappingStatus[port] = true
logger.info(`[Motrix] UPnPManager port ${port} mapping succeeded`)
resolve()
})
} catch (err) {
reject(err.message)
}
})
}
unmap (port) {
this.init()
return new Promise((resolve, reject) => {
logger.info('[Motrix] UPnPManager port unmapping: ', port)
if (!port) {
reject(new Error('[Motrix] port was not specified'))
return
}
if (!mappingStatus[port]) {
resolve()
return
}
try {
client.unmap(port, (err) => {
if (err) {
logger.warn(`[Motrix] UPnPManager unmap ${port} failed, error: `, err)
reject(err.message)
return
}
logger.info(`[Motrix] UPnPManager port ${port} unmapping succeeded`)
mappingStatus[port] = false
resolve()
})
} catch (err) {
reject(err.message)
}
})
}
closeClient () {
if (!client) {
return
}
try {
client.destroy(() => {
client = null
})
} catch (err) {
logger.warn('[Motrix] close UPnP client fail', err)
}
}
}
+42 -13
View File
@@ -1,10 +1,11 @@
import { EventEmitter } from 'events'
import { resolve } from 'path'
import { dialog } from 'electron'
import is from 'electron-is'
import { autoUpdater } from 'electron-updater'
import { resolve } from 'path'
import logger from './Logger'
import { getI18n } from '@/ui/Locale'
import { getI18n } from '../ui/Locale'
if (is.dev()) {
autoUpdater.updateConfigPath = resolve(__dirname, '../../../app-update.yml')
@@ -16,9 +17,15 @@ export default class UpdateManager extends EventEmitter {
this.options = options
this.i18n = getI18n()
this.isChecking = false
this.updater = autoUpdater
this.updater.autoDownload = false
this.updater.autoInstallOnAppQuit = false
this.updater.logger = logger
this.autoCheckData = {
checkEnable: this.options.autoCheck,
userCheck: false
}
this.init()
}
@@ -35,14 +42,22 @@ export default class UpdateManager extends EventEmitter {
this.updater.on('update-not-available', this.updateNotAvailable.bind(this))
this.updater.on('download-progress', this.updateDownloadProgress.bind(this))
this.updater.on('update-downloaded', this.updateDownloaded.bind(this))
this.updater.on('update-cancelled', this.updateCancelled.bind(this))
this.updater.on('error', this.updateError.bind(this))
if (this.autoCheckData.checkEnable && !this.isChecking) {
this.autoCheckData.userCheck = false
this.updater.checkForUpdates()
}
}
check () {
this.autoCheckData.userCheck = true
this.updater.checkForUpdates()
}
checkingForUpdate () {
this.isChecking = true
this.emit('checking')
}
@@ -54,19 +69,24 @@ export default class UpdateManager extends EventEmitter {
message: this.i18n.t('app.update-available-message'),
buttons: [this.i18n.t('app.yes'), this.i18n.t('app.no')],
cancelId: 1
}, (buttonIndex) => {
if (buttonIndex === 0) {
}).then(({ response }) => {
if (response === 0) {
this.updater.downloadUpdate()
} else {
this.emit('update-cancelled', info)
}
})
}
updateNotAvailable (event, info) {
this.isChecking = false
this.emit('update-not-available', info)
dialog.showMessageBox({
title: this.i18n.t('app.check-for-updates-title'),
message: this.i18n.t('app.update-not-available-message')
})
if (this.autoCheckData.userCheck) {
dialog.showMessageBox({
title: this.i18n.t('app.check-for-updates-title'),
message: this.i18n.t('app.update-not-available-message')
})
}
}
/**
@@ -88,18 +108,27 @@ export default class UpdateManager extends EventEmitter {
dialog.showMessageBox({
title: this.i18n.t('app.check-for-updates-title'),
message: this.i18n.t('app.update-downloaded-message')
}, () => {
}).then(_ => {
this.isChecking = false
this.emit('will-updated')
setImmediate(() => {
setTimeout(() => {
this.updater.quitAndInstall()
})
}, 200)
})
}
updateCancelled () {
this.isChecking = false
}
updateError (event, error) {
this.isChecking = false
this.emit('update-error', error)
const msg = error == null ? this.i18n.t('update-error-message') : (error.stack || error).toString()
const msg = (error == null)
? this.i18n.t('app.update-error-message')
: (error.stack || error).toString()
this.updater.logger.warn(`[Motrix] update-error: ${msg}`)
dialog.showErrorBox(msg)
dialog.showErrorBox('Error', msg)
}
}
+1 -7
View File
@@ -7,14 +7,8 @@
/* eslint-disable */
// Install `electron-debug` with `devtron`
require('electron-debug')({
// devToolsMode: 'right',
showDevTools: true
})
// Install `vue-devtools`
require('electron').app.on('ready', () => {
require('electron').app.whenReady().then(() => {
let installExtension = require('electron-devtools-installer')
installExtension.default(installExtension.VUEJS_DEVTOOLS)
.then(() => {})
+8
View File
@@ -1,8 +1,16 @@
import { app } from 'electron'
import is from 'electron-is'
import { initialize } from '@electron/remote/main'
import Launcher from './Launcher'
/**
* initialize the main-process side of the remote module
*/
initialize()
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true'
if (process.env.NODE_ENV !== 'development') {
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}
+6 -4
View File
@@ -3,7 +3,7 @@
{
"id": "menu.app",
"submenu": [
{ "id": "app.about", "command": "application:about", "command-before": "application:show,index" },
{ "id": "app.about", "command": "application:about", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.preferences", "command": "application:preferences" },
{ "id": "app.check-for-updates", "command": "application:check-for-updates" },
@@ -17,10 +17,11 @@
{
"id": "menu.task",
"submenu": [
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show,index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-arg": "torrent", "command-after": "application:show,index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show,index" },
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show?page=index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-after": "application:show?page=index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.task-list", "command": "application:task-list" },
{ "id": "task.pause-task", "command": "application:pause-task" },
{ "id": "task.resume-task", "command": "application:resume-task" },
{ "id": "task.delete-task", "command": "application:delete-task" },
@@ -29,6 +30,7 @@
{ "type": "separator" },
{ "id": "task.pause-all-task", "command": "application:pause-all-task" },
{ "id": "task.resume-all-task", "command": "application:resume-all-task" },
{ "id": "task.select-all-task", "command": "application:select-all-task" },
{ "type": "separator" },
{ "id": "task.clear-recent-tasks", "command": "application:clear-recent-tasks" }
]
+8 -6
View File
@@ -3,11 +3,11 @@
{
"id": "menu.file",
"submenu": [
{ "id": "app.about", "command": "application:about", "command-before": "application:show,index" },
{ "id": "app.about", "command": "application:about", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.preferences", "command": "application:preferences" },
{ "id": "app.check-for-updates", "command": "application:check-for-updates" },
{ "id": "app.show", "command": "application:show", "command-arg": "index" },
{ "id": "app.show", "command": "application:show", "command-arg": { "page": "index" } },
{ "type": "separator" },
{ "id": "app.quit", "role": "quit" }
]
@@ -15,10 +15,11 @@
{
"id": "menu.task",
"submenu": [
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show,index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-arg": "torrent", "command-after": "application:show,index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show,index" },
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show?page=index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-after": "application:show?page=index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.task-list", "command": "application:task-list" },
{ "id": "task.pause-task", "command": "application:pause-task" },
{ "id": "task.resume-task", "command": "application:resume-task" },
{ "id": "task.delete-task", "command": "application:delete-task" },
@@ -26,7 +27,8 @@
{ "id": "task.move-task-down", "command": "application:move-task-down" },
{ "type": "separator" },
{ "id": "task.pause-all-task", "command": "application:pause-all-task" },
{ "id": "task.resume-all-task", "command": "application:resume-all-task" }
{ "id": "task.resume-all-task", "command": "application:resume-all-task" },
{ "id": "task.select-all-task", "command": "application:select-all-task" }
]
},
{
+5 -5
View File
@@ -1,6 +1,6 @@
[
{
"type": "button", "icon": "new-task", "id": "task.new-task", "command": "application:new-task", "command-arg": "uri", "command-after": "application:show,index"
"type": "button", "icon": "new-task", "id": "task.new-task", "command": "application:new-task", "command-after": "application:show?page=index"
},
{
"type": "spacer", "size": "small"
@@ -10,13 +10,13 @@
"id": "task.task-list",
"items": [
{
"type": "button", "icon": "task-active", "command": "application:task-list", "command-arg": "active"
"type": "button", "icon": "task-active", "command": "application:task-list", "command-arg": { "status": "active" }
},
{
"type": "button", "icon": "task-waiting", "command": "application:task-list", "command-arg": "waiting"
"type": "button", "icon": "task-waiting", "command": "application:task-list", "command-arg": { "status": "waiting" }
},
{
"type": "button", "icon": "task-stopped", "command": "application:task-list", "command-arg": "stopped"
"type": "button", "icon": "task-stopped", "command": "application:task-list", "command-arg": { "status": "stopped" }
}
]
},
@@ -30,6 +30,6 @@
"type": "spacer", "size": "small"
},
{
"type": "button", "icon": "about", "id": "app.about", "command": "application:about", "command-before": "application:show,index"
"type": "button", "icon": "about", "id": "app.about", "command": "application:about", "command-before": "application:show?page=index"
}
]
+8 -6
View File
@@ -1,11 +1,13 @@
[
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show,index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-arg": "torrent", "command-after": "application:show,index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show,index" },
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show?page=index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-arg": { "type": "torrent" }, "command-after": "application:show?page=index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.show", "command": "application:show", "command-arg": "index" },
{ "id": "app.show", "command": "application:show", "command-arg": { "page": "index" } },
{ "id": "help.manual", "command": "help:manual" },
{ "id": "app.check-for-updates", "command": "application:check-for-updates" },
{ "type": "separator" },
{ "id": "app.preferences", "command": "application:preferences", "command-before": "application:show,index" },
{ "id": "app.quit", "role": "quit" }
{ "id": "app.task-list", "command": "application:task-list", "command-before": "application:show?page=index" },
{ "id": "app.preferences", "command": "application:preferences", "command-before": "application:show?page=index" },
{ "id": "app.quit", "command": "application:quit" }
]
+7 -5
View File
@@ -3,11 +3,11 @@
{
"id": "menu.file",
"submenu": [
{ "id": "app.about", "command": "application:about", "command-before": "application:show,index" },
{ "id": "app.about", "command": "application:about", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.preferences", "command": "application:preferences" },
{ "id": "app.check-for-updates", "command": "application:check-for-updates" },
{ "id": "app.show", "command": "application:show", "command-arg": "index" },
{ "id": "app.show", "command": "application:show", "command-arg": { "page": "index" } },
{ "type": "separator" },
{ "id": "app.quit", "role": "quit" }
]
@@ -15,10 +15,11 @@
{
"id": "menu.task",
"submenu": [
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show,index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-arg": "torrent", "command-after": "application:show,index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show,index" },
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show?page=index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-after": "application:show?page=index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show?page=index" },
{ "type": "separator" },
{ "id": "app.task-list", "command": "application:task-list" },
{ "id": "task.pause-task", "command": "application:pause-task" },
{ "id": "task.resume-task", "command": "application:resume-task" },
{ "id": "task.delete-task", "command": "application:delete-task" },
@@ -27,6 +28,7 @@
{ "type": "separator" },
{ "id": "task.pause-all-task", "command": "application:pause-all-task" },
{ "id": "task.resume-all-task", "command": "application:resume-all-task" },
{ "id": "task.select-all-task", "command": "application:select-all-task" },
{ "type": "separator" },
{ "id": "task.clear-recent-tasks", "command": "application:clear-recent-tasks" }
]
+64
View File
@@ -0,0 +1,64 @@
import is from 'electron-is'
import { EventEmitter } from 'events'
import { app } from 'electron'
import { bytesToSize } from '@shared/utils'
import {
APP_RUN_MODE
} from '@shared/constants'
const enabled = is.macOS()
export default class DockManager extends EventEmitter {
constructor (options) {
super()
this.options = options
const { runMode } = this.options
if (runMode === APP_RUN_MODE.TRAY) {
this.hide()
}
}
show = enabled
? () => {
if (app.dock.isVisible()) {
return
}
return app.dock.show()
}
: () => {}
hide = enabled
? () => {
if (!app.dock.isVisible()) {
return
}
app.dock.hide()
}
: () => {}
// macOS setBadge not working
// @see https://github.com/electron/electron/issues/25745#issuecomment-702826143
setBadge = enabled
? (text) => {
app.dock.setBadge(text)
}
: (text) => {}
handleSpeedChange = enabled
? (speed) => {
const { downloadSpeed } = speed
const text = downloadSpeed > 0 ? `${bytesToSize(downloadSpeed)}/s` : ''
this.setBadge(text)
}
: (text) => {}
openDock = enabled
? (path) => {
app.dock.downloadFinished(path)
}
: (path) => {}
}
+10 -9
View File
@@ -1,12 +1,13 @@
import { EventEmitter } from 'events'
import { Menu } from 'electron'
import keymap from '@shared/keymap'
import {
translateTemplate,
flattenMenuItems,
updateStates
} from '../utils/menu'
import keymap from '@shared/keymap'
import { getI18n } from '@/ui/Locale'
import { getI18n } from '../ui/Locale'
export default class MenuManager extends EventEmitter {
constructor (options) {
@@ -23,13 +24,13 @@ export default class MenuManager extends EventEmitter {
}
load () {
let template = require(`../menus/${process.platform}.json`)
this.template = template['menu']
const template = require(`../menus/${process.platform}.json`)
this.template = template.menu
}
build () {
const keystrokesByCommand = {}
for (let item in this.keymap) {
for (const item in this.keymap) {
keystrokesByCommand[this.keymap[item]] = item
}
@@ -46,11 +47,11 @@ export default class MenuManager extends EventEmitter {
this.items = flattenMenuItems(menu)
}
rebuild () {
handleLocaleChange (locale) {
this.setup()
}
updateStates (visibleStates, enabledStates, checkedStates) {
updateMenuStates (visibleStates, enabledStates, checkedStates) {
updateStates(this.items, visibleStates, enabledStates, checkedStates)
}
@@ -58,13 +59,13 @@ export default class MenuManager extends EventEmitter {
const visibleStates = {
[id]: flag
}
this.updateStates(visibleStates, null, null)
this.updateMenuStates(visibleStates, null, null)
}
updateMenuItemEnabledState (id, flag) {
const enabledStates = {
[id]: flag
}
this.updateStates(null, enabledStates, null)
this.updateMenuStates(null, enabledStates, null)
}
}
+39
View File
@@ -0,0 +1,39 @@
import { EventEmitter } from 'events'
import { nativeTheme } from 'electron'
import { APP_THEME } from '@shared/constants'
import logger from '../core/Logger'
import { getSystemTheme } from '../utils'
export default class ThemeManager extends EventEmitter {
constructor (options = {}) {
super()
this.options = options
this.init()
}
init () {
this.systemTheme = getSystemTheme()
this.handleEvents()
}
getSystemTheme () {
return this.systemTheme
}
handleEvents () {
nativeTheme.on('updated', () => {
const theme = getSystemTheme()
this.systemTheme = theme
logger.info('[Motrix] nativeTheme updated===>', theme)
this.emit('system-theme-change', theme)
})
}
updateSystemTheme (theme) {
theme = theme === APP_THEME.AUTO ? 'system' : theme
nativeTheme.themeSource = theme
}
}
+28 -25
View File
@@ -1,6 +1,7 @@
import { EventEmitter } from 'events'
import { join } from 'path'
import { TouchBar, nativeImage } from 'electron'
import { handleCommand } from '../utils/menu'
import logger from '../core/Logger'
@@ -15,7 +16,7 @@ export default class TouchBarManager extends EventEmitter {
}
load () {
this.template = require(`../menus/touchBar.json`)
this.template = require('../menus/touchBar.json')
}
getClickFn (item) {
@@ -41,30 +42,32 @@ export default class TouchBarManager extends EventEmitter {
const { label, backgroundColor, textColor, size } = options
switch (type) {
case 'button':
const icon = this.getIconImage(options.icon)
const click = this.getClickFn(options)
result = new TouchBarButton({
label,
backgroundColor,
icon,
click
case 'button':
result = new TouchBarButton({
label,
backgroundColor,
icon: this.getIconImage(options.icon),
click: this.getClickFn(options)
})
break
case 'label':
result = new TouchBarLabel({
label,
textColor
})
break
case 'spacer':
result = new TouchBarSpacer({ size })
break
case 'group':
result = new TouchBarGroup({
items: new TouchBar({
items: options.items
})
break
case 'label':
result = new TouchBarLabel({
label,
textColor
})
break
case 'spacer':
result = new TouchBarSpacer({ size })
break
case 'group':
result = new TouchBarGroup({ items: options.items })
break
default:
result = null
})
break
default:
result = null
}
return result
@@ -90,7 +93,7 @@ export default class TouchBarManager extends EventEmitter {
if (!bar) {
try {
const items = this.build(this.template)
bar = new TouchBar(items)
bar = new TouchBar({ items })
this.bars[page] = bar
} catch (e) {
logger.info('getTouchBarByPage fail', e)
+313 -41
View File
@@ -1,41 +1,133 @@
import { EventEmitter } from 'events'
import { join } from 'path'
import { Tray, Menu } from 'electron'
import { Tray, Menu, nativeImage } from 'electron'
import is from 'electron-is'
import { translateTemplate } from '../utils/menu'
import { getI18n } from '@/ui/Locale'
import { APP_RUN_MODE, APP_THEME } from '@shared/constants'
import { getInverseTheme } from '@shared/utils'
import logger from '../core/Logger'
import { getI18n } from './Locale'
import {
translateTemplate,
flattenMenuItems,
updateStates
} from '../utils/menu'
import { convertArrayBufferToBuffer } from '../utils/index'
let tray = null
const { platform } = process
export default class TrayManager extends EventEmitter {
constructor (options = {}) {
super()
this.options = options
this.theme = options.theme || APP_THEME.AUTO
this.systemTheme = options.systemTheme
this.inverseSystemTheme = getInverseTheme(this.systemTheme)
this.macOS = platform === 'darwin'
this.speedometer = options.speedometer
this.runMode = options.runMode
this.i18n = getI18n()
this.menu = null
this.cache = {}
this.uploadSpeed = 0
this.downloadSpeed = 0
this.status = false
this.focused = false
this.initialized = false
this.load()
this.init()
this.setup()
this.handleEvents()
}
load () {
this.template = require(`../menus/tray.json`)
init () {
if (tray || this.initialized || this.runMode === APP_RUN_MODE.HIDE_TRAY) {
return
}
if (is.macOS()) {
this.normalIcon = join(__static, './mo-tray-normal.png')
this.activeIcon = join(__static, './mo-tray-active.png')
} else {
this.normalIcon = join(__static, './mo-tray-colorful-normal.png')
this.activeIcon = join(__static, './mo-tray-colorful-active.png')
this.loadTemplate()
this.loadImages()
this.initTray()
this.setupMenu()
this.bindEvents()
this.initialized = true
}
loadTemplate () {
this.template = require('../menus/tray.json')
}
loadImages () {
switch (platform) {
case 'darwin':
this.loadImagesForMacOS()
break
case 'win32':
this.loadImagesForWindows()
break
case 'linux':
this.loadImagesForLinux()
break
default:
this.loadImagesForDefault()
break
}
}
build () {
loadImagesForMacOS () {
this.normalIcon = this.getFromCacheOrCreateImage('mo-tray-light-normal.png')
}
loadImagesForWindows () {
this.normalIcon = this.getFromCacheOrCreateImage('mo-tray-colorful-normal.png')
this.activeIcon = this.getFromCacheOrCreateImage('mo-tray-colorful-active.png')
}
loadImagesForLinux () {
const { theme } = this
if (theme === APP_THEME.AUTO) {
this.normalIcon = this.getFromCacheOrCreateImage('mo-tray-dark-normal.png')
this.activeIcon = this.getFromCacheOrCreateImage('mo-tray-dark-active.png')
} else {
this.normalIcon = this.getFromCacheOrCreateImage(`mo-tray-${theme}-normal.png`)
this.activeIcon = this.getFromCacheOrCreateImage(`mo-tray-${theme}-active.png`)
}
}
loadImagesForDefault () {
this.normalIcon = this.getFromCacheOrCreateImage('mo-tray-light-normal.png')
this.activeIcon = this.getFromCacheOrCreateImage('mo-tray-light-active.png')
}
getFromCacheOrCreateImage (key) {
let file = this.getCache(key)
if (file) {
return file
}
file = nativeImage.createFromPath(join(__static, `./${key}`))
file.setTemplateImage(this.macOS)
this.setCache(key, file)
return file
}
getCache (key) {
return this.cache[key]
}
setCache (key, value) {
this.cache[key] = value
}
buildMenu () {
const keystrokesByCommand = {}
for (let item in this.keymap) {
for (const item in this.keymap) {
keystrokesByCommand[this.keymap[item]] = item
}
@@ -43,55 +135,235 @@ export default class TrayManager extends EventEmitter {
const template = JSON.parse(JSON.stringify(this.template))
const tpl = translateTemplate(template, keystrokesByCommand, this.i18n)
this.menu = Menu.buildFromTemplate(tpl)
this.items = flattenMenuItems(this.menu)
}
setup () {
this.build()
setupMenu () {
this.buildMenu()
/**
* Linux requires setContextMenu to be called
* in order for the context menu to populate correctly
*/
if (process.platform === 'linux') {
tray.setContextMenu(this.menu)
this.updateContextMenu()
}
initTray () {
const { icon } = this.getIcons()
tray = new Tray(icon)
// tray.setPressedImage(inverseIcon)
if (!this.macOS) {
tray.setToolTip('Motrix')
}
}
init () {
tray = new Tray(this.normalIcon)
tray.setToolTip('Motrix')
bindEvents () {
// All OS
tray.on('click', this.handleTrayClick)
// macOS, Windows
// tray.on('double-click', this.handleTrayDbClick)
tray.on('right-click', this.handleTrayRightClick)
tray.on('mouse-down', this.handleTrayMouseDown)
tray.on('mouse-up', this.handleTrayMouseUp)
// macOS only
tray.setIgnoreDoubleClickEvents(true)
tray.on('drop-files', this.handleTrayDropFiles)
tray.on('drop-text', this.handleTrayDropText)
}
handleEvents () {
tray.on('click', this.handleTrayClick)
tray.on('double-click', this.handleTrayDbClick)
tray.on('right-click', this.handleTrayRightClick)
unbindEvents () {
// All OS
tray.removeListener('click', this.handleTrayClick)
tray.on('drop-files', this.handleTrayDropFile)
// macOS, Windows
tray.removeListener('right-click', this.handleTrayRightClick)
tray.removeListener('mouse-down', this.handleTrayMouseDown)
tray.removeListener('mouse-up', this.handleTrayMouseUp)
// macOS only
tray.removeListener('drop-files', this.handleTrayDropFiles)
tray.removeListener('drop-text', this.handleTrayDropText)
}
handleTrayClick = (event) => {
event.preventDefault()
global.application.toggle()
}
handleTrayDbClick = (event) => {
event.preventDefault()
global.application.show()
}
handleTrayRightClick = (event) => {
event.preventDefault()
tray.popUpContextMenu(this.menu)
}
handleTrayDropFile = (event, files) => {
global.application.show()
global.application.handleFile(files[0])
handleTrayMouseDown = (event) => {
this.focused = true
this.emit('mouse-down', {
focused: true,
theme: this.inverseSystemTheme
})
this.renderTray()
}
updateStatus (status) {
const icon = status ? this.activeIcon : this.normalIcon
handleTrayMouseUp = (event) => {
this.focused = false
this.emit('mouse-up', {
focused: false,
theme: this.theme
})
this.renderTray()
}
handleTrayDropFiles = (event, files) => {
this.emit('drop-files', files)
}
handleTrayDropText = (event, text) => {
this.emit('drop-text', text)
}
toggleSpeedometer (enabled) {
this.speedometer = enabled
}
async renderTray () {
if (!tray || this.speedometer) {
return
}
const { icon } = this.getIcons()
tray.setImage(icon)
// tray.setPressedImage(inverseIcon)
this.updateContextMenu()
}
getIcons () {
if (this.macOS) {
return { icon: this.normalIcon }
}
const { focused, status, systemTheme } = this
const icon = status ? this.activeIcon : this.normalIcon
if (systemTheme === APP_THEME.DARK) {
return {
icon
}
}
const inverseIcon = status ? this.inverseActiveIcon : this.inverseNormalIcon
return {
icon: focused ? inverseIcon : icon
// inverseIcon: focused ? icon : inverseIcon
}
}
updateContextMenu () {
/**
* Linux requires setContextMenu to be called
* in order for the context menu to populate correctly
*/
if (!tray || process.platform !== 'linux') {
return
}
tray.setContextMenu(this.menu)
}
updateMenuStates (visibleStates, enabledStates, checkedStates) {
updateStates(this.items, visibleStates, enabledStates, checkedStates)
this.updateContextMenu()
}
updateMenuItemVisibleState (id, flag) {
const visibleStates = {
[id]: flag
}
this.updateMenuStates(visibleStates, null, null)
}
updateMenuItemEnabledState (id, flag) {
const enabledStates = {
[id]: flag
}
this.updateMenuStates(null, enabledStates, null)
}
handleLocaleChange (locale) {
this.setupMenu()
}
handleRunModeChange (mode) {
this.runMode = mode
if (mode === APP_RUN_MODE.HIDE_TRAY) {
this.destroy()
} else {
this.init()
}
}
handleSpeedometerEnableChange (enabled) {
this.toggleSpeedometer(enabled)
this.renderTray()
}
handleSystemThemeChange (systemTheme = APP_THEME.LIGHT) {
if (!is.macOS()) {
return
}
this.systemTheme = systemTheme
this.inverseSystemTheme = getInverseTheme(systemTheme)
this.loadImages()
this.renderTray()
}
handleDownloadStatusChange (status) {
this.status = status
this.renderTray()
}
async handleSpeedChange ({ uploadSpeed, downloadSpeed }) {
if (!this.speedometer) {
return
}
this.uploadSpeed = uploadSpeed
this.downloadSpeed = downloadSpeed
await this.renderTray()
}
async updateTrayByImage (ab) {
if (!tray) {
return
}
const buffer = convertArrayBufferToBuffer(ab)
const image = nativeImage.createFromBuffer(buffer, {
scaleFactor: 2
})
image.setTemplateImage(this.macOS)
tray.setImage(image)
}
destroy () {
logger.info('[Motrix] TrayManager.destroy')
if (tray) {
this.unbindEvents()
}
tray.destroy()
tray = null
this.initialized = false
}
}
+129 -25
View File
@@ -1,18 +1,35 @@
import { join } from 'path'
import { EventEmitter } from 'events'
import { app, shell, BrowserWindow } from 'electron'
import { debounce } from 'lodash'
import { app, shell, screen, BrowserWindow } from 'electron'
import is from 'electron-is'
import pageConfig from '../configs/page'
import logger from '../core/Logger'
const defaultBrowserOptions = {
const baseBrowserOptions = {
titleBarStyle: 'hiddenInset',
useContentSize: true,
show: false,
width: 1024,
height: 768
height: 768,
backgroundColor: '#fff',
webPreferences: {
nodeIntegration: true
}
}
// fix: BrowserWindow rendering bug under linux
const defaultBrowserOptions = is.macOS()
? {
...baseBrowserOptions,
vibrancy: 'ultra-dark',
visualEffectState: 'active',
backgroundColor: '#00000000'
}
: {
...baseBrowserOptions
}
export default class WindowManager extends EventEmitter {
constructor (options = {}) {
super()
@@ -38,6 +55,13 @@ export default class WindowManager extends EventEmitter {
result.attrs.frame = false
}
// Optimized for small screen users
const { width, height } = screen.getPrimaryDisplay().workAreaSize
const widthScale = width >= 1280 ? 1 : 0.875
const heightScale = height >= 800 ? 1 : 0.875
result.attrs.width *= widthScale
result.attrs.height *= heightScale
// fix AppImage Dock Icon Missing
// https://github.com/AppImage/AppImageKit/wiki/Bundling-Electron-apps
if (is.linux()) {
@@ -47,41 +71,82 @@ export default class WindowManager extends EventEmitter {
return result
}
openWindow (page) {
const options = this.getPageOptions(page)
getPageBounds (page) {
const enabled = this.userConfig['keep-window-state']
const windowStateMap = this.userConfig['window-state'] || {}
let result = null
if (enabled) {
result = windowStateMap[page]
}
return result
}
openWindow (page, options = {}) {
const pageOptions = this.getPageOptions(page)
const { hidden } = options
const autoHideWindow = this.userConfig['auto-hide-window']
let window = this.windows[page] || null
if (window) {
window.restore()
window.show()
window.focus()
return window
}
window = new BrowserWindow({
...defaultBrowserOptions,
...options.attrs
...pageOptions.attrs,
webPreferences: {
enableRemoteModule: true,
contextIsolation: false,
nodeIntegration: true,
nodeIntegrationInWorker: true
}
})
window.webContents.on('new-window', (e, url) => {
e.preventDefault()
const bounds = this.getPageBounds(page)
if (bounds) {
window.setBounds(bounds)
}
if (is.dev() && pageOptions.openDevTools) {
window.webContents.openDevTools()
}
window.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url)
return { action: 'deny' }
})
if (options.url) {
window.loadURL(options.url)
if (pageOptions.url) {
window.loadURL(pageOptions.url)
}
window.once('ready-to-show', () => {
window.show()
if (!hidden) {
window.show()
}
})
if (options.bindCloseToHide) {
this.bindCloseToHide(page, window)
}
window.on('enter-full-screen', () => {
this.emit('enter-full-screen', window)
})
window.on('leave-full-screen', () => {
this.emit('leave-full-screen', window)
})
this.handleWindowState(page, window)
this.handleWindowClose(pageOptions, page, window)
this.bindAfterClosed(page, window)
this.addWindow(page, window)
if (autoHideWindow) {
this.handleWindowBlur()
}
return window
}
@@ -104,6 +169,9 @@ export default class WindowManager extends EventEmitter {
destroyWindow (page) {
const win = this.getWindow(page)
this.removeWindow(page)
win.removeListener('closed')
win.removeListener('move')
win.removeListener('resize')
win.destroy()
}
@@ -117,26 +185,49 @@ export default class WindowManager extends EventEmitter {
})
}
bindCloseToHide (page, window) {
handleWindowState (page, window) {
window.on('resize', debounce(() => {
const bounds = window.getBounds()
this.emit('window-resized', { page, bounds })
}, 500))
window.on('move', debounce(() => {
const bounds = window.getBounds()
this.emit('window-moved', { page, bounds })
}, 500))
}
handleWindowClose (pageOptions, page, window) {
window.on('close', (event) => {
if (!this.willQuit) {
if (pageOptions.bindCloseToHide && !this.willQuit) {
event.preventDefault()
window.hide()
// @see https://github.com/electron/electron/issues/20263
if (window.isFullScreen()) {
window.once('leave-full-screen', () => window.hide())
window.setFullScreen(false)
} else {
window.hide()
}
}
const bounds = window.getBounds()
this.emit('window-closed', { page, bounds })
})
}
showWindow (page) {
const window = this.getWindow(page)
if (!window) {
if (!window || (window.isVisible() && !window.isMinimized())) {
return
}
window.show()
}
hideWindow (page) {
const window = this.getWindow(page)
if (!window) {
if (!window || !window.isVisible()) {
return
}
window.hide()
@@ -153,10 +244,11 @@ export default class WindowManager extends EventEmitter {
if (!window) {
return
}
if (window.isVisible()) {
window.hide()
} else {
if (!window.isVisible() || window.isFullScreen()) {
window.show()
} else {
window.hide()
}
}
@@ -170,6 +262,18 @@ export default class WindowManager extends EventEmitter {
})
}
onWindowBlur (event, window) {
window.hide()
}
handleWindowBlur () {
app.on('browser-window-blur', this.onWindowBlur)
}
unbindWindowBlur () {
app.removeListener('browser-window-blur', this.onWindowBlur)
}
handleAllWindowClosed () {
app.on('window-all-closed', (event) => {
event.preventDefault()
@@ -180,7 +284,7 @@ export default class WindowManager extends EventEmitter {
if (!window) {
return
}
logger.info('[Motrix] sendCommandTo===>', window, command, ...args)
logger.info('[Motrix] send command to:', command, ...args)
window.webContents.send('command', command, ...args)
}
+120 -7
View File
@@ -1,18 +1,32 @@
import { app } from 'electron'
import { app, nativeTheme } from 'electron'
import is from 'electron-is'
import { resolve } from 'path'
import { existsSync, lstatSync } from 'fs'
import logger from '../core/Logger'
import engineBinMap from '../configs/engine'
import {
APP_THEME,
ENGINE_MAX_CONNECTION_PER_SERVER,
IP_VERSION
} from '@shared/constants'
import { engineBinMap, engineArchMap } from '../configs/engine'
export function getLogPath () {
return logger.transports.file.file
return app.getPath('logs')
}
export function getDhtPath (protocol) {
const name = protocol === IP_VERSION.V6 ? 'dht6.dat' : 'dht.dat'
return resolve(app.getPath('userData'), `./${name}`)
}
export function getSessionPath () {
return resolve(app.getPath('userData'), './download.session')
}
export function getEnginePidPath () {
return resolve(app.getPath('userData'), './engine.pid')
}
export function getUserDataPath () {
return app.getPath('userData')
}
@@ -22,12 +36,48 @@ export function getUserDownloadsPath () {
}
export function getEngineBin (platform) {
let result = engineBinMap.hasOwnProperty(platform) ? engineBinMap[platform] : ''
const result = engineBinMap[platform] || ''
return result
}
export function getEngineArch (platform, arch) {
if (!['darwin', 'win32', 'linux'].includes(platform)) {
return ''
}
const result = engineArchMap[platform][arch]
return result
}
export const getDevEnginePath = (platform, arch) => {
const ah = getEngineArch(platform, arch)
const base = `../../../extra/${platform}/${ah}/engine`
const result = resolve(__dirname, base)
return result
}
export const getProdEnginePath = () => {
return resolve(app.getAppPath(), '../engine')
}
export const getEnginePath = (platform, arch) => {
return is.dev() ? getDevEnginePath(platform, arch) : getProdEnginePath()
}
export const getAria2BinPath = (platform, arch) => {
const base = getEnginePath(platform, arch)
const binName = getEngineBin(platform)
const result = resolve(base, `./${binName}`)
return result
}
export const getAria2ConfPath = (platform, arch) => {
const base = getEnginePath(platform, arch)
return resolve(base, './aria2.conf')
}
export function transformConfig (config) {
let result = []
const result = []
for (const [k, v] of Object.entries(config)) {
if (v !== '') {
result.push(`--${k}=${v}`)
@@ -60,11 +110,55 @@ export function moveAppToApplicationsFolder (errorMsg = '') {
})
}
export function splitArgv (argv) {
const args = []
const extra = {}
for (const arg of argv) {
if (arg.startsWith('--')) {
const kv = arg.split('=')
const key = kv[0]
const value = kv[1] || '1'
extra[key] = value
continue
}
args.push(arg)
}
return { args, extra }
}
export function parseArgvAsUrl (argv) {
const arg = argv[1]
if (!arg) {
return
}
if (checkIsSupportedSchema(arg)) {
return arg
}
}
export function checkIsSupportedSchema (url = '') {
const str = url.toLowerCase()
if (
str.startsWith('ftp:') ||
str.startsWith('http:') ||
str.startsWith('https:') ||
str.startsWith('magnet:') ||
str.startsWith('thunder:') ||
str.startsWith('mo:') ||
str.startsWith('motrix:')
) {
return true
} else {
return false
}
}
export function isDirectory (path) {
return existsSync(path) && lstatSync(path).isDirectory()
}
export function parseArgv (argv) {
export function parseArgvAsFile (argv) {
let arg = argv[1]
if (!arg || isDirectory(arg)) {
return
@@ -75,3 +169,22 @@ export function parseArgv (argv) {
}
return arg
}
export const getMaxConnectionPerServer = () => {
return ENGINE_MAX_CONNECTION_PER_SERVER
}
export const getSystemTheme = () => {
let result = APP_THEME.LIGHT
result = nativeTheme.shouldUseDarkColors ? APP_THEME.DARK : APP_THEME.LIGHT
return result
}
export const convertArrayBufferToBuffer = (arrayBuffer) => {
const buffer = Buffer.alloc(arrayBuffer.byteLength)
const view = new Uint8Array(arrayBuffer)
for (let i = 0; i < buffer.length; ++i) {
buffer[i] = view[i]
}
return buffer
}
+48 -48
View File
@@ -1,33 +1,35 @@
import { parse } from 'querystring'
export function concat (template, submenu, submenuToAdd) {
submenuToAdd.forEach(sub => {
let relativeItem = null
if (sub.position) {
switch (sub.position) {
case 'first':
submenu.unshift(sub)
break
case 'last':
submenu.push(sub)
break
case 'before':
relativeItem = findById(template, sub['relative-id'])
if (relativeItem) {
let array = relativeItem.__parent
let index = array.indexOf(relativeItem)
array.splice(index, 0, sub)
}
break
case 'after':
relativeItem = findById(template, sub['relative-id'])
if (relativeItem) {
let array = relativeItem.__parent
let index = array.indexOf(relativeItem)
array.splice(index + 1, 0, sub)
}
break
default:
submenu.push(sub)
break
case 'first':
submenu.unshift(sub)
break
case 'last':
submenu.push(sub)
break
case 'before':
relativeItem = findById(template, sub['relative-id'])
if (relativeItem) {
const array = relativeItem.__parent
const index = array.indexOf(relativeItem)
array.splice(index, 0, sub)
}
break
case 'after':
relativeItem = findById(template, sub['relative-id'])
if (relativeItem) {
const array = relativeItem.__parent
const index = array.indexOf(relativeItem)
array.splice(index + 1, 0, sub)
}
break
default:
submenu.push(sub)
break
}
} else {
submenu.push(sub)
@@ -37,7 +39,7 @@ export function concat (template, submenu, submenuToAdd) {
export function merge (template, item) {
if (item.id) {
let matched = findById(template, item.id)
const matched = findById(template, item.id)
if (matched) {
if (item.submenu && Array.isArray(item.submenu)) {
if (!Array.isArray(matched.submenu)) {
@@ -54,15 +56,15 @@ export function merge (template, item) {
}
function findById (template, id) {
for (let i in template) {
let item = template[i]
for (const i in template) {
const item = template[i]
if (item.id === id) {
// Returned item need to have a reference to parent Array (.__parent).
// This is required to handle `position` and `relative-id`
item.__parent = template
return item
} else if (Array.isArray(item.submenu)) {
let result = findById(item.submenu, id)
const result = findById(item.submenu, id)
if (result) {
return result
}
@@ -72,8 +74,8 @@ function findById (template, id) {
}
export function translateTemplate (template, keystrokesByCommand, i18n) {
for (let i in template) {
let item = template[i]
for (const i in template) {
const item = template[i]
if (item.command) {
item.accelerator = acceleratorForCommand(item.command, keystrokesByCommand)
}
@@ -112,30 +114,28 @@ export function handleCommand (item) {
}
function handleCommandBefore (item) {
console.log('handleCommandBefore==1=>', item)
if (!item['command-before']) {
return
}
const [ command, ...args ] = item['command-before'].split(',')
console.log('handleCommandBefore==2=>', command, ...args)
global.application.sendCommandToAll(command, ...args)
const [command, params] = item['command-before'].split('?')
const args = parse(params)
global.application.sendCommandToAll(command, args)
}
function handleCommandAfter (item) {
console.log('handleCommandAfter==1=>', item)
if (!item['command-after']) {
return
}
const [ command, ...args ] = item['command-after'].split(',')
console.log('handleCommandAfter==2=>', command, ...args)
global.application.sendCommandToAll(command, ...args)
const [command, params] = item['command-after'].split('?')
const args = parse(params)
global.application.sendCommandToAll(command, args)
}
function acceleratorForCommand (command, keystrokesByCommand) {
const keystroke = keystrokesByCommand[command]
if (keystroke) {
let modifiers = keystroke.split(/-(?=.)/)
let key = modifiers.pop().toUpperCase()
const key = modifiers.pop().toUpperCase()
.replace('+', 'Plus')
.replace('MINUS', '-')
modifiers = modifiers.map((modifier) => {
@@ -152,14 +152,14 @@ function acceleratorForCommand (command, keystrokesByCommand) {
.replace(/alt/ig, 'Alt')
}
})
let keys = modifiers.concat([key])
const keys = modifiers.concat([key])
return keys.join('+')
}
return null
}
export function flattenMenuItems (menu) {
let flattenItems = {}
const flattenItems = {}
menu.items.forEach(item => {
if (item.id) {
flattenItems[item.id] = item
@@ -173,24 +173,24 @@ export function flattenMenuItems (menu) {
export function updateStates (itemsById, visibleStates, enabledStates, checkedStates) {
if (visibleStates) {
for (let command in visibleStates) {
let item = itemsById[command]
for (const command in visibleStates) {
const item = itemsById[command]
if (item) {
item.visible = visibleStates[command]
}
}
}
if (enabledStates) {
for (let command in enabledStates) {
let item = itemsById[command]
for (const command in enabledStates) {
const item = itemsById[command]
if (item) {
item.enabled = enabledStates[command]
}
}
}
if (checkedStates) {
for (let id in checkedStates) {
let item = itemsById[id]
for (const id in checkedStates) {
const item = itemsById[id]
if (item) {
item.checked = checkedStates[id]
}
+159 -49
View File
@@ -1,28 +1,29 @@
import { remote } from 'electron'
import { ipcRenderer } from 'electron'
import is from 'electron-is'
import { isEmpty } from 'lodash'
import Aria2 from 'aria2'
import { isEmpty, clone } from 'lodash'
import { Aria2 } from '@shared/aria2'
import {
separateConfig,
compactUndefined,
formatOptionsForEngine,
mergeTaskResult,
changeKeysToCamelCase,
changeKeysToKebabCase
} from '@shared/utils'
const application = remote.getGlobal('application')
import { ENGINE_RPC_HOST } from '@shared/constants'
export default class Api {
constructor (options = {}) {
this.options = options
this.client = null
this.init()
}
init () {
this.loadConfig()
this.initClient()
async init () {
this.config = await this.loadConfig()
this.client = this.initClient()
this.client.open()
}
loadConfigFromLocalStorage () {
@@ -31,21 +32,18 @@ export default class Api {
return result
}
loadConfigFromNativeStore () {
const systemConfig = application.configManager.getSystemConfig()
const userConfig = application.configManager.getUserConfig()
const result = { ...systemConfig, ...userConfig }
async loadConfigFromNativeStore () {
const result = await ipcRenderer.invoke('get-app-config')
return result
}
loadConfig () {
async loadConfig () {
let result = is.renderer()
? this.loadConfigFromNativeStore()
? await this.loadConfigFromNativeStore()
: this.loadConfigFromLocalStorage()
result = changeKeysToCamelCase(result)
this.config = result
return result
}
initClient () {
@@ -53,11 +51,12 @@ export default class Api {
rpcListenPort: port,
rpcSecret: secret
} = this.config
this.client = new Aria2({
const host = ENGINE_RPC_HOST
return new Aria2({
host,
port,
secret
})
this.client.open()
}
closeClient () {
@@ -72,7 +71,7 @@ export default class Api {
fetchPreference () {
return new Promise((resolve) => {
this.loadConfig()
this.config = this.loadConfig()
resolve(this.config)
})
}
@@ -80,9 +79,9 @@ export default class Api {
savePreference (params = {}) {
const kebabParams = changeKeysToKebabCase(params)
if (is.renderer()) {
this.savePreferenceToNativeStore(kebabParams)
return this.savePreferenceToNativeStore(kebabParams)
} else {
this.savePreferenceToLocalStorage(kebabParams)
return this.savePreferenceToLocalStorage(kebabParams)
}
}
@@ -92,25 +91,36 @@ export default class Api {
savePreferenceToNativeStore (params = {}) {
const { user, system, others } = separateConfig(params)
if (!isEmpty(system)) {
console.info('[Motrix] save system config: ', system)
application.configManager.setSystemConfig(system)
}
const config = {}
if (!isEmpty(user)) {
console.info('[Motrix] save user config: ', user)
application.configManager.setUserConfig(user)
config.user = user
}
if (!isEmpty(system)) {
console.info('[Motrix] save system config: ', system)
config.system = system
this.updateActiveTaskOption(system)
}
if (!isEmpty(others)) {
console.info('[Motrix] save config found iillegal key: ', others)
console.info('[Motrix] save config found illegal key: ', others)
}
ipcRenderer.send('command', 'application:save-preference', config)
}
getVersion () {
return this.client.call('getVersion')
}
changeGlobalOption (options) {
const args = formatOptionsForEngine(options)
return this.client.call('changeGlobalOption', args)
}
getGlobalOption () {
return new Promise((resolve) => {
this.client.call('getGlobalOption')
@@ -120,6 +130,39 @@ export default class Api {
})
}
getOption (params = {}) {
const { gid } = params
const args = compactUndefined([gid])
return new Promise((resolve) => {
this.client.call('getOption', ...args)
.then((data) => {
resolve(changeKeysToCamelCase(data))
})
})
}
updateActiveTaskOption (options) {
this.fetchTaskList({ type: 'active' })
.then((data) => {
if (isEmpty(data)) {
return
}
const gids = data.map((task) => task.gid)
this.batchChangeOption({ gids, options })
})
}
changeOption (params = {}) {
const { gid, options = {} } = params
const engineOptions = formatOptionsForEngine(options)
const args = compactUndefined([gid, engineOptions])
return this.client.call('changeOption', ...args)
}
getGlobalStat () {
return this.client.call('getGlobalStat')
}
@@ -127,11 +170,16 @@ export default class Api {
addUri (params) {
const {
uris,
outs,
options
} = params
const tasks = uris.map((uri) => {
const args = compactUndefined([[uri], options])
return [ 'aria2.addUri', ...args ]
const tasks = uris.map((uri, index) => {
const engineOptions = formatOptionsForEngine(options)
if (outs && outs[index]) {
engineOptions.out = outs[index]
}
const args = compactUndefined([[uri], engineOptions])
return ['aria2.addUri', ...args]
})
return this.client.multicall(tasks)
}
@@ -141,7 +189,8 @@ export default class Api {
torrent,
options
} = params
const args = compactUndefined([torrent, [], options])
const engineOptions = formatOptionsForEngine(options)
const args = compactUndefined([torrent, [], engineOptions])
return this.client.call('addTorrent', ...args)
}
@@ -150,7 +199,8 @@ export default class Api {
metalink,
options
} = params
const args = compactUndefined([metalink, options])
const engineOptions = formatOptionsForEngine(options)
const args = compactUndefined([metalink, engineOptions])
return this.client.call('addMetalink', ...args)
}
@@ -160,14 +210,14 @@ export default class Api {
const waitingArgs = compactUndefined([offset, num, keys])
return new Promise((resolve, reject) => {
this.client.multicall([
[ 'aria2.tellActive', ...activeArgs ],
[ 'aria2.tellWaiting', ...waitingArgs ]
['aria2.tellActive', ...activeArgs],
['aria2.tellWaiting', ...waitingArgs]
]).then((data) => {
console.log('fetchDownloadingTaskList data', data)
console.log('[Motrix] fetch downloading task list data:', data)
const result = mergeTaskResult(data)
resolve(result)
}).catch((err) => {
console.log('fetchDownloadingTaskList fail===>', err)
console.log('[Motrix] fetch downloading task list fail:', err)
reject(err)
})
})
@@ -185,17 +235,23 @@ export default class Api {
return this.client.call('tellStopped', ...args)
}
fetchActiveTaskList (params = {}) {
const { keys } = params
const args = compactUndefined([keys])
return this.client.call('tellActive', ...args)
}
fetchTaskList (params = {}) {
const { type } = params
switch (type) {
case 'active':
return this.fetchDownloadingTaskList(params)
case 'waiting':
return this.fetchWaitingTaskList(params)
case 'stopped':
return this.fetchStoppedTaskList(params)
default:
return this.fetchDownloadingTaskList(params)
case 'active':
return this.fetchDownloadingTaskList(params)
case 'waiting':
return this.fetchWaitingTaskList(params)
case 'stopped':
return this.fetchStoppedTaskList(params)
default:
return this.fetchDownloadingTaskList(params)
}
}
@@ -205,6 +261,36 @@ export default class Api {
return this.client.call('tellStatus', ...args)
}
fetchTaskItemWithPeers (params = {}) {
const { gid, keys } = params
const statusArgs = compactUndefined([gid, keys])
const peersArgs = compactUndefined([gid])
return new Promise((resolve, reject) => {
this.client.multicall([
['aria2.tellStatus', ...statusArgs],
['aria2.getPeers', ...peersArgs]
]).then((data) => {
console.log('[Motrix] fetchTaskItemWithPeers:', data)
const result = data[0] && data[0][0]
const peers = data[1] && data[1][0]
result.peers = peers || []
console.log('[Motrix] fetchTaskItemWithPeers.result:', result)
console.log('[Motrix] fetchTaskItemWithPeers.peers:', peers)
resolve(result)
}).catch((err) => {
console.log('[Motrix] fetch downloading task list fail:', err)
reject(err)
})
})
}
fetchTaskItemPeers (params = {}) {
const { gid, keys } = params
const args = compactUndefined([gid, keys])
return this.client.call('getPeers', ...args)
}
pauseTask (params = {}) {
const { gid } = params
const args = compactUndefined([gid])
@@ -261,11 +347,35 @@ export default class Api {
return this.client.call('removeDownloadResult', ...args)
}
startPowerSaveBlocker () {
application.energyManager.startPowerSaveBlocker()
multicall (method, params = {}) {
let { gids, options = {} } = params
options = formatOptionsForEngine(options)
const data = gids.map((gid, index) => {
const _options = clone(options)
const args = compactUndefined([gid, _options])
return [method, ...args]
})
return this.client.multicall(data)
}
stopPowerSaveBlocker () {
application.energyManager.stopPowerSaveBlocker()
batchChangeOption (params = {}) {
return this.multicall('aria2.changeOption', params)
}
batchRemoveTask (params = {}) {
return this.multicall('aria2.remove', params)
}
batchResumeTask (params = {}) {
return this.multicall('aria2.unpause', params)
}
batchPauseTask (params = {}) {
return this.multicall('aria2.pause', params)
}
batchForcePauseTask (params = {}) {
return this.multicall('aria2.forcePause', params)
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<g class="nc-icon-wrapper" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor">
<line data-cap="butt" data-color="color-2" fill="none" stroke-miterlimit="10" x1="12" y1="2" x2="12" y2="22"/>
<polyline fill="none" stroke="currentColor" stroke-miterlimit="10" points="19,15 12,22 5,15 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 429 B

Some files were not shown because too many files have changed in this diff Show More