├── CNAME ├── devenv.yaml ├── public ├── logo.png └── favicon.ico ├── .vscode └── extensions.json ├── jsconfig.json ├── .envrc ├── src ├── main.js ├── components │ ├── ThankYou.vue │ ├── icons │ │ ├── IconSupport.vue │ │ ├── IconTooling.vue │ │ ├── IconCommunity.vue │ │ ├── IconDocumentation.vue │ │ └── IconEcosystem.vue │ ├── Footer.vue │ ├── Header.vue │ ├── DarkModeToggle.vue │ ├── FAQ.vue │ ├── Authentication.vue │ ├── Summary.vue │ ├── AddonItem.vue │ ├── Configuration.vue │ └── DynamicForm.vue ├── assets │ └── main.css └── App.vue ├── Dockerfile ├── vite.config.js ├── package.json ├── .gitignore ├── index.html ├── devenv.nix ├── README.md ├── .github └── workflows │ ├── deploy.yml │ └── docker-publish.yml └── devenv.lock /CNAME: -------------------------------------------------------------------------------- 1 | addon-manager.viren070.me 2 | -------------------------------------------------------------------------------- /devenv.yaml: -------------------------------------------------------------------------------- 1 | inputs: 2 | nixpkgs: 3 | url: github:NixOS/nixpkgs/nixpkgs-unstable 4 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Viren070/stremio-addon-manager/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Viren070/stremio-addon-manager/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | }, 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | source_url "https://raw.githubusercontent.com/cachix/devenv/d1f7b48e35e6dee421cfd0f51481d17f77586997/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" 2 | 3 | use devenv -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import './assets/main.css' 2 | 3 | import { createApp } from 'vue' 4 | import { inject } from '@vercel/analytics'; 5 | import App from './App.vue' 6 | 7 | inject(); 8 | createApp(App).mount('#app') 9 | -------------------------------------------------------------------------------- /src/components/ThankYou.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine as builder 2 | 3 | WORKDIR /app 4 | 5 | COPY package*.json /app 6 | RUN npm install 7 | 8 | COPY . . 9 | RUN npm run build 10 | 11 | FROM nginx:stable-alpine as production-stage 12 | 13 | COPY --from=builder /app/dist /usr/share/nginx/html 14 | 15 | EXPOSE 80 16 | 17 | CMD ["nginx", "-g", "daemon off;"] 18 | -------------------------------------------------------------------------------- /src/components/Footer.vue: -------------------------------------------------------------------------------- 1 | 3 | 4 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | vue(), 10 | ], 11 | resolve: { 12 | alias: { 13 | '@': fileURLToPath(new URL('./src', import.meta.url)) 14 | } 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stremio-addon-manager", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@vercel/analytics": "^1.1.2", 13 | "chota": "^0.9.2", 14 | "vue": "^3.4.15", 15 | "vuedraggable": "^4.1.0" 16 | }, 17 | "devDependencies": { 18 | "@vitejs/plugin-vue": "^5.0.3", 19 | "vite": "^5.0.11" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Devenv 2 | .devenv* 3 | devenv.local.nix 4 | 5 | # Direnv 6 | .direnv 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | lerna-debug.log* 16 | 17 | node_modules 18 | .DS_Store 19 | dist 20 | dist-ssr 21 | coverage 22 | *.local 23 | 24 | /cypress/videos/ 25 | /cypress/screenshots/ 26 | 27 | # Editor directories and files 28 | .vscode/* 29 | !.vscode/extensions.json 30 | .idea 31 | *.suo 32 | *.ntvs* 33 | *.njsproj 34 | *.sln 35 | *.sw? 36 | 37 | *.tsbuildinfo 38 | -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | body.dark { 2 | --bg-color: #262626; 3 | --bg-secondary-color: #131316; 4 | --font-color: #f5f5f5; 5 | --color-grey: #777; 6 | --color-darkGrey: #555; 7 | --color-lightGrey: #555; 8 | } 9 | 10 | body>.container { 11 | max-width: 720px; 12 | } 13 | 14 | section { 15 | margin: 5rem auto; 16 | } 17 | 18 | input, 19 | .sortable-list { 20 | background-color: var(--bg-secondary-color); 21 | } 22 | 23 | details>summary { 24 | cursor: pointer; 25 | } 26 | 27 | input::placeholder, 28 | input { 29 | color: var(--font-color); 30 | } 31 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Stremio Addon Manager 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /devenv.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | # https://devenv.sh/basics/ 5 | env.GREET = "devenv"; 6 | 7 | # https://devenv.sh/packages/ 8 | packages = [ pkgs.git ]; 9 | 10 | # https://devenv.sh/scripts/ 11 | scripts.hello.exec = "echo hello from $GREET"; 12 | 13 | enterShell = '' 14 | hello 15 | git --version 16 | ''; 17 | 18 | # https://devenv.sh/languages/ 19 | languages.nix.enable = true; 20 | languages.javascript.enable = true; 21 | 22 | # https://devenv.sh/pre-commit-hooks/ 23 | # pre-commit.hooks.shellcheck.enable = true; 24 | 25 | # https://devenv.sh/processes/ 26 | # processes.ping.exec = "ping example.com"; 27 | 28 | # See full reference at https://devenv.sh/reference/options/ 29 | } 30 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 29 | -------------------------------------------------------------------------------- /src/components/Header.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 32 | 33 | 50 | -------------------------------------------------------------------------------- /src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stremio Addon Manager 2 | Manage your Stremio addons with ease. 3 | 4 | **WARNING: Use this at your own risk. This is not an official Stremio product and may break your Stremio installation. No support or warranty is given.** 5 | 6 | ## Features 7 | - Re-order your addons (including Cinemeta) 8 | - Remove non-protected addons 9 | 10 | ## Recommended IDE Setup 11 | 12 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) 13 | 14 | ## Project Setup 15 | 16 | ```sh 17 | npm install 18 | ``` 19 | 20 | ### Compile and Hot-Reload for Development 21 | 22 | ```sh 23 | npm run dev 24 | ``` 25 | 26 | ### Compile and Minify for Production 27 | 28 | ```sh 29 | npm run build 30 | ``` 31 | 32 | ## Docker 33 | Run the following commands to build and run the app in a Docker container: 34 | 35 | ```bash 36 | $ docker build -t stremio-addon-manager . 37 | $ docker run -p 8080:80 stremio-addon-manager 38 | ``` 39 | 40 | The app will be accessible at `http://localhost:8080`. 41 | 42 | ## Thanks 43 | Big thank you to `Sleeyax` and `` for the conversations and code snippets that made this really easy to implement. 44 | -------------------------------------------------------------------------------- /src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | name: Build site 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version: 18 19 | cache: npm 20 | 21 | - name: Install dependencies 22 | run: npm ci 23 | - name: Build website 24 | run: npm run build 25 | 26 | - name: Upload Build Artifact 27 | uses: actions/upload-pages-artifact@v3 28 | with: 29 | path: dist 30 | 31 | deploy: 32 | name: Deploy to GitHub Pages 33 | needs: build 34 | 35 | # Grant GITHUB_TOKEN the permissions required to make a Pages deployment 36 | permissions: 37 | pages: write # to deploy to Pages 38 | id-token: write # to verify the deployment originates from an appropriate source 39 | 40 | # Deploy to the github-pages environment 41 | environment: 42 | name: github-pages 43 | url: ${{ steps.deployment.outputs.page_url }} 44 | 45 | runs-on: ubuntu-latest 46 | steps: 47 | - name: Deploy to GitHub Pages 48 | id: deployment 49 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /src/components/DarkModeToggle.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 48 | -------------------------------------------------------------------------------- /src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/FAQ.vue: -------------------------------------------------------------------------------- 1 | 57 | -------------------------------------------------------------------------------- /src/components/Authentication.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 65 | 66 | 101 | -------------------------------------------------------------------------------- /src/components/Summary.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 83 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | # This workflow uses actions that are not certified by GitHub. 4 | # They are provided by a third-party and are governed by 5 | # separate terms of service, privacy policy, and support 6 | # documentation. 7 | 8 | on: 9 | schedule: 10 | - cron: '38 11 * * *' 11 | push: 12 | branches: [ "main" ] 13 | # Publish semver tags as releases. 14 | tags: [ 'v*.*.*' ] 15 | 16 | env: 17 | # Use docker.io for Docker Hub if empty 18 | REGISTRY: docker.io 19 | # github.repository as / 20 | IMAGE_NAME: ${{ github.repository }} 21 | 22 | 23 | jobs: 24 | build: 25 | 26 | runs-on: ubuntu-latest 27 | permissions: 28 | contents: read 29 | packages: write 30 | # This is used to complete the identity challenge 31 | # with sigstore/fulcio when running outside of PRs. 32 | id-token: write 33 | 34 | steps: 35 | - name: Checkout repository 36 | uses: actions/checkout@v3 37 | 38 | # Install the cosign tool except on PR 39 | # https://github.com/sigstore/cosign-installer 40 | - name: Install cosign 41 | if: github.event_name != 'pull_request' 42 | uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 43 | with: 44 | cosign-release: 'v2.1.1' 45 | 46 | # Set up BuildKit Docker container builder to be able to build 47 | # multi-platform images and export cache 48 | # https://github.com/docker/setup-buildx-action 49 | - name: Set up Docker Buildx 50 | uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 51 | 52 | # Login against a Docker registry except on PR 53 | # https://github.com/docker/login-action 54 | - name: Log into registry ${{ env.REGISTRY }} 55 | if: github.event_name != 'pull_request' 56 | uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 57 | with: 58 | registry: ${{ env.REGISTRY }} 59 | username: ${{ secrets.DOCKERHUB_USERNAME }} 60 | password: ${{ secrets.DOCKERHUB_TOKEN }} 61 | 62 | # Extract metadata (tags, labels) for Docker 63 | # https://github.com/docker/metadata-action 64 | - name: Extract Docker metadata 65 | id: meta 66 | uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 67 | with: 68 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 69 | 70 | # Build and push Docker image with Buildx (don't push on PR) 71 | # https://github.com/docker/build-push-action 72 | - name: Build and push Docker image 73 | id: build-and-push 74 | uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 75 | with: 76 | context: . 77 | platforms: linux/amd64,linux/arm64 78 | push: ${{ github.event_name != 'pull_request' }} 79 | tags: ${{ steps.meta.outputs.tags }} 80 | labels: ${{ steps.meta.outputs.labels }} 81 | cache-from: type=gha 82 | cache-to: type=gha,mode=max 83 | 84 | # Sign the resulting Docker image digest except on PRs. 85 | # This will only write to the public Rekor transparency log when the Docker 86 | # repository is public to avoid leaking data. If you would like to publish 87 | # transparency data even for private images, pass --force to cosign below. 88 | # https://github.com/sigstore/cosign 89 | - name: Sign the published Docker image 90 | if: ${{ github.event_name != 'pull_request' }} 91 | env: 92 | # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable 93 | TAGS: ${{ steps.meta.outputs.tags }} 94 | DIGEST: ${{ steps.build-and-push.outputs.digest }} 95 | # This step uses the identity token to provision an ephemeral certificate 96 | # against the sigstore community Fulcio instance. 97 | run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} 98 | -------------------------------------------------------------------------------- /devenv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "devenv": { 4 | "locked": { 5 | "dir": "src/modules", 6 | "lastModified": 1706018268, 7 | "narHash": "sha256-d24+re0t8b6HYGzAPZCIJed85n23RUFXQa2yuHoW0uQ=", 8 | "owner": "cachix", 9 | "repo": "devenv", 10 | "rev": "ad0ae333b210e31237e1fc4a7ddab71a01785add", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "dir": "src/modules", 15 | "owner": "cachix", 16 | "repo": "devenv", 17 | "type": "github" 18 | } 19 | }, 20 | "flake-compat": { 21 | "flake": false, 22 | "locked": { 23 | "lastModified": 1696426674, 24 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 25 | "owner": "edolstra", 26 | "repo": "flake-compat", 27 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "edolstra", 32 | "repo": "flake-compat", 33 | "type": "github" 34 | } 35 | }, 36 | "flake-utils": { 37 | "inputs": { 38 | "systems": "systems" 39 | }, 40 | "locked": { 41 | "lastModified": 1701680307, 42 | "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", 43 | "owner": "numtide", 44 | "repo": "flake-utils", 45 | "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", 46 | "type": "github" 47 | }, 48 | "original": { 49 | "owner": "numtide", 50 | "repo": "flake-utils", 51 | "type": "github" 52 | } 53 | }, 54 | "gitignore": { 55 | "inputs": { 56 | "nixpkgs": [ 57 | "pre-commit-hooks", 58 | "nixpkgs" 59 | ] 60 | }, 61 | "locked": { 62 | "lastModified": 1703887061, 63 | "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", 64 | "owner": "hercules-ci", 65 | "repo": "gitignore.nix", 66 | "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", 67 | "type": "github" 68 | }, 69 | "original": { 70 | "owner": "hercules-ci", 71 | "repo": "gitignore.nix", 72 | "type": "github" 73 | } 74 | }, 75 | "nixpkgs": { 76 | "locked": { 77 | "lastModified": 1706683685, 78 | "narHash": "sha256-FtPPshEpxH/ewBOsdKBNhlsL2MLEFv1hEnQ19f/bFsQ=", 79 | "owner": "NixOS", 80 | "repo": "nixpkgs", 81 | "rev": "5ad9903c16126a7d949101687af0aa589b1d7d3d", 82 | "type": "github" 83 | }, 84 | "original": { 85 | "owner": "NixOS", 86 | "ref": "nixpkgs-unstable", 87 | "repo": "nixpkgs", 88 | "type": "github" 89 | } 90 | }, 91 | "nixpkgs-stable": { 92 | "locked": { 93 | "lastModified": 1704874635, 94 | "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", 95 | "owner": "NixOS", 96 | "repo": "nixpkgs", 97 | "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", 98 | "type": "github" 99 | }, 100 | "original": { 101 | "owner": "NixOS", 102 | "ref": "nixos-23.11", 103 | "repo": "nixpkgs", 104 | "type": "github" 105 | } 106 | }, 107 | "pre-commit-hooks": { 108 | "inputs": { 109 | "flake-compat": "flake-compat", 110 | "flake-utils": "flake-utils", 111 | "gitignore": "gitignore", 112 | "nixpkgs": [ 113 | "nixpkgs" 114 | ], 115 | "nixpkgs-stable": "nixpkgs-stable" 116 | }, 117 | "locked": { 118 | "lastModified": 1706424699, 119 | "narHash": "sha256-Q3RBuOpZNH2eFA1e+IHgZLAOqDD9SKhJ/sszrL8bQD4=", 120 | "owner": "cachix", 121 | "repo": "pre-commit-hooks.nix", 122 | "rev": "7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf", 123 | "type": "github" 124 | }, 125 | "original": { 126 | "owner": "cachix", 127 | "repo": "pre-commit-hooks.nix", 128 | "type": "github" 129 | } 130 | }, 131 | "root": { 132 | "inputs": { 133 | "devenv": "devenv", 134 | "nixpkgs": "nixpkgs", 135 | "pre-commit-hooks": "pre-commit-hooks" 136 | } 137 | }, 138 | "systems": { 139 | "locked": { 140 | "lastModified": 1681028828, 141 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 142 | "owner": "nix-systems", 143 | "repo": "default", 144 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 145 | "type": "github" 146 | }, 147 | "original": { 148 | "owner": "nix-systems", 149 | "repo": "default", 150 | "type": "github" 151 | } 152 | } 153 | }, 154 | "root": "root", 155 | "version": 7 156 | } 157 | -------------------------------------------------------------------------------- /src/components/AddonItem.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 87 | 88 | 215 | -------------------------------------------------------------------------------- /src/components/Configuration.vue: -------------------------------------------------------------------------------- 1 | 128 | 129 | 172 | 173 | 227 | -------------------------------------------------------------------------------- /src/components/DynamicForm.vue: -------------------------------------------------------------------------------- 1 | 77 | 78 | 154 | 155 | 322 | --------------------------------------------------------------------------------