1
1
mirror of https://github.com/neosubhamoy/neodlp.git synced 2026-02-04 23:32:23 +05:30

19 Commits

60 changed files with 1346 additions and 857 deletions

40
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,40 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: neosubhamoy
---
**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.
**OS info (required):**
- OS: [e.g. Windows 11]
- OS Architecture: [e.g. x64]
- OS Version: [e.g. 25H2 26200.6899]
**App info (required):**
- NeoDLP Version: [e.g. 0.3.1]
- YT-DLP Version: [e.g. 2025.10.18.232824]
- NeoDLP Installation Mode: [e.g. msi, exe, winget]
**App logs (required):**
Paste the full app session logs here
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE REQUEST]"
labels: feature request
assignees: neosubhamoy
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

31
.github/ISSUE_TEMPLATE/test_result.md vendored Normal file
View File

@@ -0,0 +1,31 @@
---
name: Test result
about: Share your test results
title: "[TEST RESULT]"
labels: test result
assignees: neosubhamoy
---
**Describe the result**
A clear and concise description of what's the final result of your testing.
**Did you noticed any problem?**
Mention if you noticed any problems or inconsistencies during the testing
**Screenshots**
If applicable, add screenshots to help explain the results.
**What's working (required):**
- [ ] Package installation
- [ ] Downloads
- [ ] Settings and configurations
- [ ] Browser integration
**Test environment (required):**
- OS: [e.g. Windows 11]
- OS Architecture: [e.g. x64]
- OS Version: [e.g. 25H2 26200.6899]
- NeoDLP Version: [e.g. 0.3.1]
- YT-DLP Version: [e.g. 2025.10.18.232824]
- NeoDLP Installation Mode: [e.g. msi, exe, winget]

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
.github/images/completed-downloads.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

BIN
.github/images/downloader.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

Before

Width:  |  Height:  |  Size: 541 KiB

After

Width:  |  Height:  |  Size: 541 KiB

BIN
.github/images/ongoing-downloads.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
.github/images/settings.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

