mirror of
https://github.com/NoCrypt/migu.git
synced 2026-03-11 17:45:32 +00:00
fix: torrent client sometimes loading without settings on android
feat: persist files on android feat: custom download directory on android
This commit is contained in:
parent
c595dd7224
commit
94f8fafc6b
9 changed files with 442 additions and 535 deletions
|
|
@ -54,6 +54,8 @@
|
|||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -18,24 +18,25 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/assets": "github:thaunknown/capacitor-assets",
|
||||
"@capacitor/cli": "^6.1.1",
|
||||
"@capacitor/cli": "^6.1.2",
|
||||
"cordova-res": "^0.15.4",
|
||||
"nodejs-mobile-gyp": "^0.3.1",
|
||||
"nodejs-mobile-gyp": "^0.4.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.10.0"
|
||||
"webpack-merge": "^6.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@capacitor/android": "^6.1.1",
|
||||
"@capacitor/app": "^6.0.0",
|
||||
"@capacitor/browser": "^6.0.1",
|
||||
"@capacitor/core": "^6.1.1",
|
||||
"@capacitor/android": "^6.1.2",
|
||||
"@capacitor/app": "^6.0.1",
|
||||
"@capacitor/browser": "^6.0.2",
|
||||
"@capacitor/core": "^6.1.2",
|
||||
"@capacitor/device": "^6.0.1",
|
||||
"@capacitor/ios": "^6.1.1",
|
||||
"@capacitor/local-notifications": "^6.0.0",
|
||||
"@capacitor/status-bar": "^6.0.0",
|
||||
"@capacitor/ios": "^6.1.2",
|
||||
"@capacitor/local-notifications": "^6.1.0",
|
||||
"@capacitor/status-bar": "^6.0.1",
|
||||
"capacitor-folder-picker": "^0.0.2",
|
||||
"capacitor-nodejs": "https://github.com/funniray/Capacitor-NodeJS/releases/download/nodejs-18/capacitor-nodejs-1.0.0-beta.6.tgz",
|
||||
"capacitor-plugin-safe-area": "^2.0.6",
|
||||
"capacitor-plugin-safe-area": "^3.0.3",
|
||||
"common": "workspace:*",
|
||||
"cordova-plugin-navigationbar": "^1.0.31",
|
||||
"cordova-plugin-pip": "^0.0.2",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import { App } from '@capacitor/app'
|
|||
import { Browser } from '@capacitor/browser'
|
||||
import { LocalNotifications } from '@capacitor/local-notifications'
|
||||
import { Device } from '@capacitor/device'
|
||||
import { FolderPicker } from 'capacitor-folder-picker'
|
||||
import { toast } from 'svelte-sonner'
|
||||
import IPC from './ipc.js'
|
||||
|
||||
IPC.on('open', url => Browser.open({ url }))
|
||||
|
|
@ -51,6 +53,30 @@ IPC.on('get-device-info', async () => {
|
|||
IPC.emit('device-info', JSON.stringify(deviceInfo))
|
||||
})
|
||||
|
||||
const STORAGE_TYPE_MAP = {
|
||||
primary: '/sdcard/',
|
||||
secondary: '/sdcard/'
|
||||
}
|
||||
|
||||
IPC.on('dialog', async () => {
|
||||
const result = await FolderPicker.chooseFolder()
|
||||
const normalizedPath = decodeURIComponent(result.path)
|
||||
|
||||
const [, uri, ...path] = normalizedPath.split(':')
|
||||
const [,, app, subpath, type, ...rest] = uri.split('/')
|
||||
|
||||
if (app !== 'com.android.externalstorage.documents') return toast.error('Unverified app', { description: 'Expected com.android.externalstorage.documents, got: ' + app })
|
||||
if (rest.length) return toast.error('Unsupported uri', { description: 'Unxpected access type, got: tree/' + rest.join('/') })
|
||||
if (subpath !== 'tree') return toast.error('Unsupported subpath type', { description: 'Expected tree subpath, got: ' + subpath })
|
||||
|
||||
let base = STORAGE_TYPE_MAP[type]
|
||||
if (!base) {
|
||||
if (!/[a-z0-9]{4}-[a-z0-9]{4}/i.test(type)) return toast.error('Unsupported storage type')
|
||||
base = `/storage/${type}/`
|
||||
}
|
||||
IPC.emit('path', base + path.join(''))
|
||||
})
|
||||
|
||||
// schema: miru://key/value
|
||||
const protocolMap = {
|
||||
auth: token => sendToken(token),
|
||||
|
|
|
|||
|
|
@ -24,11 +24,16 @@ channel.on('port-init', data => {
|
|||
channel.send('ipc', { data })
|
||||
}
|
||||
}
|
||||
let storedSettings = {}
|
||||
|
||||
try {
|
||||
storedSettings = JSON.parse(localStorage.getItem('settings')) || {}
|
||||
} catch (error) {}
|
||||
|
||||
if (!globalThis.client) globalThis.client = new TorrentClient(channel, storageQuota, 'node', storedSettings.torrentPathNew || env.TMPDIR)
|
||||
|
||||
channel.on('ipc', a => port.onmessage(a))
|
||||
channel.emit('port', {
|
||||
ports: [port]
|
||||
})
|
||||
})
|
||||
|
||||
globalThis.client = new TorrentClient(channel, storageQuota, 'node', env.TMPDIR)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,7 @@ export const SUPPORTS = {
|
|||
update: false,
|
||||
angle: false,
|
||||
doh: false,
|
||||
dht: true,
|
||||
discord: false,
|
||||
torrentPort: true,
|
||||
torrentPath: false,
|
||||
torrentPersist: false,
|
||||
keybinds: false,
|
||||
isAndroid: true,
|
||||
externalPlayer: false,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,7 @@ export const SUPPORTS = {
|
|||
update: true,
|
||||
angle: true,
|
||||
doh: true,
|
||||
dht: true,
|
||||
discord: true,
|
||||
torrentPort: true,
|
||||
torrentPath: true,
|
||||
torrentPersist: true,
|
||||
keybinds: true,
|
||||
extensions: true,
|
||||
isAndroid: false,
|
||||
|
|
|
|||
|
|
@ -37,12 +37,6 @@ const ANNOUNCE = [
|
|||
atob('aHR0cDovL3RyYWNrZXIuYW5pcmVuYS5jb206ODAvYW5ub3VuY2U=')
|
||||
]
|
||||
|
||||
let storedSettings = {}
|
||||
|
||||
try {
|
||||
storedSettings = JSON.parse(localStorage.getItem('settings')) || {}
|
||||
} catch (error) {}
|
||||
|
||||
export default class TorrentClient extends WebTorrent {
|
||||
static excludedErrorMessages = ['WebSocket', 'User-Initiated Abort, reason=', 'Connection failed.']
|
||||
|
||||
|
|
@ -54,6 +48,12 @@ export default class TorrentClient extends WebTorrent {
|
|||
ipc
|
||||
|
||||
constructor (ipc, storageQuota, serverMode, torrentPath, controller) {
|
||||
let storedSettings = {}
|
||||
|
||||
try {
|
||||
storedSettings = JSON.parse(localStorage.getItem('settings')) || {}
|
||||
} catch (error) {}
|
||||
|
||||
const settings = { ...defaults, ...storedSettings }
|
||||
debug('Initializing TorrentClient with settings: ' + JSON.stringify(settings))
|
||||
super({
|
||||
|
|
|
|||
|
|
@ -140,25 +140,25 @@
|
|||
{/if}
|
||||
|
||||
<h4 class='mb-10 font-weight-bold'>Client Settings</h4>
|
||||
{#if SUPPORTS.torrentPath}
|
||||
<SettingCard title='Torrent Download Location' description='Path to the folder used to store torrents. By default this is the TMP folder, which might lose data when your OS tries to reclaim storage.'>
|
||||
<div
|
||||
class='input-group w-300 mw-full'>
|
||||
<div class='input-group-prepend'>
|
||||
<button type='button' use:click={handleFolder} class='btn btn-primary input-group-append'>Select Folder</button>
|
||||
</div>
|
||||
<input type='url' class='form-control bg-dark' readonly value={settings.torrentPathNew} placeholder='/tmp' />
|
||||
<SettingCard title='Torrent Download Location' description='Path to the folder used to store torrents. By default this is the TMP folder, which might lose data when your OS tries to reclaim storage. {SUPPORTS.isAndroid ? 'RESTART IS REQUIRED. /sdcard/ is internal storage, not external SD Cards. /storage/AB12-34CD/ is external storage, not internal. Thank you Android!' : ''}'>
|
||||
<div
|
||||
class='input-group w-300 mw-full'>
|
||||
<div class='input-group-prepend'>
|
||||
<button type='button' use:click={handleFolder} class='btn btn-primary input-group-append'>Select Folder</button>
|
||||
</div>
|
||||
</SettingCard>
|
||||
{/if}
|
||||
{#if SUPPORTS.torrentPersist}
|
||||
<SettingCard title='Persist Files' description="Keeps torrents files instead of deleting them after a new torrent is played. This doesn't seed the files, only keeps them on your drive. This will quickly fill up your storage.">
|
||||
<div class='custom-switch'>
|
||||
<input type='checkbox' id='torrent-persist' bind:checked={settings.torrentPersist} />
|
||||
<label for='torrent-persist'>{settings.torrentPersist ? 'On' : 'Off'}</label>
|
||||
</div>
|
||||
</SettingCard>
|
||||
{/if}
|
||||
{#if !SUPPORTS.isAndroid}
|
||||
<input type='url' class='form-control bg-dark' readonly bind:value={settings.torrentPathNew} placeholder='/tmp' />
|
||||
{:else}
|
||||
<input type='text' class='form-control bg-dark' bind:value={settings.torrentPathNew} placeholder='/tmp' />
|
||||
{/if}
|
||||
</div>
|
||||
</SettingCard>
|
||||
<SettingCard title='Persist Files' description="Keeps torrents files instead of deleting them after a new torrent is played. This doesn't seed the files, only keeps them on your drive. This will quickly fill up your storage.">
|
||||
<div class='custom-switch'>
|
||||
<input type='checkbox' id='torrent-persist' bind:checked={settings.torrentPersist} />
|
||||
<label for='torrent-persist'>{settings.torrentPersist ? 'On' : 'Off'}</label>
|
||||
</div>
|
||||
</SettingCard>
|
||||
<SettingCard title='Streamed Download' description="Only downloads the single file that's currently being watched, instead of downloading an entire batch of episodes. Saves bandwidth and reduces strain on the peer swarm.">
|
||||
<div class='custom-switch'>
|
||||
<input type='checkbox' id='torrent-streamed-download' bind:checked={settings.torrentStreamedDownload} />
|
||||
|
|
@ -176,22 +176,18 @@
|
|||
<SettingCard title='Max Number of Connections' description='Number of peers per torrent. Higher values will increase download speeds but might quickly fill up available ports if your ISP limits the maximum allowed number of open connections.'>
|
||||
<input type='number' inputmode='numeric' pattern='[0-9]*' bind:value={settings.maxConns} min='1' max='512' class='form-control text-right bg-dark w-100 mw-full' />
|
||||
</SettingCard>
|
||||
{#if SUPPORTS.torrentPort}
|
||||
<SettingCard title='Torrent Port' description='Port used for Torrent connections. 0 is automatic.'>
|
||||
<input type='number' inputmode='numeric' pattern='[0-9]*' bind:value={settings.torrentPort} min='0' max='65536' class='form-control text-right bg-dark w-150 mw-full' />
|
||||
</SettingCard>
|
||||
{/if}
|
||||
{#if SUPPORTS.dht}
|
||||
<SettingCard title='DHT Port' description='Port used for DHT connections. 0 is automatic.'>
|
||||
<input type='number' inputmode='numeric' pattern='[0-9]*' bind:value={settings.dhtPort} min='0' max='65536' class='form-control text-right bg-dark w-150 mw-full' />
|
||||
</SettingCard>
|
||||
<SettingCard title='Disable DHT' description='Disables Distributed Hash Tables for use in private trackers to improve privacy. Might greatly reduce the amount of discovered peers.'>
|
||||
<div class='custom-switch'>
|
||||
<input type='checkbox' id='torrent-dht' bind:checked={settings.torrentDHT} />
|
||||
<label for='torrent-dht'>{settings.torrentDHT ? 'On' : 'Off'}</label>
|
||||
</div>
|
||||
</SettingCard>
|
||||
{/if}
|
||||
<SettingCard title='Torrent Port' description='Port used for Torrent connections. 0 is automatic.'>
|
||||
<input type='number' inputmode='numeric' pattern='[0-9]*' bind:value={settings.torrentPort} min='0' max='65536' class='form-control text-right bg-dark w-150 mw-full' />
|
||||
</SettingCard>
|
||||
<SettingCard title='DHT Port' description='Port used for DHT connections. 0 is automatic.'>
|
||||
<input type='number' inputmode='numeric' pattern='[0-9]*' bind:value={settings.dhtPort} min='0' max='65536' class='form-control text-right bg-dark w-150 mw-full' />
|
||||
</SettingCard>
|
||||
<SettingCard title='Disable DHT' description='Disables Distributed Hash Tables for use in private trackers to improve privacy. Might greatly reduce the amount of discovered peers.'>
|
||||
<div class='custom-switch'>
|
||||
<input type='checkbox' id='torrent-dht' bind:checked={settings.torrentDHT} />
|
||||
<label for='torrent-dht'>{settings.torrentDHT ? 'On' : 'Off'}</label>
|
||||
</div>
|
||||
</SettingCard>
|
||||
<SettingCard title='Disable PeX' description='Disables Peer Exchange for use in private trackers to improve privacy. Might greatly reduce the amount of discovered peers.'>
|
||||
<div class='custom-switch'>
|
||||
<input type='checkbox' id='torrent-pex' bind:checked={settings.torrentPeX} />
|
||||
|
|
|
|||
833
pnpm-lock.yaml
833
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue