mirror of
https://github.com/KevinMidboe/seasoned.git
synced 2026-03-11 03:49:07 +00:00
Feat: vite & upgraded dependencies (#100)
* On every route change, update local variables from query params * ResultSection is keyed to query to force re-render * Resolved lint warnings * replace webpack w/ vite * update all imports with alias @ and scss * vite environment variables, also typed * upgraded eslint, defined new rules & added ignore comments * resolved linting issues * moved index.html to project root * updated dockerfile w/ build stage before runtime image definition * sign drone config
This commit is contained in:
21
.drone.yml
21
.drone.yml
@@ -25,7 +25,7 @@ steps:
|
|||||||
path: /cache
|
path: /cache
|
||||||
|
|
||||||
- name: Frontend install
|
- name: Frontend install
|
||||||
image: node:18.2.0
|
image: node:24.13.1
|
||||||
commands:
|
commands:
|
||||||
- node -v
|
- node -v
|
||||||
- yarn --version
|
- yarn --version
|
||||||
@@ -42,8 +42,14 @@ steps:
|
|||||||
- name: cache
|
- name: cache
|
||||||
path: /cache
|
path: /cache
|
||||||
|
|
||||||
|
- name: Lint project using eslint
|
||||||
|
image: node:24.13.1
|
||||||
|
commands:
|
||||||
|
- yarn lint
|
||||||
|
failure: ignore
|
||||||
|
|
||||||
- name: Frontend build
|
- name: Frontend build
|
||||||
image: node:18.2.0
|
image: node:24.13.1
|
||||||
commands:
|
commands:
|
||||||
- yarn build
|
- yarn build
|
||||||
environment:
|
environment:
|
||||||
@@ -56,12 +62,6 @@ steps:
|
|||||||
SEASONED_DOMAIN:
|
SEASONED_DOMAIN:
|
||||||
from_secret: SEASONED_DOMAIN
|
from_secret: SEASONED_DOMAIN
|
||||||
|
|
||||||
- name: Lint project using eslint
|
|
||||||
image: node:18.2.0
|
|
||||||
commands:
|
|
||||||
- yarn lint
|
|
||||||
failure: ignore
|
|
||||||
|
|
||||||
- name: Build and publish docker image
|
- name: Build and publish docker image
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
settings:
|
settings:
|
||||||
@@ -105,3 +105,8 @@ trigger:
|
|||||||
include:
|
include:
|
||||||
- push
|
- push
|
||||||
# - pull_request
|
# - pull_request
|
||||||
|
---
|
||||||
|
kind: signature
|
||||||
|
hmac: 6f10b2871d2bd6b5cd26ddf72796325991ba211ba1eb62b657baf993e9d549c8
|
||||||
|
|
||||||
|
...
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
SEASONED_API=
|
SEASONED_API=http://localhost:31459
|
||||||
ELASTIC=
|
ELASTIC_URL=http://elastic.local:9200/tmdb-movies-shows
|
||||||
ELASTIC_INDEX=shows,movies
|
ELASTIC_API_KEY=
|
||||||
SEASONED_DOMAIN=
|
|
||||||
|
|||||||
31
.eslintrc
31
.eslintrc
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
"parser": "vue-eslint-parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"plugins": [
|
|
||||||
"@typescript-eslint"
|
|
||||||
],
|
|
||||||
"extends": [
|
|
||||||
"@vue/eslint-config-airbnb",
|
|
||||||
"plugin:vue/recommended",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"plugin:prettier/recommended",
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"vue/no-v-model-argument": "off",
|
|
||||||
"no-underscore-dangle": "off",
|
|
||||||
"vue/multi-word-component-names": "off",
|
|
||||||
"no-shadow": "off",
|
|
||||||
"@typescript-eslint/no-shadow": ["error"],
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"import/resolver": {
|
|
||||||
webpack: {
|
|
||||||
config: "./webpack.config.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ src/config.json
|
|||||||
|
|
||||||
# Build directory
|
# Build directory
|
||||||
dist/
|
dist/
|
||||||
|
lib/
|
||||||
|
|
||||||
# Node packages
|
# Node packages
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|||||||
36
Dockerfile
36
Dockerfile
@@ -1,7 +1,39 @@
|
|||||||
FROM nginx:latest
|
FROM node:24.13.1 AS build
|
||||||
|
|
||||||
COPY public /usr/share/nginx/html
|
# Set the working directory for the build stage
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
COPY package.json yarn.lock .
|
||||||
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
|
# Copy source files that the build depends on
|
||||||
|
COPY index.html .
|
||||||
|
COPY public/ public/
|
||||||
|
COPY src/ src/
|
||||||
|
COPY tsconfig.json vite.config.ts .
|
||||||
|
|
||||||
|
ARG SEASONED_API=http://localhost:31459
|
||||||
|
ENV VITE_SEASONED_API=$SEASONED_API
|
||||||
|
|
||||||
|
ARG ELASTIC_URL=http://elastic.local:9200/tmdb-movies-shows
|
||||||
|
ENV VITE_ELASTIC_URL=$ELASTIC_URL
|
||||||
|
ARG ELASTIC_API_KEY=
|
||||||
|
ENV VITE_ELASTIC_API_KEY=$ELASTIC_API_KEY
|
||||||
|
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
FROM nginx:1.29.5
|
||||||
|
|
||||||
|
# Copy the static build from the previous stage
|
||||||
|
COPY index.html /usr/share/nginx/html
|
||||||
|
COPY public/ /usr/share/nginx/html
|
||||||
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy nginx config file
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf.template
|
COPY nginx.conf /etc/nginx/conf.d/default.conf.template
|
||||||
|
|
||||||
|
# Manual entrypoint after nginx substring
|
||||||
COPY docker-entrypoint.sh /docker-entrypoint.d/05-docker-entrypoint.sh
|
COPY docker-entrypoint.sh /docker-entrypoint.d/05-docker-entrypoint.sh
|
||||||
|
|
||||||
RUN chmod +x /docker-entrypoint.d/05-docker-entrypoint.sh
|
RUN chmod +x /docker-entrypoint.d/05-docker-entrypoint.sh
|
||||||
|
|||||||
67
eslint.config.mjs
Normal file
67
eslint.config.mjs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
|
||||||
|
import { includeIgnoreFile } from "@eslint/compat";
|
||||||
|
import js from "@eslint/js";
|
||||||
|
import { defineConfig } from "eslint/config";
|
||||||
|
import { configs, plugins } from "eslint-config-airbnb-extended";
|
||||||
|
import { rules as prettierConfigRules } from "eslint-config-prettier";
|
||||||
|
import prettierPlugin from "eslint-plugin-prettier";
|
||||||
|
|
||||||
|
const CUSTOM_RULES = {
|
||||||
|
"vue/no-v-model-argument": "off",
|
||||||
|
"no-underscore-dangle": "off",
|
||||||
|
"vue/multi-word-component-names": "off",
|
||||||
|
"no-shadow": "off",
|
||||||
|
"@typescript-eslint/no-shadow": ["error"]
|
||||||
|
};
|
||||||
|
|
||||||
|
const gitignorePath = path.resolve(".", ".gitignore");
|
||||||
|
|
||||||
|
// ESLint recommended config
|
||||||
|
const jsConfig = defineConfig([
|
||||||
|
{
|
||||||
|
name: "js/config",
|
||||||
|
...js.configs.recommended
|
||||||
|
},
|
||||||
|
plugins.stylistic,
|
||||||
|
plugins.importX,
|
||||||
|
...configs.base.recommended // Airbnb base recommended config
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Node & Airbnb recommended config
|
||||||
|
const nodeConfig = defineConfig([plugins.node, ...configs.node.recommended]);
|
||||||
|
|
||||||
|
// Typescript & Airbnb base TS config
|
||||||
|
const typescriptConfig = defineConfig([
|
||||||
|
plugins.typescriptEslint,
|
||||||
|
...configs.base.typescript
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Prettier config
|
||||||
|
const prettierConfig = defineConfig([
|
||||||
|
{
|
||||||
|
name: "prettier/plugin/config",
|
||||||
|
plugins: {
|
||||||
|
prettier: prettierPlugin
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prettier/config",
|
||||||
|
rules: {
|
||||||
|
...prettierConfigRules,
|
||||||
|
"prettier/prettier": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
// Ignore files and folders listed in .gitignore
|
||||||
|
includeIgnoreFile(gitignorePath),
|
||||||
|
...jsConfig,
|
||||||
|
...nodeConfig,
|
||||||
|
...typescriptConfig,
|
||||||
|
...prettierConfig,
|
||||||
|
{
|
||||||
|
rules: CUSTOM_RULES
|
||||||
|
}
|
||||||
|
]);
|
||||||
@@ -24,7 +24,9 @@
|
|||||||
<meta name="theme-color" content="#081c24" />
|
<meta name="theme-color" content="#081c24" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="entry"></div>
|
<div id="app"></div>
|
||||||
|
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script
|
<script
|
||||||
@@ -2,7 +2,7 @@ server {
|
|||||||
listen 5000 default_server;
|
listen 5000 default_server;
|
||||||
listen [::]:5000 default_server;
|
listen [::]:5000 default_server;
|
||||||
|
|
||||||
server_name $SEASONED_DOMAIN;
|
server_name _;
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
gzip on;
|
gzip on;
|
||||||
|
|||||||
60
package.json
60
package.json
@@ -5,57 +5,31 @@
|
|||||||
"author": "Kevin Midboe",
|
"author": "Kevin Midboe",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_ENV=development webpack server",
|
"dev": "NODE_ENV=development vite",
|
||||||
"build": "yarn build:ts && yarn build:webpack",
|
"build": "yarn vite build",
|
||||||
"build:ts": "tsc --project tsconfig.json",
|
"clean": "rm -r dist 2> /dev/null; rm public/index.html 2> /dev/null; rm -r lib 2> /dev/null",
|
||||||
"build:webpack": "NODE_ENV=production webpack-cli build --progress",
|
|
||||||
"postbuild": "cp public/dist/index.html public/index.html",
|
|
||||||
"clean": "rm -r public/dist 2> /dev/null; rm public/index.html 2> /dev/null; rm -r lib 2> /dev/null",
|
|
||||||
"start": "echo 'Start using docker, consult README'",
|
"start": "echo 'Start using docker, consult README'",
|
||||||
"lint": "eslint src --ext .ts,.vue",
|
"lint": "eslint src --ext .ts,.vue",
|
||||||
"docs": "documentation build src/api.ts -f html -o docs/api && documentation build src/api.ts -f md -o docs/api.md"
|
"docs": "documentation build src/api.ts -f html -o docs/api && documentation build src/api.ts -f md -o docs/api.md"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "3.9.1",
|
"chart.js": "3.9.1",
|
||||||
"connect-history-api-fallback": "2.0.0",
|
"vue": "3.5.28",
|
||||||
"dotenv": "^16.0.1",
|
"vue-router": "5.0.3",
|
||||||
"express": "4.18.1",
|
"vuex": "4.1.0"
|
||||||
"vue": "3.2.37",
|
|
||||||
"vue-router": "4.1.3",
|
|
||||||
"vuex": "4.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.18.10",
|
"@eslint/compat": "^2.0.2",
|
||||||
"@babel/plugin-transform-runtime": "7.18.10",
|
"@eslint/js": "^10.0.1",
|
||||||
"@babel/preset-env": "7.18.10",
|
"@types/node": "^25.3.0",
|
||||||
"@babel/runtime": "7.18.9",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@types/express": "4.17.13",
|
"eslint": "^10.0.1",
|
||||||
"@types/node": "18.6.1",
|
"eslint-config-airbnb-extended": "^3.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "5.33.0",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"@typescript-eslint/parser": "5.33.0",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"@vue/cli": "5.0.8",
|
"prettier": "^3.8.1",
|
||||||
"@vue/cli-service": "5.0.8",
|
|
||||||
"@vue/eslint-config-airbnb": "6.0.0",
|
|
||||||
"babel-loader": "8.2.5",
|
|
||||||
"css-loader": "6.7.1",
|
|
||||||
"documentation": "13.2.5",
|
|
||||||
"eslint": "8.21.0",
|
|
||||||
"eslint-config-prettier": "8.5.0",
|
|
||||||
"eslint-plugin-import": "2.26.0",
|
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
|
||||||
"eslint-plugin-vue": "9.3.0",
|
|
||||||
"eslint-plugin-vuejs-accessibility": "1.2.0",
|
|
||||||
"file-loader": "6.2.0",
|
|
||||||
"html-webpack-plugin": "5.5.0",
|
|
||||||
"prettier": "2.7.1",
|
|
||||||
"sass": "1.54.3",
|
"sass": "1.54.3",
|
||||||
"sass-loader": "13.0.2",
|
"typescript": "5.9.3",
|
||||||
"terser-webpack-plugin": "5.3.3",
|
"vite": "^6.0.3"
|
||||||
"ts-loader": "9.3.1",
|
|
||||||
"typescript": "4.7.4",
|
|
||||||
"vue-loader": "17.0.0",
|
|
||||||
"webpack": "5.74.0",
|
|
||||||
"webpack-cli": "4.10.0",
|
|
||||||
"webpack-dev-server": "4.9.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/App.vue
11
src/App.vue
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="content">
|
||||||
<!-- Header and hamburger navigation -->
|
<!-- Header and hamburger navigation -->
|
||||||
<NavigationHeader class="header" />
|
<NavigationHeader class="header" />
|
||||||
|
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
#app {
|
#content {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: var(--header-size);
|
grid-template-rows: var(--header-size);
|
||||||
grid-template-columns: var(--header-size) 1fr;
|
grid-template-columns: var(--header-size) 100%;
|
||||||
|
|
||||||
@include mobile {
|
@include mobile {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
width: calc(100% - var(--header-size));
|
||||||
grid-column: 2 / 3;
|
grid-column: 2 / 3;
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
|
|||||||
23
src/api.ts
23
src/api.ts
@@ -1,11 +1,13 @@
|
|||||||
|
/* eslint-disable n/no-unsupported-features/node-builtins */
|
||||||
import { IList, IMediaCredits, IPersonCredits } from "./interfaces/IList";
|
import { IList, IMediaCredits, IPersonCredits } from "./interfaces/IList";
|
||||||
import type {
|
import type {
|
||||||
IRequestStatusResponse,
|
IRequestStatusResponse,
|
||||||
IRequestSubmitResponse
|
IRequestSubmitResponse
|
||||||
} from "./interfaces/IRequestResponse";
|
} from "./interfaces/IRequestResponse";
|
||||||
|
|
||||||
const { ELASTIC, ELASTIC_INDEX, ELASTIC_APIKEY } = process.env;
|
const API_HOSTNAME = import.meta.env.VITE_SEASONED_API;
|
||||||
const API_HOSTNAME = window.location.origin;
|
const ELASTIC_URL = import.meta.env.VITE_ELASTIC_URL;
|
||||||
|
const ELASTIC_API_KEY = import.meta.env.VITE_ELASTIC_API_KEY;
|
||||||
|
|
||||||
// - - - TMDB - - -
|
// - - - TMDB - - -
|
||||||
|
|
||||||
@@ -334,7 +336,11 @@ const register = (username, password) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const login = (username, password, throwError = false) => {
|
const login = async (
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
throwError = false
|
||||||
|
) => {
|
||||||
const url = new URL("/api/v1/user/login", API_HOSTNAME);
|
const url = new URL("/api/v1/user/login", API_HOSTNAME);
|
||||||
const options = {
|
const options = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -351,7 +357,7 @@ const login = (username, password, throwError = false) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const logout = (throwError = false) => {
|
const logout = async (throwError = false) => {
|
||||||
const url = new URL("/api/v1/user/logout", API_HOSTNAME);
|
const url = new URL("/api/v1/user/logout", API_HOSTNAME);
|
||||||
const options = { method: "POST" };
|
const options = { method: "POST" };
|
||||||
|
|
||||||
@@ -472,8 +478,9 @@ const getEmoji = async () => {
|
|||||||
* @param {string} query
|
* @param {string} query
|
||||||
* @returns {object} List of movies and shows matching query
|
* @returns {object} List of movies and shows matching query
|
||||||
*/
|
*/
|
||||||
const elasticSearchMoviesAndShows = (query: string, count = 22) => {
|
|
||||||
const url = new URL(`${ELASTIC_INDEX}/_search`, ELASTIC);
|
const elasticSearchMoviesAndShows = (query, count = 22) => {
|
||||||
|
const url = new URL(`${ELASTIC_URL}/_search`);
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
sort: [{ popularity: { order: "desc" } }, "_score"],
|
sort: [{ popularity: { order: "desc" } }, "_score"],
|
||||||
@@ -521,8 +528,8 @@ const elasticSearchMoviesAndShows = (query: string, count = 22) => {
|
|||||||
const options = {
|
const options = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `ApiKey ${ELASTIC_APIKEY}`,
|
"Content-Type": "application/json",
|
||||||
"Content-Type": "application/json"
|
Authorization: `ApiKey ${ELASTIC_API_KEY}`
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CastListItem from "src/components/CastListItem.vue";
|
import { defineProps } from "vue";
|
||||||
|
import CastListItem from "@/components/CastListItem.vue";
|
||||||
import type {
|
import type {
|
||||||
IMovie,
|
IMovie,
|
||||||
IShow,
|
IShow,
|
||||||
|
|||||||
@@ -100,8 +100,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
header {
|
header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -47,9 +47,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
|
|
||||||
header {
|
header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
let _type: MediaTypes;
|
let _type: MediaTypes;
|
||||||
|
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
params.forEach((value, key) => {
|
params.forEach((_, key) => {
|
||||||
if (
|
if (
|
||||||
key !== MediaTypes.Movie &&
|
key !== MediaTypes.Movie &&
|
||||||
key !== MediaTypes.Show &&
|
key !== MediaTypes.Show &&
|
||||||
@@ -90,8 +90,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.movie-popup {
|
.movie-popup {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
|
|
||||||
.no-results {
|
.no-results {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -111,9 +111,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
|
|
||||||
.movie-item {
|
.movie-item {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.resultSection {
|
.resultSection {
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
|
|||||||
@@ -29,12 +29,11 @@ Searches Elasticsearch for results based on changes to `query`.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from "vue";
|
|
||||||
import { useStore } from "vuex";
|
|
||||||
import IconMovie from "@/icons/IconMovie.vue";
|
|
||||||
import IconShow from "@/icons/IconShow.vue";
|
|
||||||
import IconPerson from "@/icons/IconPerson.vue";
|
|
||||||
import type { Ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
|
import { ref, watch, defineProps } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
import IconMovie from "../../icons/IconMovie.vue";
|
||||||
|
import IconShow from "../../icons/IconShow.vue";
|
||||||
import { elasticSearchMoviesAndShows } from "../../api";
|
import { elasticSearchMoviesAndShows } from "../../api";
|
||||||
import { MediaTypes } from "../../interfaces/IList";
|
import { MediaTypes } from "../../interfaces/IList";
|
||||||
import type {
|
import type {
|
||||||
@@ -161,9 +160,9 @@ Searches Elasticsearch for results based on changes to `query`.
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
$sizes: 22;
|
$sizes: 22;
|
||||||
|
|
||||||
@for $i from 0 through $sizes {
|
@for $i from 0 through $sizes {
|
||||||
@@ -241,7 +240,9 @@ Searches Elasticsearch for results based on changes to `query`.
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
transition: color 0.1s ease, fill 0.4s ease;
|
transition:
|
||||||
|
color 0.1s ease,
|
||||||
|
fill 0.4s ease;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|||||||
@@ -61,8 +61,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
@include mobile-only {
|
@include mobile-only {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.navigation-link {
|
.navigation-link {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -47,8 +47,13 @@
|
|||||||
padding: 1rem 0.15rem;
|
padding: 1rem 0.15rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: var(--background-color-secondary);
|
background-color: var(--background-color-secondary);
|
||||||
transition: transform 0.3s ease, color 0.3s ease, stoke 0.3s ease,
|
transition:
|
||||||
fill 0.3s ease, background-color 0.5s ease;
|
transform 0.3s ease,
|
||||||
|
color 0.3s ease,
|
||||||
|
stoke 0.3s ease,
|
||||||
|
fill 0.3s ease,
|
||||||
|
background-color 0.5s ease;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.navigation-icons {
|
.navigation-icons {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ the `query`.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { Ref } from "vue";
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
import { useRouter, useRoute } from "vue-router";
|
import { useRouter, useRoute } from "vue-router";
|
||||||
import AutocompleteDropdown from "@/components/header/AutocompleteDropdown.vue";
|
import AutocompleteDropdown from "./AutocompleteDropdown.vue";
|
||||||
import IconSearch from "@/icons/IconSearch.vue";
|
import IconSearch from "../../icons/IconSearch.vue";
|
||||||
import IconClose from "@/icons/IconClose.vue";
|
import IconClose from "../../icons/IconClose.vue";
|
||||||
import type { Ref } from "vue";
|
|
||||||
import type { MediaTypes } from "../../interfaces/IList";
|
import type { MediaTypes } from "../../interfaces/IList";
|
||||||
import { IAutocompleteResult } from "../../interfaces/IAutocompleteSearch";
|
import { IAutocompleteResult } from "../../interfaces/IAutocompleteSearch";
|
||||||
|
|
||||||
@@ -98,13 +98,9 @@ import { IAutocompleteResult } from "../../interfaces/IAutocompleteSearch";
|
|||||||
query.value = decodeURIComponent(params.get("query"));
|
query.value = decodeURIComponent(params.get("query"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { ELASTIC, ELASTIC_APIKEY } = process.env;
|
const ELASTIC_URL = import.meta.env.VITE_ELASTIC_URL;
|
||||||
if (
|
const ELASTIC_API_KEY = import.meta.env.VITE_ELASTIC_API_KEY;
|
||||||
ELASTIC === undefined ||
|
if (!ELASTIC_URL || !ELASTIC_API_KEY) {
|
||||||
ELASTIC === "" ||
|
|
||||||
ELASTIC_APIKEY === undefined ||
|
|
||||||
ELASTIC_APIKEY === ""
|
|
||||||
) {
|
|
||||||
disabled.value = true;
|
disabled.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,9 +180,9 @@ import { IAutocompleteResult } from "../../interfaces/IAutocompleteSearch";
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
|
|
||||||
.close-icon {
|
.close-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
li.sidebar-list-element {
|
li.sidebar-list-element {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
const overflow: Ref<boolean> = ref(false);
|
const overflow: Ref<boolean> = ref(false);
|
||||||
const descriptionElement: Ref<HTMLElement> = ref(null);
|
const descriptionElement: Ref<HTMLElement> = ref(null);
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
function removeElements(elems: NodeListOf<Element>) {
|
function removeElements(elems: NodeListOf<Element>) {
|
||||||
elems.forEach(el => el.remove());
|
elems.forEach(el => el.remove());
|
||||||
}
|
}
|
||||||
@@ -67,7 +66,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.movie-description {
|
.movie-description {
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.movie-detail {
|
.movie-detail {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|||||||
@@ -169,21 +169,20 @@
|
|||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
|
|
||||||
// import img from "@/directives/v-image";
|
// import img from "@/directives/v-image";
|
||||||
import IconProfile from "@/icons/IconProfile.vue";
|
import IconProfile from "../../icons/IconProfile.vue";
|
||||||
import IconThumbsUp from "@/icons/IconThumbsUp.vue";
|
import IconThumbsUp from "../../icons/IconThumbsUp.vue";
|
||||||
import IconThumbsDown from "@/icons/IconThumbsDown.vue";
|
import IconThumbsDown from "../../icons/IconThumbsDown.vue";
|
||||||
import IconInfo from "@/icons/IconInfo.vue";
|
import IconInfo from "../../icons/IconInfo.vue";
|
||||||
import IconRequest from "@/icons/IconRequest.vue";
|
import IconRequest from "../../icons/IconRequest.vue";
|
||||||
import IconRequested from "@/icons/IconRequested.vue";
|
import IconRequested from "../../icons/IconRequested.vue";
|
||||||
import IconBinoculars from "@/icons/IconBinoculars.vue";
|
import IconBinoculars from "../../icons/IconBinoculars.vue";
|
||||||
import IconPlay from "@/icons/IconPlay.vue";
|
import IconPlay from "../../icons/IconPlay.vue";
|
||||||
import TorrentList from "@/components/torrent/TruncatedTorrentResults.vue";
|
import TorrentList from "../torrent/TruncatedTorrentResults.vue";
|
||||||
import CastList from "@/components/CastList.vue";
|
import CastList from "../CastList.vue";
|
||||||
import Detail from "@/components/popup/Detail.vue";
|
import Detail from "./Detail.vue";
|
||||||
import ActionButton from "@/components/popup/ActionButton.vue";
|
import ActionButton from "./ActionButton.vue";
|
||||||
import Description from "@/components/popup/Description.vue";
|
import Description from "./Description.vue";
|
||||||
import LoadingPlaceholder from "@/components/ui/LoadingPlaceholder.vue";
|
import LoadingPlaceholder from "../ui/LoadingPlaceholder.vue";
|
||||||
import type { Ref } from "vue";
|
|
||||||
import type {
|
import type {
|
||||||
IMovie,
|
IMovie,
|
||||||
IShow,
|
IShow,
|
||||||
@@ -342,10 +341,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/loading-placeholder";
|
@import "scss/loading-placeholder";
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
|
|
||||||
header {
|
header {
|
||||||
$duration: 0.2s;
|
$duration: 0.2s;
|
||||||
|
|||||||
@@ -165,10 +165,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/loading-placeholder";
|
@import "scss/loading-placeholder";
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/main";
|
@import "scss/main";
|
||||||
|
|
||||||
section.person {
|
section.person {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
try {
|
try {
|
||||||
validate();
|
validate();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("not valid!"); // eslint-disable-line no-console
|
console.log("not valid! error:", error); // eslint-disable-line no-console
|
||||||
}
|
}
|
||||||
|
|
||||||
// const body: ResetPasswordPayload = {
|
// const body: ResetPasswordPayload = {
|
||||||
|
|||||||
@@ -102,9 +102,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/elements";
|
@import "scss/elements";
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@@ -115,13 +115,8 @@
|
|||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
|
||||||
background-color: $background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-results {
|
.no-results {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-bottom: 2rem;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -155,9 +155,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
@import "src/scss/elements";
|
@import "scss/elements";
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import { ref, defineProps, computed } from "vue";
|
||||||
import TorrentSearchResults from "@/components/torrent/TorrentSearchResults.vue";
|
import TorrentSearchResults from "@/components/torrent/TorrentSearchResults.vue";
|
||||||
import SeasonedButton from "@/components/ui/SeasonedButton.vue";
|
import SeasonedButton from "@/components/ui/SeasonedButton.vue";
|
||||||
import IconArrowDown from "@/icons/IconArrowDown.vue";
|
import IconArrowDown from "@/icons/IconArrowDown.vue";
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.nav__hamburger {
|
.nav__hamburger {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -20,5 +20,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/loading-placeholder";
|
@import "scss/loading-placeholder";
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
button {
|
button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -42,7 +42,10 @@
|
|||||||
background: $background-color-secondary;
|
background: $background-color-secondary;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: background 0.5s ease, color 0.5s ease, border-color 0.5s ease;
|
transition:
|
||||||
|
background 0.5s ease,
|
||||||
|
color 0.5s ease,
|
||||||
|
border-color 0.5s ease;
|
||||||
|
|
||||||
@include desktop {
|
@include desktop {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
|||||||
@@ -74,8 +74,8 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.group {
|
.group {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -64,8 +64,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.fade-active {
|
.fade-active {
|
||||||
transition: opacity 0.4s;
|
transition: opacity 0.4s;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
$background: $background-ui;
|
$background: $background-ui;
|
||||||
$background-selected: $background-color-secondary;
|
$background-selected: $background-color-secondary;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/*
|
||||||
let setValue = function(el, binding) {
|
let setValue = function(el, binding) {
|
||||||
let value = binding.value;
|
let value = binding.value;
|
||||||
let dateArray = value.split('-');
|
let dateArray = value.split('-');
|
||||||
@@ -13,3 +14,4 @@ module.exports = {
|
|||||||
setValue(el, binding);
|
setValue(el, binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
let setValue = function(el, binding) {
|
/*
|
||||||
let img = new Image();
|
const setValue = function(el, binding) {
|
||||||
|
const img = new Image();
|
||||||
img.src = binding.value;
|
img.src = binding.value;
|
||||||
|
|
||||||
img.onload = function() {
|
img.onload = function() {
|
||||||
@@ -10,10 +11,11 @@ let setValue = function(el, binding) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isLiteral: true,
|
isLiteral: true,
|
||||||
bind(el, binding){
|
bind(el, binding) {
|
||||||
setValue(el, binding);
|
setValue(el, binding);
|
||||||
},
|
},
|
||||||
update(el, binding){
|
update(el, binding) {
|
||||||
setValue(el, binding);
|
setValue(el, binding);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable no-use-before-define */
|
|
||||||
import { MediaTypes } from "./IList";
|
import { MediaTypes } from "./IList";
|
||||||
|
|
||||||
export interface IAutocompleteResult {
|
export interface IAutocompleteResult {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable no-use-before-define */
|
|
||||||
|
|
||||||
export enum GraphTypes {
|
export enum GraphTypes {
|
||||||
Plays = "plays",
|
Plays = "plays",
|
||||||
Duration = "duration"
|
Duration = "duration"
|
||||||
@@ -12,12 +10,12 @@ export enum GraphValueTypes {
|
|||||||
|
|
||||||
export interface IGraphDataset {
|
export interface IGraphDataset {
|
||||||
name: string;
|
name: string;
|
||||||
data: Array<number>;
|
data: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGraphData {
|
export interface IGraphData {
|
||||||
labels: Array<string>;
|
labels: string[];
|
||||||
series: Array<IGraphDataset>;
|
series: IGraphDataset[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGraphResponse {
|
export interface IGraphResponse {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export interface IMovie {
|
|||||||
backdrop: string;
|
backdrop: string;
|
||||||
release_date: string | Date;
|
release_date: string | Date;
|
||||||
rating: number;
|
rating: number;
|
||||||
genres: Array<MovieGenres>;
|
genres: MovieGenres[];
|
||||||
production_status: MovieProductionStatus;
|
production_status: MovieProductionStatus;
|
||||||
tagline: string;
|
tagline: string;
|
||||||
runtime: number;
|
runtime: number;
|
||||||
@@ -88,9 +88,9 @@ export interface IShow {
|
|||||||
seasons?: number;
|
seasons?: number;
|
||||||
episodes?: number;
|
episodes?: number;
|
||||||
popularity?: number;
|
popularity?: number;
|
||||||
genres?: Array<ShowGenres>;
|
genres?: ShowGenres[];
|
||||||
production_status?: string;
|
production_status?: string;
|
||||||
runtime?: Array<number>;
|
runtime?: number[];
|
||||||
exists_in_plex?: boolean;
|
exists_in_plex?: boolean;
|
||||||
type: MediaTypes.Show;
|
type: MediaTypes.Show;
|
||||||
}
|
}
|
||||||
@@ -135,19 +135,19 @@ export interface ICrew {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IMediaCredits {
|
export interface IMediaCredits {
|
||||||
cast: Array<ICast>;
|
cast: ICast[];
|
||||||
crew: Array<ICrew>;
|
crew: ICrew[];
|
||||||
id: number;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPersonCredits {
|
export interface IPersonCredits {
|
||||||
cast: Array<IMovie | IShow>;
|
cast: (IMovie | IShow)[];
|
||||||
crew: Array<ICrew>;
|
crew: ICrew[];
|
||||||
id: number;
|
id: number;
|
||||||
type?: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ListResults = Array<IMovie | IShow | IPerson | IRequest>;
|
export type ListResults = (IMovie | IShow | IPerson | IRequest)[];
|
||||||
|
|
||||||
export interface IList {
|
export interface IList {
|
||||||
results: ListResults;
|
results: ListResults;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export default interface INavigationIcon {
|
export default interface INavigationIcon {
|
||||||
title: string;
|
title: string;
|
||||||
route: string;
|
route: string;
|
||||||
icon: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
icon: any;
|
||||||
requiresAuth?: boolean;
|
requiresAuth?: boolean;
|
||||||
useStroke?: boolean;
|
useStroke?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type ITorrent from "./ITorrent";
|
import type ITorrent from "./ITorrent";
|
||||||
|
|
||||||
export default interface IStateTorrent {
|
export default interface IStateTorrent {
|
||||||
results: Array<ITorrent>;
|
results: ITorrent[];
|
||||||
resultCount: number | null;
|
resultCount: number | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ export default interface ITorrent {
|
|||||||
seed: string;
|
seed: string;
|
||||||
leech: string;
|
leech: string;
|
||||||
url: string | null;
|
url: string | null;
|
||||||
release_type: Array<string>;
|
release_type: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import router from "./routes";
|
|||||||
import store from "./store";
|
import store from "./store";
|
||||||
import Toast from "./plugins/Toast";
|
import Toast from "./plugins/Toast";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
import App from "./App.vue";
|
||||||
const App = require("./App.vue").default;
|
|
||||||
|
|
||||||
store.dispatch("darkmodeModule/findAndSetDarkmodeSupported");
|
store.dispatch("darkmodeModule/findAndSetDarkmodeSupported");
|
||||||
store.dispatch("user/initUserFromCookie");
|
store.dispatch("user/initUserFromCookie");
|
||||||
@@ -14,4 +13,5 @@ const app = createApp(App);
|
|||||||
app.use(router);
|
app.use(router);
|
||||||
app.use(store);
|
app.use(store);
|
||||||
app.use(Toast);
|
app.use(Toast);
|
||||||
app.mount("#entry");
|
|
||||||
|
app.mount("#app");
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-param-reassign */
|
||||||
import IStateDarkmode from "../interfaces/IStateDarkmode";
|
import IStateDarkmode from "../interfaces/IStateDarkmode";
|
||||||
|
|
||||||
const state: IStateDarkmode = {
|
const state: IStateDarkmode = {
|
||||||
@@ -10,9 +11,7 @@ export default {
|
|||||||
namespaced: true,
|
namespaced: true,
|
||||||
state,
|
state,
|
||||||
getters: {
|
getters: {
|
||||||
darkmodeSupported: (state: IStateDarkmode) => {
|
darkmodeSupported: (state: IStateDarkmode) => state.darkmodeSupported
|
||||||
return state.darkmodeSupported;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_DARKMODE_SUPPORT: (
|
SET_DARKMODE_SUPPORT: (
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-param-reassign */
|
||||||
import type IStateDocumentTitle from "../interfaces/IStateDocumentTitle";
|
import type IStateDocumentTitle from "../interfaces/IStateDocumentTitle";
|
||||||
|
|
||||||
const capitalize = (string: string) => {
|
const capitalize = (string: string) => {
|
||||||
@@ -26,7 +27,7 @@ const state: IStateDocumentTitle = {
|
|||||||
title: undefined
|
title: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-shadow, no-return-assign */
|
/* eslint-disable @typescript-eslint/no-shadow */
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state,
|
state,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-param-reassign */
|
||||||
import type IStateHamburger from "../interfaces/IStateHamburger";
|
import type IStateHamburger from "../interfaces/IStateHamburger";
|
||||||
|
|
||||||
const state: IStateHamburger = {
|
const state: IStateHamburger = {
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
|
/* eslint-disable no-param-reassign */
|
||||||
import { MediaTypes } from "../interfaces/IList";
|
import { MediaTypes } from "../interfaces/IList";
|
||||||
import type { IStatePopup, IPopupQuery } from "../interfaces/IStatePopup";
|
import type { IStatePopup, IPopupQuery } from "../interfaces/IStatePopup";
|
||||||
|
|
||||||
/* eslint-disable-next-line import/no-cycle */
|
/* eslint-disable-next-line import-x/no-cycle */
|
||||||
import router from "../routes";
|
import router from "../routes";
|
||||||
|
|
||||||
const removeIncludedQueryParams = (params, key) => {
|
const removeIncludedQueryParams = (params: URLSearchParams, key: string) => {
|
||||||
if (params.has(key)) params.delete(key);
|
if (params.has(key)) params.delete(key);
|
||||||
return params;
|
return params;
|
||||||
};
|
};
|
||||||
|
|
||||||
function paramsToObject(entries) {
|
function paramsToObject(entries: Iterator<[string, string]>) {
|
||||||
const result = {};
|
const result = {};
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
for (const [key, value] of entries) {
|
for (const [key, value] of entries) {
|
||||||
@@ -65,7 +66,7 @@ export default {
|
|||||||
actions: {
|
actions: {
|
||||||
open: ({ commit }, { id, type }: { id: number; type: MediaTypes }) => {
|
open: ({ commit }, { id, type }: { id: number; type: MediaTypes }) => {
|
||||||
if (!Number.isNaN(id)) {
|
if (!Number.isNaN(id)) {
|
||||||
id = Number(id); /* eslint-disable-line no-param-reassign */
|
id = Number(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
commit("SET_OPEN", { id, type });
|
commit("SET_OPEN", { id, type });
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-param-reassign */
|
||||||
import type ITorrent from "../interfaces/ITorrent";
|
import type ITorrent from "../interfaces/ITorrent";
|
||||||
import type IStateTorrent from "../interfaces/IStateTorrent";
|
import type IStateTorrent from "../interfaces/IStateTorrent";
|
||||||
|
|
||||||
@@ -11,16 +12,12 @@ export default {
|
|||||||
namespaced: true,
|
namespaced: true,
|
||||||
state,
|
state,
|
||||||
getters: {
|
getters: {
|
||||||
results: (state: IStateTorrent) => {
|
results: (state: IStateTorrent) => state.results,
|
||||||
return state.results;
|
resultCount: (state: IStateTorrent) => state.resultCount
|
||||||
},
|
|
||||||
resultCount: (state: IStateTorrent) => {
|
|
||||||
return state.resultCount;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_RESULTS: (state: IStateTorrent, results: Array<ITorrent>) => {
|
SET_RESULTS: (state: IStateTorrent, results: ITorrent[]) => {
|
||||||
state.results = results;
|
state.results = results;
|
||||||
},
|
},
|
||||||
SET_RESULT_COUNT: (state: IStateTorrent, count: number) => {
|
SET_RESULT_COUNT: (state: IStateTorrent, count: number) => {
|
||||||
@@ -32,7 +29,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setResults({ commit }, results: Array<ITorrent>) {
|
setResults({ commit }, results: ITorrent[]) {
|
||||||
commit("SET_RESULTS", results);
|
commit("SET_RESULTS", results);
|
||||||
},
|
},
|
||||||
setResultCount({ commit }, count: number) {
|
setResultCount({ commit }, count: number) {
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables.scss";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
|||||||
@@ -141,7 +141,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
|
|||||||
@@ -118,8 +118,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.button--group {
|
.button--group {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
section {
|
section {
|
||||||
padding: 1.3rem;
|
padding: 1.3rem;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
|
|||||||
@@ -48,8 +48,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.settings {
|
.settings {
|
||||||
padding: 3rem;
|
padding: 3rem;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
section {
|
section {
|
||||||
padding: 1.3rem;
|
padding: 1.3rem;
|
||||||
|
|||||||
@@ -94,7 +94,9 @@
|
|||||||
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.17), 0 2px 4px 0 rgba(0, 0, 0, 0.08);
|
box-shadow:
|
||||||
|
0 4px 8px 0 rgba(0, 0, 0, 0.17),
|
||||||
|
0 2px 4px 0 rgba(0, 0, 0, 0.08);
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
margin: 1rem 2rem 1rem 0.71rem;
|
margin: 1rem 2rem 1rem 0.71rem;
|
||||||
// max-width: calc(100% - 3rem);
|
// max-width: calc(100% - 3rem);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
import type { RouteRecordRaw, RouteLocationNormalized } from "vue-router";
|
import type { RouteRecordRaw, RouteLocationNormalized } from "vue-router";
|
||||||
|
|
||||||
/* eslint-disable-next-line import/no-cycle */
|
/* eslint-disable-next-line import-x/no-cycle */
|
||||||
import store from "./store";
|
import store from "./store";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -10,7 +10,7 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
name: "home",
|
name: "home",
|
||||||
path: "/",
|
path: "/",
|
||||||
@@ -99,7 +99,6 @@ const loggedIn = () => store.getters["user/loggedIn"];
|
|||||||
const hasPlexAccount = () => store.getters["user/plexUserId"] !== null;
|
const hasPlexAccount = () => store.getters["user/plexUserId"] !== null;
|
||||||
const hamburgerIsOpen = () => store.getters["hamburger/isOpen"];
|
const hamburgerIsOpen = () => store.getters["hamburger/isOpen"];
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
router.beforeEach(
|
router.beforeEach(
|
||||||
(to: RouteLocationNormalized, from: RouteLocationNormalized, next: any) => {
|
(to: RouteLocationNormalized, from: RouteLocationNormalized, next: any) => {
|
||||||
store.dispatch("documentTitle/updateTitle", to.name);
|
store.dispatch("documentTitle/updateTitle", to.name);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
// Loading placeholder styling
|
// Loading placeholder styling
|
||||||
@mixin nth-children($points...) {
|
@mixin nth-children($points...) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@import "src/scss/variables";
|
@import "scss/variables";
|
||||||
|
|
||||||
.noselect {
|
.noselect {
|
||||||
-webkit-touch-callout: none; /* iOS Safari */
|
-webkit-touch-callout: none; /* iOS Safari */
|
||||||
|
|||||||
@@ -8,72 +8,72 @@ $desktop-l-width: 1600px;
|
|||||||
$mobile-width: 768px;
|
$mobile-width: 768px;
|
||||||
|
|
||||||
@mixin desktop {
|
@mixin desktop {
|
||||||
@media (min-width: #{$mobile-width + 1px}) {
|
@media (min-width: #{$mobile-width + 1px}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin mobile {
|
@mixin mobile {
|
||||||
@media (max-width: #{$mobile-width}) {
|
@media (max-width: #{$mobile-width}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.desktop-only {
|
.desktop-only {
|
||||||
@include mobile {
|
@include mobile {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-only {
|
.mobile-only {
|
||||||
@include desktop {
|
@include desktop {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Media
|
// Media
|
||||||
@mixin mobile-only {
|
@mixin mobile-only {
|
||||||
@media (max-width: #{$tablet-p-width - 1px}) {
|
@media (max-width: #{$tablet-p-width - 1px}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin mobile-ls-min {
|
@mixin mobile-ls-min {
|
||||||
@media (min-width: #{$phone-xs-width}) {
|
@media (min-width: #{$phone-xs-width}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin tablet-only {
|
@mixin tablet-only {
|
||||||
@media (min-width: #{$tablet-p-width}) and (max-width: #{$desktop-width - 1px}) {
|
@media (min-width: #{$tablet-p-width}) and (max-width: #{$desktop-width - 1px}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin tablet-min {
|
@mixin tablet-min {
|
||||||
@media (min-width: #{$tablet-p-width}) {
|
@media (min-width: #{$tablet-p-width}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin tablet-portrait-only {
|
@mixin tablet-portrait-only {
|
||||||
@media (min-width: #{$tablet-p-width}) and (max-width: #{$tablet-l-width - 1px}) {
|
@media (min-width: #{$tablet-p-width}) and (max-width: #{$tablet-l-width - 1px}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin tablet-landscape-min {
|
@mixin tablet-landscape-min {
|
||||||
@media (min-width: #{$tablet-l-width}) {
|
@media (min-width: #{$tablet-l-width}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin desktop-min {
|
@mixin desktop-min {
|
||||||
@media (min-width: #{$desktop-width}) {
|
@media (min-width: #{$desktop-width}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin desktop-lg-min {
|
@mixin desktop-lg-min {
|
||||||
@media (min-width: #{$desktop-l-width}) {
|
@media (min-width: #{$desktop-l-width}) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@mixin retina {
|
@mixin retina {
|
||||||
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Colors
|
// Colors
|
||||||
// @import "./media-queries";
|
// @import "./media-queries";
|
||||||
@import "src/scss/media-queries";
|
@import "scss/media-queries";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import torrentModule from "./modules/torrentModule";
|
|||||||
import user from "./modules/user";
|
import user from "./modules/user";
|
||||||
import hamburger from "./modules/hamburger";
|
import hamburger from "./modules/hamburger";
|
||||||
|
|
||||||
/* eslint-disable-next-line import/no-cycle */
|
/* eslint-disable-next-line import-x/no-cycle */
|
||||||
import popup from "./modules/popup";
|
import popup from "./modules/popup";
|
||||||
|
|
||||||
const store = createStore({
|
const store = createStore({
|
||||||
|
|||||||
12
src/utils.ts
12
src/utils.ts
@@ -14,9 +14,7 @@ export const parseJwt = (token: string) => {
|
|||||||
const jsonPayload = decodeURIComponent(
|
const jsonPayload = decodeURIComponent(
|
||||||
atob(base64)
|
atob(base64)
|
||||||
.split("")
|
.split("")
|
||||||
.map(c => {
|
.map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)
|
||||||
return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`;
|
|
||||||
})
|
|
||||||
.join("")
|
.join("")
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -62,10 +60,10 @@ export function focusOnNextElement(elementEvent: KeyboardEvent): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function humanMinutes(minutes) {
|
export function humanMinutes(minutes: number[] | number) {
|
||||||
if (minutes instanceof Array) {
|
if (minutes instanceof Array) {
|
||||||
/* eslint-disable-next-line prefer-destructuring, no-param-reassign */
|
/* eslint-disable-next-line no-param-reassign */
|
||||||
minutes = minutes[0];
|
[minutes] = minutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hours = Math.floor(minutes / 60);
|
const hours = Math.floor(minutes / 60);
|
||||||
@@ -93,7 +91,7 @@ export function setUrlQueryParameter(parameter: string, value: string): void {
|
|||||||
|
|
||||||
const url = `${window.location.protocol}//${window.location.hostname}${
|
const url = `${window.location.protocol}//${window.location.hostname}${
|
||||||
window.location.port ? `:${window.location.port}` : ""
|
window.location.port ? `:${window.location.port}` : ""
|
||||||
}${window.location.pathname}${params.toString().length ? `?${params}` : ""}`;
|
}${ndow.location.pathname}${params.toString().length ? `?${params}` : ""}`;
|
||||||
|
|
||||||
window.history.pushState({}, "search", url);
|
window.history.pushState({}, "search", url);
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/vite-env.d.ts
vendored
Normal file
9
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_SEASONED_API: string;
|
||||||
|
readonly VITE_ELASTIC_URL: string;
|
||||||
|
readonly VITE_ELASTIC_API_KEY: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv;
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
"outDir": "lib",
|
"outDir": "lib",
|
||||||
"baseUrl": "/",
|
"baseUrl": "/",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@": ["src"]
|
"@/*": ["./src/*"],
|
||||||
|
"scss/*": ["./src/scss/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
|||||||
14
vite.config.ts
Normal file
14
vite.config.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import path from "path";
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
import vue from "@vitejs/plugin-vue";
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
scss: path.resolve(__dirname, "./src/scss")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [vue()]
|
||||||
|
});
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
const path = require("path");
|
|
||||||
const webpack = require("webpack");
|
|
||||||
const sass = require("sass");
|
|
||||||
const HTMLWebpackPlugin = require("html-webpack-plugin");
|
|
||||||
const { VueLoaderPlugin } = require("vue-loader");
|
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
|
||||||
const dotenv = require("dotenv").config({ path: "./.env" });
|
|
||||||
const dotenvExample = require("dotenv").config({ path: "./.env.example" });
|
|
||||||
|
|
||||||
const sourcePath = path.resolve(__dirname, "src");
|
|
||||||
const indexFile = path.join(sourcePath, "index.html");
|
|
||||||
const javascriptEntry = path.join(sourcePath, "main.ts");
|
|
||||||
const publicPath = path.resolve(__dirname, "public");
|
|
||||||
const isProd = process.env.NODE_ENV === "production";
|
|
||||||
const variables = dotenv.parsed || dotenvExample.parsed;
|
|
||||||
|
|
||||||
// Merge inn all process.env values that match dotenv keys
|
|
||||||
Object.keys(process.env).forEach(key => {
|
|
||||||
if (key in variables) {
|
|
||||||
variables[key] = process.env[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
mode: process.env.NODE_ENV,
|
|
||||||
context: publicPath,
|
|
||||||
entry: javascriptEntry,
|
|
||||||
output: {
|
|
||||||
path: `${publicPath}/dist/`,
|
|
||||||
publicPath: "/dist/",
|
|
||||||
filename: "[name].[contenthash].js",
|
|
||||||
clean: true
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
loader: "babel-loader",
|
|
||||||
options: {
|
|
||||||
presets: ["@babel/preset-env"]
|
|
||||||
},
|
|
||||||
exclude: /node_modules/
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.vue$/,
|
|
||||||
use: ["vue-loader"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.ts$/,
|
|
||||||
loader: "ts-loader",
|
|
||||||
exclude: /node_modules/,
|
|
||||||
options: {
|
|
||||||
appendTsSuffixTo: [/\.vue$/]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.scss$/,
|
|
||||||
use: [
|
|
||||||
"vue-style-loader",
|
|
||||||
// isProd ? MiniCssExtractPlugin.loader : "vue-style-loader",
|
|
||||||
"css-loader",
|
|
||||||
"sass-loader"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.(png|jpg|gif|svg)$/,
|
|
||||||
loader: "file-loader",
|
|
||||||
options: {
|
|
||||||
name: "[name].[ext]?[hash]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new VueLoaderPlugin(),
|
|
||||||
new HTMLWebpackPlugin({
|
|
||||||
template: indexFile,
|
|
||||||
filename: "index.html",
|
|
||||||
minify: isProd
|
|
||||||
}),
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
"process.env": JSON.stringify(variables)
|
|
||||||
})
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
extensions: [".js", ".ts", ".vue", ".json", ".scss"],
|
|
||||||
alias: {
|
|
||||||
vue: "@vue/runtime-dom",
|
|
||||||
"@": path.resolve(__dirname, "src"),
|
|
||||||
src: path.resolve(__dirname, "src"),
|
|
||||||
assets: `${publicPath}/assets`,
|
|
||||||
components: path.resolve(__dirname, "src/components")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
devtool: "source-map",
|
|
||||||
performance: {
|
|
||||||
hints: false
|
|
||||||
},
|
|
||||||
optimization: {
|
|
||||||
splitChunks: {
|
|
||||||
chunks: "all",
|
|
||||||
maxInitialRequests: Infinity,
|
|
||||||
minSize: 0,
|
|
||||||
cacheGroups: {
|
|
||||||
vendor: {
|
|
||||||
test: /[\\/]node_modules[\\/]/,
|
|
||||||
name(module) {
|
|
||||||
// get the name. E.g. node_modules/packageName/not/this/part.js
|
|
||||||
// or node_modules/packageName
|
|
||||||
const packageName = module.context.match(
|
|
||||||
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
|
|
||||||
)[1];
|
|
||||||
|
|
||||||
// npm package names are URL-safe, but some servers don't like @ symbols
|
|
||||||
return `npm.${packageName.replace("@", "")}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
minimizer: [
|
|
||||||
new TerserPlugin({
|
|
||||||
parallel: true,
|
|
||||||
terserOptions: {
|
|
||||||
sourceMap: true
|
|
||||||
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
|
|
||||||
}
|
|
||||||
})
|
|
||||||
]
|
|
||||||
},
|
|
||||||
devServer: {
|
|
||||||
static: publicPath,
|
|
||||||
historyApiFallback: {
|
|
||||||
index: "/dist/index.html"
|
|
||||||
},
|
|
||||||
compress: true,
|
|
||||||
hot: true,
|
|
||||||
port: 8080
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isProd) {
|
|
||||||
module.exports.mode = "production";
|
|
||||||
module.exports.devtool = false;
|
|
||||||
module.exports.performance.hints = "warning";
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable proxy for anything that hits /Api
|
|
||||||
// View README or update src/config.ts:SEASONED_API_URL
|
|
||||||
const { SEASONED_API } = process.env;
|
|
||||||
if (SEASONED_API) {
|
|
||||||
module.exports.devServer.proxy = {
|
|
||||||
"/api": {
|
|
||||||
target: SEASONED_API,
|
|
||||||
changeOrigin: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user