@@ -25,9 +25,19 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- name: 🚚 Checkout repository
uses: actions/checkout@v4
with:
lfs: true
uses: actions/checkout@v5
- name: 🔐 Configure Git LFS
shell: bash
run: |
git config --global credential.helper store
echo "https://${{ secrets.LFS_USERNAME }}:${{ secrets.LFS_PASSWORD }}@lfs.neosubhamoy.com" > ~/.git-credentials
- name: 📥 Pull LFS objects
shell: bash
run: |
git lfs install
git lfs pull
- name: 🛠️ Install dependencies
if: matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-22.04-arm'
@@ -36,7 +46,7 @@ jobs:
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: 📦 Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: 'lts/*'
cache: 'npm'

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ dist
dist-ssr
*.local
.github/workflows/.secrets
/target/
# Editor directories and files
.vscode/*

2
.lfsconfig Normal file
View File

@@ -0,0 +1,2 @@
[lfs]
url = https://lfs.neosubhamoy.com

View File

@@ -1,25 +1,19 @@
### ✨ Changelog
- Added per-download configuration tweaks in downloader
- Added cookies support
- Added sponsorblock support (mark/remove segments)
- Added custom yt-dlp command support
- Added aria2 support (macos users need to install aria2 via homebrew to use this feature)
- Added force ipv protocol option in settings
- Added filename template option in settings
- Added real-time app session log viewer (monitor detailed yt-dlp logs)
- Improved download resume persistence (now more essential settings are preserved on resume)
- Added quick search button for completed downloads in library
- Fixed completed download sorting order (last completed on top)
- Ships with deno javascript runtime (as per new yt-dlp requirement)
- Added new linux arm64 builds (deb, rpm)
- Lots of other fixes and improvements
- Added Debug Mode (with log customization)
- Added quick paste and clear buttons on downloader
- Fixed browser integration not working on Windows MSI install
- Fixed the occasional freezing issue on macOS while downloading large files
- Now Linux (deb, rpm) packages supports in-built app-updater
- Other minor fixes and improvements
### 📝 Notes
> **🔴 DANGER:** This update introduces few breaking changes! Users are adviced to complete/cancel all paused downloads before updating to this version, otherwise paused downloads may not resume properly or re-start from the begining.
> [!CAUTION]
> This is a breaking update if you are coming from older version than `v0.3.0`. Users are adviced to complete/cancel all paused downloads before updating to this version, otherwise paused downloads may not resume properly or re-start from the begining.
> **⚠️ WARNING:** Linux users make sure `yt-dlp`, `ffmpeg`, `ffprobe` and `deno` is not installed in your distro (otherwise you will get package installation conflict). Don't worry, You can still use yt-dlp cli as before (the only difference is that now it will be installed and auto-updated by neo-dlp, which You can also disable from neo-dlp Settings if you don't want to auto-update yt-dlp)
> [!WARNING]
> Linux users make sure `yt-dlp` and `deno` is not installed in your distro (otherwise you will get package installation conflict). Don't worry, You can still use yt-dlp cli as before (the only difference is that now it will be installed and auto-updated by neo-dlp, which You can also disable from neo-dlp Settings if you don't want to auto-update yt-dlp)
> This is an Un-Signed Build (Windows doesn't trust this Certificate so, it may flag this as malicious software, in that case, disable Windows SmartScreen and Defender, install it, and then re-enable them)
@@ -29,17 +23,23 @@
| yt-dlp (updateable) | ffmpeg | ffprobe | aria2c | deno |
| :---- | :---- | :---- | :---- | :---- |
| v2025.10.01.232815 (nightly) | v7.1.1 | v7.1.1 | v1.37.0 | v2.5.3|
| v2025.10.25.232842 (nightly) | v7.1.1 | v7.1.1 | v1.37.0 | v2.5.4 |
> ‼️ Linux builds (deb, rpm) does not ships with `ffmpeg` and `ffprobe` (though it will be auto installed as a dependency by your package manager, if you are on fedora make sure to [enable rpmfusion free+nonfree repos](https://docs.fedoraproject.org/en-US/quick-docs/rpmfusion-setup/#_enabling_the_rpm_fusion_repositories_using_command_line_utilities) before installing the rpm package)
> ‼️ MacOS builds (dmg, app) does not ships with `aria2c`, If you want to use [aria2](https://formulae.brew.sh/formula/aria2) install it via [homebrew](https://brew.sh)
### ⬇️ Download Section
| Arch\OS | Windows (msi) ⬆️ | Windows (exe) ⬆️ | Linux (deb) | Linux (rpm) | MacOS (dmg) ⬆️ | MacOS (app) ⬆️ |
| :---- | :---- | :---- | :---- | :---- | :---- | :---- |
| x86_64 | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64_en-US.msi) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64-setup.exe) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_amd64.deb) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP-<version>-1.x86_64.rpm) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64.dmg) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_x64.app.tar.gz) |
| ARM64 | N/A | 🪟 [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64-setup.exe) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_arm64.deb) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP-<version>-1.aarch64.rpm) | ⚠️ [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_aarch64.dmg) | ⚠️ [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_aarch64.app.tar.gz) |
| Arch\OS | Windows (msi) | Windows (exe) | Linux (deb) | Linux (rpm) | Linux (AppImage) | MacOS (dmg) | MacOS (app) |
| :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- |
| x86_64 | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64_en-US_windows.msi) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64-setup_windows.exe) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_amd64_linux.deb) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP-<version>-1.x86_64_linux.rpm) | 🚫 [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_amd64_linux.AppImage) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64_darwin.dmg) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_darwin_x64.app.tar.gz) |
| ARM64 | N/A | 🪟 [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_x64-setup_windows.exe) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_arm64_linux.deb) | [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP-<version>-1.aarch64_linux.rpm) | N/A | ⚠️ [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_<version>_aarch64_darwin.dmg) | ⚠️ [Download](https://github.com/neosubhamoy/neodlp/releases/download/<release_tag>/NeoDLP_darwin_aarch64.app.tar.gz) |
> ⬆️ icon indicates this packaging format supports in-built app-updater
> ⬆️ Now, all packages supports in-built app-updater
> 🪟 Windows x86_64 binary also works on ARM64 (Windows on ARM) devices with emulation (Not planning to release native Windows ARM64 build anytime soon as, x86_64 one works fine on ARM64 without noticeable performance impact)
> 🚫 Linux AppImage builds are experimental and does not support neodlp's browser intergration features due to it's sandboxed nature. Also, don't run the AppImage with portable (.home, .config) folders, it will break things (it is highly recommended to use native [deb, rpm, AUR] builds if possible for the full experiance, otherwise AppImages are good for trying out NeoDLP without installing)
> ⚠️ MacOS ARM64 binary downloads are experimental and may not open on Apple Silicon Macs if downloaded from browser (You will get 'Damaged File' error) it's because the binaries are not signed (signing MacOS binaries requires 99$/year Apple Developer Account subscription, which I can't afford RN!) and Apple Silicon Macs don't allow unsigned apps (downloaded from browser) to be installed on the system. If you want to use NeoDLP on your Apple Silicon Macs, you can simply use the command line [Curl-Bash Installer](https://neodlp.neosubhamoy.com/download) (Recommended) -OR- [compile it from source](https://github.com/neosubhamoy/neodlp?tab=readme-ov-file#%EF%B8%8F-contributing--building-from-source) in your Mac

View File

@@ -1,4 +1,4 @@
![NeoDLP](./.github/banner.svg)
![NeoDLP](./.github/images/banner.svg)
# NeoDLP - (Neo Downloader Plus)
@@ -9,11 +9,12 @@ Cross-platform Video/Audio Downloader Desktop App with Modern UI and Browser Int
[![github downloads](https://img.shields.io/github/downloads/neosubhamoy/neodlp/total)](https://github.com/neosubhamoy/neodlp/releases)
[![PRs](https://img.shields.io/badge/PRs-welcome-blue.svg?style=flat)](https://github.com/neosubhamoy/neodlp)
> [!TIP]
> **🥰 Liked this project? Please consider giving it a Star (🌟) on github to show us your appreciation and help the algorythm recommend this project to even more awesome people like you!**
[![Packaging status](https://repology.org/badge/vertical-allrepos/neodlp.svg)](https://repology.org/project/neodlp/versions)
### ✨ Highlighted Features
## ✨ Highlighted Features
- Download Video/Audio from popular sites (YT, FB, IG, X and other 2.5k+ [supported sites](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md))
- Download Video/Audio in your preffered format (MP4, WEBM, MKV, MP3 etc.)
@@ -25,7 +26,7 @@ Cross-platform Video/Audio Downloader Desktop App with Modern UI and Browser Int
- Network controls (proxy, rate limit etc.)
- Highly customizable and many more...😉
### 🧩 Browser Integration
## 🧩 Browser Integration
You can integrate NeoDLP with your favourite browser (any Chrome/Chromium/Firefox based browser) Just, install [NeoDLP Extension](https://github.com/neosubhamoy/neodlp-extension) to get started!
@@ -35,26 +36,34 @@ After installing the extension you can do the following directly from the browse
- Right Click Context Menu Action (Download with Neo Downloader Plus - Link, Selection, Media Source)
### 👀 Sneak Peek
## 👀 Sneak Peek
![NeoDLP-Mockup](./.github/mockup.svg)
![NeoDLP-Mockup](./.github/images/mockup.svg)
### 💻 Supported Platforms
| Downloader | Completed Downloads | Ongoing Downloads | Settings |
| :---- | :---- | :---- | :---- |
| ![Downloader](./.github/images/downloader.png) | ![Completed-Downloads](./.github/images/completed-downloads.png) | ![Ongoing-Downloads](./.github/images/ongoing-downloads.png) | ![Settings](./.github/images/settings.png) |
## 💻 Supported Platforms
- Windows (10 / 11)
- Linux (Debian / Fedora / Arch Linux base)
- Linux (Debian / Fedora / RHEL / SUSE / Arch Linux base)
- MacOS (>11)
> ⚠️ **NOTE:** Though most linux (debian/fedora/arch base) distros are supported but not all packages are tested on all these platforms, to save some time (and brain cells) and ship the software as fast as possible! (Currently only the debian package is tested on Ubuntu 24.04 LTS - So, other linux packages may have issues, test it yourself and feel free to report issues if you found one)
### 🤝 External Dependencies
## 🤝 External Dependencies
- [YT-DLP](https://github.com/yt-dlp/yt-dlp) - The core CLI tool used to download video/audio from the web (Hero of the show 😎)
- [FFmpeg & FFprobe](https://www.ffmpeg.org) - Used for video/audio post-processing
- [Aria2](https://aria2.github.io) - Used as an external downloader for blazing fast downloads with yt-dlp (Not included with NeoDLP MacOS builds)
- [Deno](https://deno.com) - Provides sandboxed javascript runtime environment for yt-dlp (Required for YT downloads, as per the new yt-dlp [announcement](https://github.com/yt-dlp/yt-dlp/issues/14404))
### ⬇️ Download and Installation
## System Pre-Requirements
- **Windows:** [Microsoft Visual C++ Redistributable 2015+](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170) `winget install Microsoft.VCRedist.2015+.x64` (Will be auto-installed if you install NeoDLP via winget)
- **MacOS:** XCode Command Line Tools `xcode-select --install` (Mostly, comes pre-installed on modern macos, still if you encounter any issue then try installing it manually)
- **Linux:** Most linux packages comes with pre-defined system dependencies which will be auto installed by your package manager (if you are on `fedora` make sure to [enable rpmfusion free+nonfree repos](https://docs.fedoraproject.org/en-US/quick-docs/rpmfusion-setup/#_enabling_the_rpm_fusion_repositories_using_command_line_utilities) before installing the rpm package. also, if you prefer to install dependencies manually [follow this](https://v2.tauri.app/start/prerequisites/#linux))
## ⬇️ Download and Installation
1. Download the latest [NeoDLP](https://github.com/neosubhamoy/neodlp/releases/latest) release based on your OS and CPU Architecture, then install it! -OR- Install it directly from an available distribution channel (listed below)
@@ -63,15 +72,37 @@ After installing the extension you can do the following directly from the browse
| x86_64 | ✅ [Download](https://github.com/neosubhamoy/neodlp/releases/latest) | ✅ [Download](https://github.com/neosubhamoy/neodlp/releases/latest) | ✅ [Download](https://github.com/neosubhamoy/neodlp/releases/latest) |
| ARM64 | ✅ Emulation | ✅ [Download](https://github.com/neosubhamoy/neodlp/releases/latest) | ✅ [Download](https://github.com/neosubhamoy/neodlp/releases/latest) |
> 📌 **NOTE:** x86_64 Windows binary also works on ARM64 (Windows on ARM) devices with emulation (Not planning to release native Windows ARM64 build anytime soon as, x86_64 one works fine on ARM64 without noticeable performance impact)
> [!NOTE]
> x86_64 Windows binary also works on ARM64 (Windows on ARM) devices with emulation (Not planning to release native Windows ARM64 build anytime soon as, x86_64 one works fine on ARM64 without noticeable performance impact)
| Platform (OS) | Distribution Channel | Installation Command / Instruction |
| :---- | :---- | :---- |
| Windows x86_64 / ARM64 | WinGet | `winget install neodlp` |
| MacOS x86_64 / ARM64 | Curl-Bash Installer | `curl -sSL https://neodlp.neosubhamoy.com/neodlp_macos_installer.sh \| bash` |
| Linux x86_64 (Arch Linux) | AUR | `yay -S neodlp` |
| MacOS x86_64 / ARM64 | Curl-Bash Installer | `curl -sSL https://neodlp.neosubhamoy.com/macos_installer.sh \| bash` |
| Linux x86_64 / ARM64 | Curl-Bash Installer | `curl -sSL https://neodlp.neosubhamoy.com/linux_installer.sh \| bash` |
| Arch Linux x86_64 / ARM64 | AUR | `yay -S neodlp` |
### 💝 Support the Development
## 🧪 Package Testing Status
Though NeoDLP is supported on most platforms but not all packages are tested on all platforms, to save some time (and brain cells) and ship the software as fast as possible! Current test coverage is given below. So, untested packages may have issues, test it yourself and always feel free to report any issue on github.
> [!TIP]
> If you have access to any of the untested systems listed below, you can test the packages there and send me the test results via creating an github issue! (that would be super helpful actualy 😊)
| Platform | Status | Platform | Status |
| :---- | :---- | :---- | :---- |
| Windows 10 (x64) | ✅ Tested | Windows 10 (ARM64) | ⚠️ Untested |
| Windows 11 (x64) | ✅ Tested | Windows 11 (ARM64) | ✅ Tested |
| MacOS 14 (x64) | ✅ Tested | MacOS 14 (ARM64) | ✅ Tested |
| MacOS 15 (x64) | ⚠️ Untested | MacOS 15 (ARM64) | ✅ Tested |
| MacOS 26 (x64) | ⚠️ Untested | MacOS 26 (ARM64) | ✅ Tested |
| Ubuntu 24.04 LTS (x64) | ✅ Tested | Ubuntu 24.04 LTS (ARM64) | ⚠️ Untested |
| Fedora 42 (x64) | ✅ Tested | Fedora 42 (ARM64) | ⚠️ Untested |
| Arch Linux (x64) | ✅ Tested | Arch Linux (ARM64) | ✅ Tested |
| openSUSE 16 (x64) | ⚠️ Untested | openSUSE 16 (ARM64) | ⚠️ Untested |
| RHEL 10 (x64) | ⚠️ Untested | RHEL 10 (ARM64) | ⚠️ Untested |
## 💝 Support the Development
NeoDLP is and will be always FREE to Use and Open-Sourced for Everyone. On the other hand the developent process of NeoDLP takes lots of time, effort and even sometimes money! So, if you appriciate my work and have the ability to donate, then please consider supporting the development by donating (even a very small donation matters and helps NeoDLP to be a better product!) Your support is the key to my motivation...🤗
@@ -80,21 +111,23 @@ NeoDLP is and will be always FREE to Use and Open-Sourced for Everyone. On the o
</a>
<br></br>
> 📌 **NOTE:** You can also donate via UPI by sending donations to this UPI ID directly: **subhamoybiswas636-2@oksbi**
> [!NOTE]
> You can also donate via UPI by sending donations to this UPI ID directly: **subhamoybiswas636-2@oksbi**
### 🪜 Roadmap
## 🪜 Roadmap
- [x] Add support for yt-dlp
- [x] Add basic settings and customization
- [x] Integrate with browsers
- [x] Add aria2c support
- [x] Add custom command support
- [ ] Add more advanced settings and achive stability **(ongoing)**
- [ ] Add media converter
- [ ] Add multiple downloader engines
- [ ] Add advanced web extractor
- [ ] Add more cool stuffs 😉
### ⚡ Technologies Used
## ⚡ Technologies Used
![Tauri](https://img.shields.io/badge/tauri-%2324C8DB.svg?style=for-the-badge&logo=tauri&logoColor=%23FFFFFF)
![Rust](https://img.shields.io/badge/rust-%23000000.svg?style=for-the-badge&logo=rust&logoColor=white)
@@ -102,49 +135,50 @@ NeoDLP is and will be always FREE to Use and Open-Sourced for Everyone. On the o
![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)
![ShadCnUi](https://img.shields.io/badge/shadcn%2Fui-000000?style=for-the-badge&logo=shadcnui&logoColor=white)
### 🛠️ Contributing / Building from Source
## 🛠️ Contributing / Building from Source
Want to be part of this? Feel free to contribute...!! Pull Requests are always welcome...!! (^_^) Follow these simple steps to start building:
* Make sure to install [Rust](https://www.rust-lang.org/tools/install), [Node.js](https://nodejs.org/en), [Git](https://git-scm.com/downloads) and [Git-LFS](https://git-lfs.com/) before proceeding.
* Install [Tauri Prerequisites](https://v2.tauri.app/start/prerequisites/) for your OS / platform
1. Fork this repo in your github account.
2. Git clone the forked repo in your local machine.
2. Git clone the forked repo in your local machine. (**NOTE:** I've recently switched from GitHub LFS Server to my own self-hosted LFS Server! Cause GitHub LFS Storage is too expencive for me and NeoDLP requires a lots of LFS bandwidth. So, If you currently clone the repo it will clone the codebase but not the LFS Objects, If you want to clone the LFS Objects unfortunately you have to ask me for auth credentials - which will be only provided to you in certain conditions)
3. Create a git branch (related to the feature you are working on) (Optional - Recommended)
4. Install Node.js dependencies: `npm install`
5. Run development / build process
> ⚠️ **IMPORTANT:** Make sure to run the build command once before running the dev command for the first time to avoid compile time errors
> [!WARNING]
> Make sure to run the `build` command once before running the `dev` command for the first time to avoid compile time errors
```code
# for windows users
npm run tauri dev # for development
npm run tauri dev # for development
npm run tauri build # for production build
# for linux users
npm run tauri dev -- --config "./src-tauri/tauri.linux-aarch64.conf.json" # for ARM64 devices, development
# for linux users (based on cpu architecture)
npm run tauri dev -- --config "./src-tauri/tauri.linux-aarch64.conf.json" # for ARM64 devices, development
npm run tauri build -- --config "./src-tauri/tauri.linux-aarch64.conf.json" # for ARM64 devices, production build
npm run tauri dev -- --config "./src-tauri/tauri.linux-x86_64.conf.json" # for x64 devices, development
npm run tauri build -- --config "./src-tauri/tauri.linux-x86_64.conf.json" # for x64 devices, production build
npm run tauri dev -- --config "./src-tauri/tauri.linux-x86_64.conf.json" # for x64 devices, development
npm run tauri build -- --config "./src-tauri/tauri.linux-x86_64.conf.json" # for x64 devices, production build
# for macOS users (based on cpu architecture)
npm run tauri dev -- --config "./src-tauri/tauri.macos-aarch64.conf.json" # for apple silicon macs, development
npm run tauri dev -- --config "./src-tauri/tauri.macos-aarch64.conf.json" # for apple silicon macs, development
npm run tauri build -- --config "./src-tauri/tauri.macos-aarch64.conf.json" # for apple silicon macs, production build
npm run tauri dev -- --config "./src-tauri/tauri.macos-x86_64.conf.json" # for intel x86 macs, development
npm run tauri build -- --config "./src-tauri/tauri.macos-x86_64.conf.json" # for intel x86 macs, production build
npm run tauri dev -- --config "./src-tauri/tauri.macos-x86_64.conf.json" # for intel x86 macs, development
npm run tauri build -- --config "./src-tauri/tauri.macos-x86_64.conf.json" # for intel x86 macs, production build
```
6. Do the changes, Send a Pull Request with proper Description (NOTE: Pull Requests Without Proper Description will be Rejected)
### ⭕ Bug Report
## ⭕ Bug Report
Noticed any Bug? or Want to give me some suggetion? Always feel free to open a [GitHub Issue](https://github.com/neosubhamoy/neodlp/issues). I would love to hear from you...!!
### 💫 Credits
## 💫 Credits
- NeoDLP's 'Format Selection' options are inspired from the [Seal](https://github.com/JunkFood02/Seal) app by [@JunkFood02](https://github.com/JunkFood02)
- Aria2 Windows x86_64 and Linux x86_64 static binaries are built by [@asdo92](https://github.com/asdo92/aria2-static-builds)
### 📝 License
## 📝 License
NeoDLP is Licensed under the [MIT license](https://github.com/neosubhamoy/neodlp/blob/main/LICENSE). Anyone can view, modify, use (personal and commercial) or distribute it's sources without any attribution and extra permissions.

642
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "neodlp",
"private": true,
"version": "0.3.0",
"version": "0.3.2",
"type": "module",
"scripts": {
"dev": "vite",
@@ -38,16 +38,17 @@
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.2",
"@tanstack/react-query": "^5.90.5",
"@tanstack/react-query-devtools": "^5.90.2",
"@tauri-apps/api": "^2.8.0",
"@tauri-apps/plugin-dialog": "^2.4.0",
"@tauri-apps/plugin-fs": "^2.4.2",
"@tauri-apps/plugin-opener": "^2.5.0",
"@tauri-apps/plugin-os": "^2.3.1",
"@tauri-apps/plugin-process": "^2.3.0",
"@tauri-apps/plugin-shell": "^2.3.1",
"@tauri-apps/plugin-sql": "^2.3.0",
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
"@tauri-apps/plugin-dialog": "^2.4.2",
"@tauri-apps/plugin-fs": "^2.4.4",
"@tauri-apps/plugin-opener": "^2.5.2",
"@tauri-apps/plugin-os": "^2.3.2",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-shell": "^2.3.3",
"@tauri-apps/plugin-sql": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.9.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -55,15 +56,15 @@
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
"lucide-react": "^0.545.0",
"lucide-react": "^0.548.0",
"next-themes": "^0.4.6",
"react": "^19.2.0",
"react-day-picker": "^9.11.0",
"react-day-picker": "^9.11.1",
"react-dom": "^19.2.0",
"react-hook-form": "^7.64.0",
"react-hook-form": "^7.65.0",
"react-resizable-panels": "^3.0.6",
"react-router-dom": "^7.9.3",
"recharts": "^3.2.1",
"react-router-dom": "^7.9.4",
"recharts": "^3.3.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.3.1",
"ulid": "^3.0.1",
@@ -72,17 +73,17 @@
"zustand": "^5.0.8"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.14",
"@tailwindcss/vite": "^4.1.14",
"@tauri-apps/cli": "^2.8.4",
"@types/node": "^24.7.0",
"@tailwindcss/postcss": "^4.1.16",
"@tailwindcss/vite": "^4.1.16",
"@tauri-apps/cli": "^2.9.1",
"@types/node": "^24.9.1",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.1",
"@vitejs/plugin-react": "^5.0.4",
"@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.14",
"tailwindcss": "^4.1.16",
"tw-animate-css": "^1.4.0",
"typescript": "~5.9.3",
"vite": "^7.1.9"
"vite": "^7.1.12"
}
}

View File

@@ -5,10 +5,11 @@ import { execSync } from 'child_process';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
// Define array of binary source directories
const binSrcDirs = [
path.join(__dirname, 'src-tauri', 'binaries'),
path.join(projectRoot, 'src-tauri', 'binaries'),
];
function makeFilesExecutable() {
@@ -46,5 +47,5 @@ function makeFilesExecutable() {
console.log(`\nSummary: Made ${totalCount} files executable across ${successDirs} directories`);
}
console.log(`RUNNING: 🛠️ Build Script makeFilesExecutable.js`);
console.log(`RUNNING: 🛠️ Build Script --> chmod.js`);
makeFilesExecutable();

View File

@@ -5,8 +5,9 @@ import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
console.log(`RUNNING: 🛠️ Build Script updateYtDlpBinary.js`);
console.log(`RUNNING: 🛠️ Build Script --> update-yt-dlp.js`);
// Get the platform triple from command line arguments
const platformTriple = process.argv[2];
@@ -17,7 +18,7 @@ if (!platformTriple) {
}
// Define the binaries directory
const binariesDir = path.join(__dirname, 'src-tauri', 'binaries');
const binariesDir = path.join(projectRoot, 'src-tauri', 'binaries');
// Construct the binary filename based on platform triple
let binaryName = `yt-dlp-${platformTriple}`;

923
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "neodlp"
version = "0.3.0"
version = "0.3.2"
description = "NeoDLP"
authors = ["neosubhamoy <hey@neosubhamoy.com>"]
edition = "2021"
@@ -29,6 +29,7 @@ sqlx = { version = "0.8", features = [ "sqlite", "runtime-tokio", "tls-native-tl
base64 = "0.22"
directories = "6.0"
futures-util = "0.3"
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs" }
tauri-plugin-opener = "2"
tauri-plugin-shell = "2"
tauri-plugin-fs = "2"
@@ -36,6 +37,7 @@ tauri-plugin-os = "2"
tauri-plugin-dialog = "2"
tauri-plugin-sql = { version = "2", features = ["sqlite"] }
tauri-plugin-process = "2"
tauri-plugin-clipboard-manager = "2"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-single-instance = "2"

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1037b241d626483d0048c5ef459aa9fa13cd6bc2bc57d2c7a2aaf7e3b7515f78
size 91614816
oid sha256:b2243469ad3e5d874a2ccf87d3375ea6566c65b9aeae7154de7ad4dd403ef23d
size 91664944

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0716e9b52129cb0e43aa33064f641788650a2162681780590ec67dbca419d74f
size 103264328
oid sha256:f13fc741f238849e8c2d48587ae4eced59abec6864b05b618feb5dc28168baff
size 103329904

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:510c9d6ded38568a13dfb0acdaa178f060ee5cacb37aeb9ae500724e460a8e79
size 102745408
oid sha256:30c6df2176d096fafbdc0f049a68d4a4466360fd8f8daf698d3fc406b0f7a5c7
size 102795504

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:522e54fc5ca4cb42bc9bb7ed952327481c8b6d20149a8d8e7f7b7a604f9ed199
size 117758936
oid sha256:9037f4f141020246aac5f65336cda8127808d644a391df2502f76ef7ea3bdefb
size 117761496

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:df96c25d1804cee25e463d5084a7ded48b6d9d58f8b0d819644a960aa13a7230
size 113525240
oid sha256:d96ceee08834553afb6d6cc6bc76cc3120ce765fe309ce1813b0dd1428c0bce9
size 113570336

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:81eb29b0678f4749cc01934b954f57cdd858c9afce5adf6872394adb5ffb2be2
size 80268888
oid sha256:7717da6f1d21ec928aba5421f3ca83eddba63f6602e80a14901a2935982bf2f0
size 80129848

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9e085bde1b47b05d41b23d3f60526067894ba92ce7eba1668c38d460a37c9bb2
size 137315712
oid sha256:8f0364b1e3db45af96ca1149bc76b6593713446dff28458681302861214a2ca5
size 152316736

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:81eb29b0678f4749cc01934b954f57cdd858c9afce5adf6872394adb5ffb2be2
size 80268888
oid sha256:7717da6f1d21ec928aba5421f3ca83eddba63f6602e80a14901a2935982bf2f0
size 80129848

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7d3403afa6d8510aca69d4b3c99619d972fb4651e4787c2de019f1404a139019
size 175262208
oid sha256:1df43d5ee4c7ef9379f29fdddd9f7c538f6362de478ed4883ac566ad0dd65166
size 190388224

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1058b4d448ddcdd2a7e560f928f0c18197c6f8b8cc25a489a95c5e1989b82d88
size 176215272
oid sha256:3e3b84c425dd3c9f3b88712df0a3cf3ea844fb5968f15ed05eae63a0c2068fc7
size 191335144

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2559a63f05e35f2d2d771a2044c1463d6be1e7f0279e67869d5d9bc658556894
size 80086968
oid sha256:90cae105568f54d029fbaacf25a4879f44b25aaa32fa2ba369696dfeac00d6c9
size 79947928

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b22c9ad49225bf133ccbb9e2a6494ba2b8c83f4c0514b24e06bdb2c6d6fa7427
size 137124736
oid sha256:265c8a8a5b386970facc84e54cb3bfb72579d6729ce0d9b9a64d1ae4864c1274
size 152125760

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2559a63f05e35f2d2d771a2044c1463d6be1e7f0279e67869d5d9bc658556894
size 80086968
oid sha256:90cae105568f54d029fbaacf25a4879f44b25aaa32fa2ba369696dfeac00d6c9
size 79947928

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b49251407a2e2e1a9d00722a89a4163a1f89e128108155585f4ef6c79bcfbd85
size 175064064
oid sha256:19208c2236b754cd359f6397ea1202521d961bba586c2434a0c99d056281aa87
size 190191104

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cbdef955953b157ee366c162746ccafdb4e2bc1a154e8d6d97bf57751b7e6918
size 176011752
oid sha256:f8d7c94d5f600f8acd3555ebb64ce87a410dca9a84bb4ec586ba2c76cb594fdd
size 191123432

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c5d493c97561527824d64327b60221bc2646747c30953423e818715f3cea5c3a
size 35709136
oid sha256:4b8c840bf89c4428ada0c79bbae63e300d889c15efaf09321d42f502689bc5ed
size 35764384

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:45213ee9e85de7ecc4ea4edd4862dbf8cd8899d109c469500b1434ac47f80474
size 37262312
oid sha256:59de22585cc971159674d797a2e094fb0c05a9238bbb8d3f7120f4867dfc699f
size 37285184

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c5d493c97561527824d64327b60221bc2646747c30953423e818715f3cea5c3a
size 35709136
oid sha256:4b8c840bf89c4428ada0c79bbae63e300d889c15efaf09321d42f502689bc5ed
size 35764384

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:619d7fa15ff4cdafbf912530799acf32bb4227b363bc8144cb377d82a9ecb6ac
size 18332203
oid sha256:2f7446c110e4d2ccad95338871cd82d60354a85b82cfe1bc776b67b0deb8db8a
size 18344563

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ab4161f2fa57092a8d5f4448ed5aef1c814aa38cddc37d068aaf91b0a517c2ea
size 37574216
oid sha256:d960d82b390bf63f79863d0a7b51df638ffc5d31e93aae42ba8bcf35927d94a0
size 37600736

View File

@@ -22,6 +22,8 @@
"fs:allow-app-write-recursive",
"updater:default",
"process:default",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text",
{
"identifier": "opener:allow-open-path",
"allow": [

View File

@@ -35,6 +35,11 @@
"args": true,
"sidecar": true
},
{
"name": "ffmpeg",
"cmd": "ffmpeg",
"args": true
},
{
"name": "aria2c",
"cmd": "aria2c",
@@ -75,6 +80,11 @@
"args": true,
"sidecar": true
},
{
"name": "ffmpeg",
"cmd": "ffmpeg",
"args": true
},
{
"name": "aria2c",
"cmd": "aria2c",

View File

@@ -1,8 +1,8 @@
!macro NSIS_HOOK_POSTINSTALL
; Add Registry Keys for Chrome Native Messaging Host
WriteRegStr HKCU "Software\Google\Chrome\NativeMessagingHosts\com.neosubhamoy.neodlp" "" "$INSTDIR\neodlp-msghost.json"
WriteRegStr HKCU "Software\Google\Chrome\NativeMessagingHosts\com.neosubhamoy.neodlp" "" "$INSTDIR\chrome.json"
; Add Registry Keys for Firefox Native Messaging Host
WriteRegStr HKCU "Software\Mozilla\NativeMessagingHosts\com.neosubhamoy.neodlp" "" "$INSTDIR\neodlp-msghost-moz.json"
WriteRegStr HKCU "Software\Mozilla\NativeMessagingHosts\com.neosubhamoy.neodlp" "" "$INSTDIR\firefox.json"
; Add entry for automatic startup with Windows
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${PRODUCTNAME}" "$\"$INSTDIR\neodlp.exe$\" --hidden"
!macroend

View File

@@ -4,10 +4,10 @@
<DirectoryRef Id="TARGETDIR">
<Component Id="NeoDlpRegEntriesFragment" Guid="*">
<RegistryKey Root="HKLM" Key="Software\Google\Chrome\NativeMessagingHosts\com.neosubhamoy.neodlp" Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Value="[INSTALLDIR]neodlp-msghost.json" KeyPath="no" />
<RegistryValue Type="string" Value="[INSTALLDIR]chrome.json" KeyPath="no" />
</RegistryKey>
<RegistryKey Root="HKLM" Key="Software\Mozilla\NativeMessagingHosts\com.neosubhamoy.neodlp" Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Value="[INSTALLDIR]neodlp-msghost-moz.json" KeyPath="no" />
<RegistryValue Type="string" Value="[INSTALLDIR]firefox.json" KeyPath="no" />
</RegistryKey>
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Run">
<RegistryValue Name="NeoDLP" Type="string" Value="&quot;[INSTALLDIR]neodlp.exe&quot; --hidden" KeyPath="no" />

View File

@@ -452,6 +452,7 @@ async fn pause_ongoing_downloads(
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub async fn run() {
let _ = fix_path_env::fix();
let migrations = migrations::get_migrations();
let config = load_config();
let port = config.port;
@@ -485,6 +486,7 @@ pub async fn run() {
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_clipboard_manager::init())
.manage(ImageCache(StdMutex::new(HashMap::new())))
.manage(websocket_state.clone())
.setup(move |app| {

View File

@@ -2,7 +2,7 @@
"$schema": "https://schema.tauri.app/config/2",
"productName": "NeoDLP",
"mainBinaryName": "neodlp",
"version": "0.3.0",
"version": "0.3.2",
"identifier": "com.neosubhamoy.neodlp",
"build": {
"beforeDevCommand": "npm run dev",

View File

@@ -1,8 +1,8 @@
{
"identifier": "com.neosubhamoy.neodlp",
"build": {
"beforeDevCommand": "cargo build --target=aarch64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=aarch64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run build",
"beforeDevCommand": "cargo build --target=aarch64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=aarch64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run build",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},
@@ -37,13 +37,12 @@
],
"externalBin": [
"binaries/yt-dlp",
"binaries/ffmpeg",
"binaries/ffprobe",
"binaries/aria2c",
"binaries/deno"
],
"linux": {
"deb": {
"depends": ["ffmpeg"],
"files": {
"/etc/opt/chrome/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
"/etc/chromium/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
@@ -55,6 +54,7 @@
"rpm": {
"epoch": 0,
"release": "1",
"depends": ["ffmpeg"],
"files": {
"/etc/opt/chrome/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
"/etc/chromium/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",

View File

@@ -1,8 +1,8 @@
{
"identifier": "com.neosubhamoy.neodlp",
"build": {
"beforeDevCommand": "cargo build --target=x86_64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=x86_64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run build",
"beforeDevCommand": "cargo build --target=x86_64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=x86_64-unknown-linux-gnu --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run build",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},
@@ -25,7 +25,7 @@
},
"bundle": {
"active": true,
"targets": ["deb", "rpm"],
"targets": ["deb", "rpm", "appimage"],
"createUpdaterArtifacts": true,
"licenseFile": "../LICENSE",
"icon": [
@@ -37,13 +37,12 @@
],
"externalBin": [
"binaries/yt-dlp",
"binaries/ffmpeg",
"binaries/ffprobe",
"binaries/aria2c",
"binaries/deno"
],
"linux": {
"deb": {
"depends": ["ffmpeg"],
"files": {
"/etc/opt/chrome/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
"/etc/chromium/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
@@ -55,6 +54,7 @@
"rpm": {
"epoch": 0,
"release": "1",
"depends": ["ffmpeg"],
"files": {
"/etc/opt/chrome/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
"/etc/chromium/native-messaging-hosts/com.neosubhamoy.neodlp.json": "./resources/msghost-manifest/linux/chrome.json",
@@ -62,6 +62,12 @@
"/usr/bin/neodlp-msghost": "./target/x86_64-unknown-linux-gnu/release/neodlp-msghost",
"/etc/xdg/autostart/neodlp-autostart.desktop": "./resources/autostart/linux/autostart.desktop"
}
},
"appimage": {
"files": {
"/usr/bin/ffmpeg": "./binaries/ffmpeg-x86_64-unknown-linux-gnu",
"/usr/bin/ffprobe": "./binaries/ffprobe-x86_64-unknown-linux-gnu"
}
}
}
}

View File

@@ -1,8 +1,8 @@
{
"identifier": "com.neosubhamoy.neodlp",
"build": {
"beforeDevCommand": "cargo build --target=aarch64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=aarch64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run build",
"beforeDevCommand": "cargo build --target=aarch64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=aarch64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run build",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},

View File

@@ -1,8 +1,8 @@
{
"identifier": "com.neosubhamoy.neodlp",
"build": {
"beforeDevCommand": "cargo build --target=x86_64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=x86_64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node makeFilesExecutable.js && npm run build",
"beforeDevCommand": "cargo build --target=x86_64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run dev",
"beforeBuildCommand": "cargo build --release --target=x86_64-apple-darwin --manifest-path=./src-tauri/msghost/Cargo.toml && node scripts/chmod.js && npm run build",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},

View File

@@ -44,8 +44,8 @@
],
"resources": {
"target/release/neodlp-msghost.exe": "neodlp-msghost.exe",
"resources/msghost-manifest/windows/chrome.json": "neodlp-msghost.json",
"resources/msghost-manifest/windows/firefox.json": "neodlp-msghost-moz.json"
"resources/msghost-manifest/windows/chrome.json": "chrome.json",
"resources/msghost-manifest/windows/firefox.json": "firefox.json"
},
"windows": {
"wix": {

View File

@@ -88,6 +88,10 @@ export default function App({ children }: { children: React.ReactNode }) {
const USE_CUSTOM_COMMANDS = useSettingsPageStatesStore(state => state.settings.use_custom_commands);
const CUSTOM_COMMANDS = useSettingsPageStatesStore(state => state.settings.custom_commands);
const FILENAME_TEMPLATE = useSettingsPageStatesStore(state => state.settings.filename_template);
const DEBUG_MODE = useSettingsPageStatesStore(state => state.settings.debug_mode);
const LOG_VERBOSE = useSettingsPageStatesStore(state => state.settings.log_verbose);
const LOG_WARNING = useSettingsPageStatesStore(state => state.settings.log_warning);
const LOG_PROGRESS = useSettingsPageStatesStore(state => state.settings.log_progress);
const isErrored = useDownloaderPageStatesStore((state) => state.isErrored);
const isErrorExpected = useDownloaderPageStatesStore((state) => state.isErrorExpected);
@@ -99,6 +103,7 @@ export default function App({ children }: { children: React.ReactNode }) {
const appWindow = getCurrentWebviewWindow()
const navigate = useNavigate();
const LOG = useLogger();
const currentPlatform = platform();
const { updateYtDlp } = useYtDlpUpdater();
const { registerToMac } = useMacOsRegisterer();
const { checkForAppUpdate } = useAppUpdater();
@@ -294,11 +299,22 @@ export default function App({ children }: { children: React.ReactNode }) {
'--format',
selectedFormat,
'--no-mtime',
'--no-warnings',
'--retries',
MAX_RETRIES.toString(),
];
if (currentPlatform === 'macos') {
args.push('--ffmpeg-location', '/Applications/NeoDLP.app/Contents/MacOS');
}
if (!DEBUG_MODE || (DEBUG_MODE && !LOG_WARNING)) {
args.push('--no-warnings');
}
if (DEBUG_MODE && LOG_VERBOSE) {
args.push('--verbose');
}
if (selectedSubtitles) {
args.push('--embed-subs', '--sub-lang', selectedSubtitles);
}
@@ -456,8 +472,8 @@ export default function App({ children }: { children: React.ReactNode }) {
command.stdout.on('data', line => {
if (line.startsWith('status:') || line.startsWith('[#')) {
console.log(line);
LOG.info(`YT-DLP Download ${downloadId}`, line);
// console.log(line);
if (DEBUG_MODE && LOG_PROGRESS) LOG.progress(`YT-DLP Download ${downloadId}`, line);
const currentProgress = parseProgressLine(line);
const state: DownloadState = {
download_id: downloadId,
@@ -517,7 +533,7 @@ export default function App({ children }: { children: React.ReactNode }) {
}
})
} else {
console.log(line);
// console.log(line);
if (line.trim() !== '') LOG.info(`YT-DLP Download ${downloadId}`, line);
if (line.startsWith('Finalpath: ')) {
@@ -648,6 +664,7 @@ export default function App({ children }: { children: React.ReactNode }) {
if (!ongoingDownloads || ongoingDownloads && ongoingDownloads?.length < MAX_PARALLEL_DOWNLOADS) {
LOG.info('NEODLP', `Starting yt-dlp download with args: ${args.join(' ')}`);
if(!DEBUG_MODE || (DEBUG_MODE && !LOG_PROGRESS)) LOG.warning('NEODLP', `Progress logs are hidden. Enable 'Debug Mode > Log Progress' in Settings to unhide.`);
const child = await command.spawn();
processPid = child.pid;
return Promise.resolve();
@@ -1054,7 +1071,6 @@ export default function App({ children }: { children: React.ReactNode }) {
appVersion: appVersion,
registeredVersion: macOsRegisteredVersion
});
const currentPlatform = platform();
if (currentPlatform === 'macos' && (!macOsRegisteredVersion || macOsRegisteredVersion !== appVersion)) {
console.log("Running MacOS auto registration...");
LOG.info('NEODLP', 'Running macOS registration');

View File

@@ -12,7 +12,7 @@ export default function Navbar() {
const logs = useLogger().getLogs();
return (
<nav className="flex justify-between items-center py-3 px-4 sticky top-0 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b z-50">
<nav className="flex justify-between items-center py-3 px-4 sticky top-0 backdrop-blur supports-backdrop-filter:bg-background/60 border-b z-50">
<div className="flex justify-center">
<SidebarTrigger />
<h1 className="text-lg text-primary font-semibold ml-4">{getRouteName(location.pathname)}</h1>
@@ -41,7 +41,7 @@ export default function Navbar() {
<p className="text-sm text-muted-foreground">NO LOGS TO SHOW!</p>
) : (
logs.slice().reverse().map((log, index) => (
<div key={index} className={`flex flex-col ${log.level === 'error' ? 'text-red-500' : log.level === 'warning' ? 'text-amber-500' : log.level === 'debug' ? 'text-sky-500' : 'text-foreground'}`}>
<div key={index} className={`flex flex-col ${log.level === 'error' ? 'text-red-500' : log.level === 'warning' ? 'text-amber-500' : log.level === 'debug' ? 'text-sky-500' : log.level === 'progress' ? 'text-emerald-500' : 'text-foreground'}`}>
<p className="text-xs"><strong>{new Date(log.timestamp).toLocaleTimeString()}</strong> [{log.level.toUpperCase()}] <em>{log.context}</em> :</p>
<p className="text-xs font-mono break-all">{log.message}</p>
</div>

View File

@@ -18,6 +18,9 @@ export function useLogger() {
debug: (context: string, message: string) => {
addLog({ timestamp: Date.now(), level: 'debug', context, message });
},
progress: (context: string, message: string) => {
addLog({ timestamp: Date.now(), level: 'progress', context, message });
},
getLogs: () => logs,
clearLogs,
};

View File

@@ -9,7 +9,7 @@ import { toast } from "sonner";
import { useAppContext } from "@/providers/appContextProvider";
import { useCurrentVideoMetadataStore, useDownloaderPageStatesStore, useSettingsPageStatesStore } from "@/services/store";
import { determineFileType, fileFormatFilter, formatBitrate, formatDurationString, formatFileSize, formatReleaseDate, formatYtStyleCount, isObjEmpty, sortByBitrate } from "@/utils";
import { Calendar, Clock, DownloadCloud, Eye, Info, Loader2, Music, ThumbsUp, Video, File, ListVideo, PackageSearch, AlertCircleIcon, X, Settings2 } from "lucide-react";
import { Calendar, Clock, DownloadCloud, Eye, Info, Loader2, Music, ThumbsUp, Video, File, ListVideo, PackageSearch, AlertCircleIcon, X, Settings2, Clipboard } from "lucide-react";
import { FormatSelectionGroup, FormatSelectionGroupItem } from "@/components/custom/formatSelectionGroup";
import { useEffect, useRef } from "react";
import { ToggleGroup, ToggleGroupItem } from "@/components/custom/legacyToggleGroup";
@@ -29,6 +29,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { readText } from '@tauri-apps/plugin-clipboard-manager';
const searchFormSchema = z.object({
url: z.url({
@@ -391,6 +392,36 @@ export default function DownloaderPage() {
<X className="size-4" />
</Button>
)}
{!isMetadataLoading && !videoUrl && (
<Button
type="button"
size="icon"
disabled={isMetadataLoading}
onClick={async () => {
const text = await readText();
if (text) {
searchForm.setValue("url", text);
setVideoUrl(text);
}
}}
>
<Clipboard className="size-4" />
</Button>
)}
{!isMetadataLoading && videoUrl && (
<Button
type="button"
variant="outline"
size="icon"
disabled={isMetadataLoading}
onClick={() => {
searchForm.setValue("url", '');
setVideoUrl('');
}}
>
<X className="size-4" />
</Button>
)}
<Button
type="submit"
disabled={!videoUrl || Object.keys(searchFormErrors).length > 0 || isMetadataLoading}
@@ -945,7 +976,7 @@ export default function DownloaderPage() {
)}
</div>
<div className="flex flex-col gap-1">
<span className="text-sm text-nowrap max-w-[30rem] xl:max-w-[50rem] overflow-hidden text-ellipsis">{videoMetadata._type === 'video' ? videoMetadata.title : videoMetadata._type === 'playlist' ? videoMetadata.entries[Number(selectedPlaylistVideoIndex) - 1].title : 'Unknown' }</span>
<span className="text-sm text-nowrap max-w-120 xl:max-w-200 overflow-hidden text-ellipsis">{videoMetadata._type === 'video' ? videoMetadata.title : videoMetadata._type === 'playlist' ? videoMetadata.entries[Number(selectedPlaylistVideoIndex) - 1].title : 'Unknown' }</span>
<span className="text-xs text-muted-foreground">{selectedFormatFinalMsg}</span>
</div>
</div>

View File

@@ -6,7 +6,7 @@ import { Progress } from "@/components/ui/progress";
import { Separator } from "@/components/ui/separator";
import { toast } from "sonner";
import { useAppContext } from "@/providers/appContextProvider";
import { useCurrentVideoMetadataStore, useDownloadActionStatesStore, useDownloadStatesStore, useLibraryPageStatesStore } from "@/services/store";
import { useCurrentVideoMetadataStore, useDownloadActionStatesStore, useDownloadStatesStore, useLibraryPageStatesStore, useSettingsPageStatesStore } from "@/services/store";
import { formatBitrate, formatCodec, formatDurationString, formatFileSize, formatSecToTimeString, formatSpeed } from "@/utils";
import { AudioLines, Clock, File, FileAudio2, FileQuestion, FileVideo2, FolderInput, ListVideo, Loader2, Music, Pause, Play, Search, Square, Trash2, Video, X } from "lucide-react";
import { invoke } from "@tauri-apps/api/core";
@@ -34,6 +34,8 @@ export default function LibraryPage() {
const setIsCancelingDownload = useDownloadActionStatesStore(state => state.setIsCancelingDownload);
const setIsDeleteFileChecked = useDownloadActionStatesStore(state => state.setIsDeleteFileChecked);
const debugMode = useSettingsPageStatesStore(state => state.settings.debug_mode);
const { pauseDownload, resumeDownload, cancelDownload } = useAppContext()
const queryClient = useQueryClient();
@@ -379,7 +381,7 @@ export default function LibraryPage() {
</div>
)}
<div className="text-xs text-muted-foreground">{ state.download_status && (
`${state.download_status === 'downloading' && state.status === 'finished' ? 'Processing' : state.download_status.charAt(0).toUpperCase() + state.download_status.slice(1)} ${state.download_id ? `• ID: ${state.download_id.toUpperCase()}` : ""} ${state.download_status === 'downloading' && state.status !== 'finished' && state.speed ? `• Speed: ${formatSpeed(state.speed)}` : ""} ${state.download_status === 'downloading' && state.eta ? `• ETA: ${formatSecToTimeString(state.eta)}` : ""}`
`${state.download_status === 'downloading' && state.status === 'finished' ? 'Processing' : state.download_status.charAt(0).toUpperCase() + state.download_status.slice(1)} ${debugMode && state.download_id ? `• ID: ${state.download_id.toUpperCase()}` : ""} ${state.download_status === 'downloading' && state.status !== 'finished' && state.speed ? `• Speed: ${formatSpeed(state.speed)}` : ""} ${state.download_status === 'downloading' && state.eta ? `• ETA: ${formatSecToTimeString(state.eta)}` : ""}`
)}</div>
</div>
<div className="w-full flex items-center gap-2 mt-2">

View File

@@ -7,7 +7,7 @@ import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";
import { ArrowDownToLine, ArrowRight, BrushCleaning, Cookie, EthernetPort, ExternalLink, FileVideo, Folder, FolderOpen, Info, Loader2, LucideIcon, Monitor, Moon, Radio, RotateCcw, RotateCw, ShieldMinus, SquareTerminal, Sun, Terminal, Trash, TriangleAlert, WandSparkles, Wifi, Wrench } from "lucide-react";
import { ArrowDownToLine, ArrowRight, BrushCleaning, Bug, Cookie, EthernetPort, ExternalLink, FileVideo, Folder, FolderOpen, Info, Loader2, LucideIcon, Monitor, Moon, Radio, RotateCcw, RotateCw, ShieldMinus, SquareTerminal, Sun, Terminal, Trash, TriangleAlert, WandSparkles, Wifi, Wrench } from "lucide-react";
import { cn } from "@/lib/utils";
import { useEffect } from "react";
import { useTheme } from "@/providers/themeProvider";
@@ -123,6 +123,10 @@ export default function SettingsPage() {
const useCustomCommands = useSettingsPageStatesStore(state => state.settings.use_custom_commands);
const customCommands = useSettingsPageStatesStore(state => state.settings.custom_commands);
const filenameTemplate = useSettingsPageStatesStore(state => state.settings.filename_template);
const debugMode = useSettingsPageStatesStore(state => state.settings.debug_mode);
const logVerbose = useSettingsPageStatesStore(state => state.settings.log_verbose);
const logWarning = useSettingsPageStatesStore(state => state.settings.log_warning);
const logProgress = useSettingsPageStatesStore(state => state.settings.log_progress);
const websocketPort = useSettingsPageStatesStore(state => state.settings.websocket_port);
const isChangingWebSocketPort = useSettingsPageStatesStore(state => state.isChangingWebSocketPort);
@@ -525,9 +529,14 @@ export default function SettingsPage() {
value="commands"
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground justify-start px-3 py-1.5 gap-2"
><SquareTerminal className="size-4" /> Commands</TabsTrigger>
<TabsTrigger
key="debug"
value="debug"
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground justify-start px-3 py-1.5 gap-2"
><Bug className="size-4" /> Debug</TabsTrigger>
</TabsList>
<div className="min-h-full flex flex-col max-w-[55%] w-full border-l border-border pl-4">
<TabsContent key="general" value="general" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="general" value="general" className="flex flex-col gap-4 min-h-[385px]">
<div className="max-parallel-downloads">
<h3 className="font-semibold">Max Parallel Downloads</h3>
<p className="text-xs text-muted-foreground mb-3">Set maximum number of allowed parallel downloads</p>
@@ -583,7 +592,7 @@ export default function SettingsPage() {
/>
</div>
</TabsContent>
<TabsContent key="appearance" value="appearance" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="appearance" value="appearance" className="flex flex-col gap-4 min-h-[385px]">
<div className="app-theme">
<h3 className="font-semibold">Theme</h3>
<p className="text-xs text-muted-foreground mb-3">Choose app interface theme</p>
@@ -606,7 +615,7 @@ export default function SettingsPage() {
</div>
</div>
</TabsContent>
<TabsContent key="folders" value="folders" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="folders" value="folders" className="flex flex-col gap-4 min-h-[385px]">
<div className="download-dir">
<h3 className="font-semibold">Download Folder</h3>
<p className="text-xs text-muted-foreground mb-3">Set default download folder (directory)</p>
@@ -696,7 +705,7 @@ export default function SettingsPage() {
</Form>
</div>
</TabsContent>
<TabsContent key="formats" value="formats" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="formats" value="formats" className="flex flex-col gap-4 min-h-[385px]">
<div className="video-format">
<h3 className="font-semibold">Video Format</h3>
<p className="text-xs text-muted-foreground mb-3">Choose in which format the final video file will be saved</p>
@@ -764,7 +773,7 @@ export default function SettingsPage() {
/>
</div>
</TabsContent>
<TabsContent key="metadata" value="metadata" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="metadata" value="metadata" className="flex flex-col gap-4 min-h-[385px]">
<div className="embed-video-metadata">
<h3 className="font-semibold">Embed Metadata</h3>
<p className="text-xs text-muted-foreground mb-3">Wheather to embed metadata in video/audio files (info, chapters)</p>
@@ -798,7 +807,7 @@ export default function SettingsPage() {
/>
</div>
</TabsContent>
<TabsContent key="network" value="network" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="network" value="network" className="flex flex-col gap-4 min-h-[385px]">
<div className="proxy">
<h3 className="font-semibold">Proxy</h3>
<p className="text-xs text-muted-foreground mb-3">Use proxy for downloads, Unblocks blocked sites in your region (download speed may affect, some sites may not work)</p>
@@ -893,7 +902,7 @@ export default function SettingsPage() {
onCheckedChange={(checked) => saveSettingsKey('use_force_internet_protocol', checked)}
disabled={useCustomCommands}
/>
<Label htmlFor="use-force-internet-protocol">Force</Label>
<Label htmlFor="use-force-internet-protocol">Force IPV</Label>
</div>
<RadioGroup
orientation="horizontal"
@@ -914,7 +923,7 @@ export default function SettingsPage() {
<Label className="text-xs text-muted-foreground">(Forced: {forceInternetProtocol === "ipv4" ? 'IPv4' : 'IPv6'}, Status: {useForceInternetProtocol && !useCustomCommands ? 'Enabled' : 'Disabled'})</Label>
</div>
</TabsContent>
<TabsContent key="cookies" value="cookies" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="cookies" value="cookies" className="flex flex-col gap-4 min-h-[385px]">
<div className="cookies">
<h3 className="font-semibold">Cookies</h3>
<p className="text-xs text-muted-foreground mb-3">Use cookies to access exclusive/private (login-protected) contents from sites (use wisely, over-use can even block/ban your account)</p>
@@ -1003,7 +1012,7 @@ export default function SettingsPage() {
<Label className="text-xs text-muted-foreground">(Configured: {importCookiesFrom === "browser" ? 'Yes' : cookiesFile ? 'Yes' : 'No'}, From: {importCookiesFrom === "browser" ? 'Browser' : 'Text'}, Status: {useCookies && !useCustomCommands ? 'Enabled' : 'Disabled'})</Label>
</div>
</TabsContent>
<TabsContent key="sponsorblock" value="sponsorblock" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="sponsorblock" value="sponsorblock" className="flex flex-col gap-4 min-h-[385px]">
<div className="sponsorblock">
<h3 className="font-semibold">Sponsor Block</h3>
<p className="text-xs text-muted-foreground mb-3">Use sponsorblock to remove/mark unwanted segments in videos (sponsorships, intros, outros, etc.)</p>
@@ -1127,7 +1136,7 @@ export default function SettingsPage() {
<Label className="text-xs text-muted-foreground">(Configured: {sponsorblockMode === "remove" && sponsorblockRemove === "custom" && sponsorblockRemoveCategories.length <= 0 ? 'No' : sponsorblockMode === "mark" && sponsorblockMark === "custom" && sponsorblockMarkCategories.length <= 0 ? 'No' : 'Yes'}, Mode: {sponsorblockMode === "remove" ? 'Remove' : 'Mark'}, Status: {useSponsorblock && !useCustomCommands ? 'Enabled' : 'Disabled'})</Label>
</div>
</TabsContent>
<TabsContent key="commands" value="commands" className="flex flex-col gap-4 min-h-[350px]">
<TabsContent key="commands" value="commands" className="flex flex-col gap-4 min-h-[385px]">
<div className="custom-commands">
<h3 className="font-semibold">Custom Commands</h3>
<p className="text-xs text-muted-foreground mb-3"> Run custom yt-dlp commands for your downloads</p>
@@ -1229,6 +1238,50 @@ export default function SettingsPage() {
</div>
</div>
</TabsContent>
<TabsContent key="debug" value="debug" className="flex flex-col gap-4 min-h-[385px]">
<div className="debug-mode">
<h3 className="font-semibold">Debug Mode</h3>
<p className="text-xs text-muted-foreground mb-3">Enable debug mode for troubleshooting issues (get debug logs, download ids, and more)</p>
<div className="flex items-center space-x-2 mb-4">
<Switch
id="debug-mode"
checked={debugMode}
onCheckedChange={(checked) => saveSettingsKey('debug_mode', checked)}
/>
<Label htmlFor="debug-mode">Enable Debug Mode</Label>
</div>
<div className="flex flex-col gap-2 mt-5">
<Label className="text-xs mb-1">Logging Options</Label>
<div className="flex items-center space-x-2 mb-1">
<Switch
id="log-verbose"
checked={logVerbose}
onCheckedChange={(checked) => saveSettingsKey('log_verbose', checked)}
disabled={!debugMode}
/>
<Label htmlFor="log-verbose">Verbose Logging</Label>
</div>
<div className="flex items-center space-x-2 mb-1">
<Switch
id="log-warning"
checked={logWarning}
onCheckedChange={(checked) => saveSettingsKey('log_warning', checked)}
disabled={!debugMode}
/>
<Label htmlFor="log-warning">Log Warnings</Label>
</div>
<div className="flex items-center space-x-2 mb-1">
<Switch
id="log-progress"
checked={logProgress}
onCheckedChange={(checked) => saveSettingsKey('log_progress', checked)}
disabled={!debugMode}
/>
<Label htmlFor="log-progress">Log Progress</Label>
</div>
</div>
</div>
</TabsContent>
</div>
</Tabs>
</TabsContent>

View File

@@ -180,6 +180,10 @@ export const useSettingsPageStatesStore = create<SettingsPageStatesStore>((set)
use_custom_commands: false,
custom_commands: [],
filename_template: '%(title)s_%(resolution|unknown)s',
debug_mode: false,
log_verbose: true,
log_warning: true,
log_progress: false,
// extension settings
websocket_port: 53511
},
@@ -241,6 +245,10 @@ export const useSettingsPageStatesStore = create<SettingsPageStatesStore>((set)
use_custom_commands: false,
custom_commands: [],
filename_template: '%(title)s_%(resolution|unknown)s',
debug_mode: false,
log_verbose: true,
log_warning: true,
log_progress: false,
// extension settings
websocket_port: 53511
},

View File

@@ -1,6 +1,6 @@
export interface Log {
timestamp: number;
level: 'info' | 'warning' | 'error' | 'debug';
level: 'info' | 'warning' | 'error' | 'debug' | 'progress';
context: string;
message: string;
}

View File

@@ -44,6 +44,10 @@ export interface Settings {
use_custom_commands: boolean;
custom_commands: CustomCommand[];
filename_template: string;
debug_mode: boolean;
log_verbose: boolean;
log_warning: boolean;
log_progress: boolean;
// extension settings
websocket_port: number;
}