Compare commits
13 Commits
80c59acf0d
...
2b13a79013
Author | SHA1 | Date | |
---|---|---|---|
2b13a79013 | |||
d1e2d1fa1f | |||
![]() |
70efba181f | ||
![]() |
dfc45f4e4a | ||
![]() |
630aae3cd8 | ||
![]() |
250d8bb388 | ||
![]() |
1030798a73 | ||
![]() |
f141f45f96 | ||
![]() |
26769fd7c0 | ||
![]() |
82e530e82b | ||
![]() |
4eb30dc534 | ||
![]() |
8465103877 | ||
![]() |
4caf603162 |
28
.gitea/workflows/build.yml
Normal file
28
.gitea/workflows/build.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
name: Build and publish the docker image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["custom"]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: git.ngn.tf
|
||||||
|
IMAGE: ${{gitea.repository}}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: "https://github.com/actions/checkout@v4"
|
||||||
|
|
||||||
|
- name: Login to container repo
|
||||||
|
uses: "https://github.com/docker/login-action@v1"
|
||||||
|
with:
|
||||||
|
registry: ${{env.REGISTRY}}
|
||||||
|
username: ${{gitea.actor}}
|
||||||
|
password: ${{secrets.PACKAGES_TOKEN}}
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
run: |
|
||||||
|
docker build . --tag ${{env.REGISTRY}}/${{env.IMAGE}}:latest
|
||||||
|
docker push ${{env.REGISTRY}}/${{env.IMAGE}}:latest
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -24,7 +24,7 @@ yarn-error.log*
|
|||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
.env*.local
|
.env
|
||||||
|
|
||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
154
CHANGELOG.md
154
CHANGELOG.md
@ -1,154 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
||||||
|
|
||||||
## [4.0.0](https://github.com/zyachel/libremdb/compare/v3.4.0...v4.0.0) (2024-08-24)
|
|
||||||
|
|
||||||
|
|
||||||
### ⚠ BREAKING CHANGES
|
|
||||||
|
|
||||||
* **list:** will give 503 now
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* add disclaimer ([2626dfd](https://github.com/zyachel/libremdb/commit/2626dfd8ab75b6d05d20e92e8dc98be53017fe66))
|
|
||||||
* **api:** fix reviews api ([1041de5](https://github.com/zyachel/libremdb/commit/1041de5439604baab5fbc113c31dbad3096a2945))
|
|
||||||
* **cache:** make cache keys for review more distinctive ([324c138](https://github.com/zyachel/libremdb/commit/324c138ec49cd24e932f9b1f8569c22ca25ebc13))
|
|
||||||
* **cleaners:** fix app crash ([333d3b1](https://github.com/zyachel/libremdb/commit/333d3b107e36a8455364e5e09fc6064a9745f3b9))
|
|
||||||
* **error:** add sanity checks before error destructuring ([e320557](https://github.com/zyachel/libremdb/commit/e320557addd4f12f32a638f452a738b5a8f5aa32))
|
|
||||||
* **list:** remove list route ([67891c7](https://github.com/zyachel/libremdb/commit/67891c765533791a1a276e0669358b935ef9f697))
|
|
||||||
|
|
||||||
## [3.4.0](https://github.com/zyachel/libremdb/compare/v3.3.1...v3.4.0) (2024-03-31)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **reviews:** add reviews route ([dc42b32](https://github.com/zyachel/libremdb/commit/dc42b3204caf843d0f07fa28572c5ed275bb601d))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **instances:** fix urls in instances.json ([3eb5178](https://github.com/zyachel/libremdb/commit/3eb517849f279b2453579d0b5c5000e803a13bca))
|
|
||||||
|
|
||||||
## [3.3.1](https://github.com/zyachel/libremdb/compare/v3.3.0...v3.3.1) (2024-01-06)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **dockerfile:** fix failing docker build ([719f42b](https://github.com/zyachel/libremdb/commit/719f42b5e6f6bafc0807986b6198dbbe1cb271ab))
|
|
||||||
|
|
||||||
## [3.3.0](https://github.com/zyachel/libremdb/compare/v3.2.0...v3.3.0) (2023-12-07)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **api:** add a catch-all route ([9fdd731](https://github.com/zyachel/libremdb/commit/9fdd7311368411d59784977f77d1af103ae16543))
|
|
||||||
* **api:** add api endpoints for dynamic routes ([19f1700](https://github.com/zyachel/libremdb/commit/19f1700a55867c1fb8d6c11431bd4557e7520de1))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **api:** refactor all endpoints a bit ([4dffbbc](https://github.com/zyachel/libremdb/commit/4dffbbc0ec870a8f9a56e4ee62e6a6c472552f6a))
|
|
||||||
* **title:** fix title route crash ([a5b7d52](https://github.com/zyachel/libremdb/commit/a5b7d527833a67f40f992c13bbe391884c0d1f82))
|
|
||||||
|
|
||||||
## [3.2.0](https://github.com/zyachel/libremdb/compare/v3.1.1...v3.2.0) (2023-10-28)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **list:** add list route ([97f1432](https://github.com/zyachel/libremdb/commit/97f1432ac5d23206229d806b7cb3e04af6dec36f))
|
|
||||||
|
|
||||||
## [3.1.1](https://github.com/zyachel/libremdb/compare/v3.1.0...v3.1.1) (2023-10-14)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **card:** fix long attributes in cards under 'Known For' section ([736d680](https://github.com/zyachel/libremdb/commit/736d6802430a3f4f364915f3df93fc548a51ebf1))
|
|
||||||
* **error:** fix incorrect 'view on IMDb' link on error page ([0aea2f4](https://github.com/zyachel/libremdb/commit/0aea2f47dad6eb78e319ea1abd8c444f2cba4424))
|
|
||||||
* **media proxy:** fix 304 response code with body error ([c610ef4](https://github.com/zyachel/libremdb/commit/c610ef4d1be39c122715a0eb200155537e7d6abf))
|
|
||||||
* **name:** fix name route crash ([38ed0c6](https://github.com/zyachel/libremdb/commit/38ed0c62177532b93f61af4172ffa6e5b9995bdc))
|
|
||||||
* **name:** fix route crash for some ids ([e91c313](https://github.com/zyachel/libremdb/commit/e91c313f127632f1bd44d190af71bc841bbe87b7))
|
|
||||||
* **title:** fix a crash in title route ([21a1c83](https://github.com/zyachel/libremdb/commit/21a1c83d95b703fa08cdb96c206626f22d5366c9))
|
|
||||||
|
|
||||||
## [3.1.0](https://github.com/zyachel/libremdb/compare/v3.0.0...v3.1.0) (2023-05-21)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **cache:** implement caching of routes ([c53c88d](https://github.com/zyachel/libremdb/commit/c53c88db9bf98258547e2ca512f864800821cb1f))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **form:** fix hydration error ([8599ae2](https://github.com/zyachel/libremdb/commit/8599ae2c5ac11f2818f56c9f7de7666a38b4386c))
|
|
||||||
* **name:** fix a couple of crashes in name and title route ([8d9b663](https://github.com/zyachel/libremdb/commit/8d9b6630a576b7e8331eb5431cd90d02733b4917))
|
|
||||||
|
|
||||||
## [3.0.0](https://github.com/zyachel/libremdb/compare/v2.4.0...v3.0.0) (2023-04-15)
|
|
||||||
|
|
||||||
|
|
||||||
### ⚠ BREAKING CHANGES
|
|
||||||
|
|
||||||
* **title:** older versions won't work, at least for title route
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* add info related to the current instance ([2c5d2f8](https://github.com/zyachel/libremdb/commit/2c5d2f86e46a52223f07d573b152bad5174ee2d9))
|
|
||||||
* **route:** add name route ([75732e0](https://github.com/zyachel/libremdb/commit/75732e00869f9777e87e767a48648996345f02f7))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **title:** fix title page crash ([8ce02d0](https://github.com/zyachel/libremdb/commit/8ce02d02364c8e1f03a8b16594bc20ee6766a8c6))
|
|
||||||
|
|
||||||
# [2.4.0](https://github.com/zyachel/libremdb/compare/v2.3.1...v2.4.0) (2023-01-22)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* fix app crash ([71d1d5b](https://github.com/zyachel/libremdb/commit/71d1d5b34e2866729ae0c96c59ea51e8d1a3dcca))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* add error boundary ([5cc2ef0](https://github.com/zyachel/libremdb/commit/5cc2ef02cec0b31c5d449e189a054fbef5801f60))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.3.1](https://github.com/zyachel/libremdb/compare/v2.3.0...v2.3.1) (2023-01-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* fix unseekable videos on webkit-based browsers ([a32785c](https://github.com/zyachel/libremdb/commit/a32785ce00b638e9079f0924fd9b00f98c077348))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.3.0](https://github.com/zyachel/libremdb/compare/v2.2.2...v2.3.0) (2022-12-31)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* couple css improvements for webkit-based browsers ([81eaf2f](https://github.com/zyachel/libremdb/commit/81eaf2fd5e5980c0c4d59a8805cf541fa8fe51f9))
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **search:** add basic search functionality ([0cff34a](https://github.com/zyachel/libremdb/commit/0cff34a766b09ba17be2a89f6290889dbf225436))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.2.2](https://github.com/zyachel/libremdb/compare/v2.2.1...v2.2.2) (2022-12-10)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* app crash on qutebrowser ([78b14ec](https://github.com/zyachel/libremdb/commit/78b14ec07955d29403b8b5ae0d449f38eea2bbc5))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.2.1](https://github.com/zyachel/libremdb/compare/v2.2.0...v2.2.1) (2022-12-01)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **title:** fix site crash ([dd75df0](https://github.com/zyachel/libremdb/commit/dd75df01eb7c03d8945a8bd20ed231a66bd88b8f))
|
|
38
Dockerfile
38
Dockerfile
@ -1,35 +1,33 @@
|
|||||||
# Thanks @yordis on Github! https://github.com/vercel/next.js/discussions/16995#discussioncomment-132339
|
|
||||||
|
|
||||||
# Install dependencies only when needed
|
|
||||||
FROM node:lts-alpine AS deps
|
FROM node:lts-alpine AS deps
|
||||||
|
|
||||||
WORKDIR /opt/app
|
WORKDIR /app
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml ./
|
||||||
|
|
||||||
RUN npm install -g pnpm
|
RUN npm install -g pnpm
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
# Rebuild the source code only when needed
|
|
||||||
# This is where because may be the case that you would try
|
|
||||||
# to build the app based on some `X_TAG` in my case (Git commit hash)
|
|
||||||
# but the code hasn't changed.
|
|
||||||
FROM node:lts-alpine AS builder
|
FROM node:lts-alpine AS builder
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
WORKDIR /app
|
||||||
WORKDIR /opt/app
|
|
||||||
RUN npm install -g pnpm
|
|
||||||
COPY . .
|
COPY . .
|
||||||
COPY --from=deps /opt/app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
RUN npm install -g pnpm
|
||||||
RUN pnpm build
|
RUN pnpm build
|
||||||
|
|
||||||
# Production image, copy all the files and run next
|
FROM node:lts-alpine AS runner
|
||||||
FROM gcr.io/distroless/nodejs18-debian11 AS runner
|
|
||||||
ARG X_TAG
|
WORKDIR /app
|
||||||
WORKDIR /opt/app
|
COPY --from=builder /app/next.config.mjs ./
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder /app/.next ./.next
|
||||||
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
|
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
COPY --from=builder /opt/app/next.config.mjs ./
|
|
||||||
COPY --from=builder /opt/app/public ./public
|
|
||||||
COPY --from=builder /opt/app/.next ./.next
|
|
||||||
COPY --from=builder /opt/app/node_modules ./node_modules
|
|
||||||
ENV HOST=0.0.0.0
|
ENV HOST=0.0.0.0
|
||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
|
|
||||||
CMD ["./node_modules/next/dist/bin/next", "start"]
|
CMD ["./node_modules/next/dist/bin/next", "start"]
|
221
README.md
221
README.md
@ -1,220 +1,5 @@
|
|||||||
# libremdb
|
# [ngn.tf] | libremdb
|
||||||
|
|
||||||
A free & open source IMDb front-end.
|
![](https://git.ngn.tf/ngn/libremdb/actions/workflows/build.yml/badge.svg)
|
||||||
|
|
||||||
Inspired by projects like [teddit](https://codeberg.org/teddit/teddit), [nitter](https://github.com/zedeus/nitter) and [many others](#similar-projects).
|
A fork of the [libremdb](https://github.com/zyachel/libremdb) project, with my personal changes.
|
||||||
|
|
||||||
| | |
|
|
||||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
||||||
| <img src="./public/img/misc/preview.jpg" title="screenshot (desktop screen, light mode)" width="1500" /> | <img src="./public/img/misc/preview2.jpg" title="screenshot (mobile screen, dark mode)" width="400" /> |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Some Features
|
|
||||||
|
|
||||||
- No ads or tracking
|
|
||||||
Browse any movie info without being tracked or bombarded by annoying ads.
|
|
||||||
- Modern interface
|
|
||||||
Modern interface with curated colors supporting both dark and light themes.
|
|
||||||
- Responsive design
|
|
||||||
Be it your small mobile or big computer screen, it's fully responsive.
|
|
||||||
- Lightweight
|
|
||||||
_[Up movie page](https://imdb.com/title/tt1049413/)_
|
|
||||||
(tested on Firefox v104; without scroll; simulated regular 4g)
|
|
||||||
|
|
||||||
| Network tab stats | libremdb | IMDb |
|
|
||||||
| ------------------------ | -------- | ------ |
|
|
||||||
| no. of requests | 22 | 180 |
|
|
||||||
| data transfered(gzipped) | 468KB | 1.88MB |
|
|
||||||
| load event fired in | 6.22s | 10.01s |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Instances
|
|
||||||
|
|
||||||
| Instance | Tor | I2P | Region | Cloudflare | Notes |
|
|
||||||
| ---------------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------- | ---------- | ------------------------------------------------------------------ |
|
|
||||||
| <https://libremdb.iket.me/> | No | No | CA | No | Operated by me |
|
|
||||||
| <https://libremdb.pussthecat.org/> | No | No | DE | No | Operated by [PussTheCat.org](https://pussthecat.org/) |
|
|
||||||
| <https://ld.vern.cc/> | [Yes](http://ld.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion/) | [Yes](http://vernz3ubrntql4wrgyrssd6u3qzi36zrhz2agbo6vibzbs5olk2q.b32.i2p/) | US | No | Operated by [~vern](https://vern.cc/) |
|
|
||||||
| <https://binge.whatever.social/> | No | No | US/DE | No | Operated by [Whatever Social](https://whatever.social/) |
|
|
||||||
| <https://libremdb.lunar.icu/> | No | No | DE | No | Operated by [lunar.icu](https://lunar.icu/) |
|
|
||||||
| <https://libremdb.jeikobu.net/> | No | No | DE | Yes | Operated by [shindouj](https://github.com/shindouj/) |
|
|
||||||
| <https://lmdb.hostux.net/> | No | No | FR | No | Operated by [Hostux.net](https://hostux.net/) |
|
|
||||||
| <https://binge.whateveritworks.org/> | No | No | DE | Yes | Operated by [WhateverItWorks](https://github.com/WhateverItWorks/) |
|
|
||||||
| <https://libremdb.nerdyfam.tech/> | No | No | US | Yes | Operated by [Nerdyfam.tech](https://nerdyfam.tech/) |
|
|
||||||
| <https://libremdb.tux.pizza/> | No | No | US | No | Operated by [tux.pizza](https://tux.pizza/) |
|
|
||||||
| <https://libremdb.frontendfriendly.xyz/> | No | No | — | No | Operated by [frontendfriendly.xyz](https://frontendfriendly.xyz/) |
|
|
||||||
| <https://d.opnxng.com/> | No | No | SG | No | Operated by [Opnxng](https://about.opnxng.com/) |
|
|
||||||
| <https://libremdb.catsarch.com/> | [Yes](https://libremdb.catsarchywsyuss6jdxlypsw5dc7owd5u5tr6bujxb7o6xw2hipqehyd.onion) | [Yes](http://qjlgasoy3nxepgzntucmcnb6pryqxakwdu7sxvqzi7spdfootryq.b32.i2p/) | US | No | Operated by [Butter Cat](https://catsarch.com/) |
|
|
||||||
| <https://libremdb.r4fo.com/> | [Yes](http://libremdb.r4focoma7gu2zdwwcjjad47ysxt634lg73sxmdbkdozanwqslho5ohyd.onion/) | No | NL | No | Operated by [r4fo](https://r4fo.com/) |
|
|
||||||
| <https://libremdb.privacydev.net/> | [Yes](http://libremdb.g4c3eya4clenolymqbpgwz3q3tawoxw56yhzk4vugqrl6dtu3ejvhjid.onion/) | No | FR | No | Operated by [PrivacyDev](https://privacydev.net/) |
|
|
||||||
| <https://libremdb.ducks.party/> | No | No | NL | No | Operated by [ducks.party](https://ducks.party/) |
|
|
||||||
| <https://lmdb.ngn.tf/> | No | No | TR | No | Operated by [ngn](https://ngn.tf/) |
|
|
||||||
| <https://lmdb.bloat.cat/> | No | No | DE | No | Operated by [bloat.cat](https://bloat.cat/) |
|
|
||||||
| <https://libremdb.darkness.services/> | No | No | US | Yes | Operated by [blade10101](https://github.com/blade10101) |
|
|
||||||
| <https://libremdb.hyperreal.coffee/> | No | No | US | No | Operated by [hyperreal64](https://github.com/hyperreal64) |
|
|
||||||
| <https://ld.ca.zorby.top/> | [Yes](http://q3hetdcyyy572xznqmsledzlbv77moycoqs6ptehpp5vsmx4dtcuqeqd.onion/) | [Yes](http://5j37qusybvyhecljn4hr5i4chifdlfqfkfveythzpzyfxiibt7cq.b32.i2p/) | CA | No | Operated by [Troughy](https://zorby.top/) |
|
|
||||||
| <https://imdb.nerdvpn.de/> | No | No | UA | No | Operated by [Weidenwiesel](https://nerdvpn.de/) |
|
|
||||||
|
|
||||||
Instances list in JSON format can be found in [instances.json](instances.json) file.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Questions you might have
|
|
||||||
|
|
||||||
- How do I use it?
|
|
||||||
Replace `imdb.com` in any IMDb URL with any of the instances. For example: '[imdb.com/title/tt1049413](https://imdb.com/title/tt1049413/)' to '[libremdb.iket.me/title/tt1049413](https://libremdb.iket.me/title/tt1049413/)'.
|
|
||||||
To avoid changing the URLs manually, you can use [extensions](#automatic-redirection).
|
|
||||||
|
|
||||||
- Why is it so slow?
|
|
||||||
Whenever you request info about a movie/show on libremdb, 4 trips are made(2 between your browser and libremdb's server, and 2 between libremdb's server and IMDb's server) instead of the usual 2 trips when you visit a website. For this reason there's a noticable delay. This is a bit of inconvenience you'll have to face should you wish to use this website.
|
|
||||||
|
|
||||||
- It doesn't have all routes.
|
|
||||||
I'll implement more with time :)
|
|
||||||
|
|
||||||
- Is content served from third-parties, like Amazon?
|
|
||||||
Nope, libremdb proxies all image and video requests through the instance to avoid exposing your IP address, browser information and other personally identifiable metadata ([Contributor](https://github.com/httpjamesm)).
|
|
||||||
|
|
||||||
- Why not just use IMDb?
|
|
||||||
Refer to the [features section](#some-features) above.
|
|
||||||
|
|
||||||
- Why didn't you use other databases like [TMDB](https://www.themoviedb.org/) or [OMDb](https://www.omdbapi.com/)?
|
|
||||||
IMDb simply has superior dataset compared to all other alternatives. With that being said, I'd encourage you to check out those alternatives too.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Privacy
|
|
||||||
|
|
||||||
- Information collected:
|
|
||||||
None.
|
|
||||||
|
|
||||||
- Information stored in your browser:
|
|
||||||
A key named 'theme' is stored in Local Storage provided by your browser, if you ever override the default theme. To remove it, go to site data settings, and clear the data for this website. To permamently disable libremdb from storing your theme prefrences, either turn off JavaScript or disable access to Local Storage for libremdb.
|
|
||||||
|
|
||||||
- Information collected by other services:
|
|
||||||
None. libremdb proxies images anonymously through the instance for maximum privacy ([Contributor](https://github.com/httpjamesm)).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## To-Do
|
|
||||||
|
|
||||||
- [ ] add advanced search route
|
|
||||||
- [x] add did you know and reviews on movie info page
|
|
||||||
- [x] add a way to see trailer and other videos
|
|
||||||
- [ ] implement movie specific routes like:
|
|
||||||
|
|
||||||
- [x] reviews(including critic reviews)
|
|
||||||
- [ ] video & image gallery
|
|
||||||
- [ ] sections under 'did you know'
|
|
||||||
- [ ] release info
|
|
||||||
- [ ] parental guide
|
|
||||||
|
|
||||||
- [ ] implement other routes like:
|
|
||||||
|
|
||||||
- [x] lists
|
|
||||||
- [ ] moviemeter
|
|
||||||
- [x] person info(includes directors and actors)
|
|
||||||
- [ ] company info
|
|
||||||
- [ ] user info
|
|
||||||
|
|
||||||
- [x] use redis, or any other caching strategy
|
|
||||||
- [x] implement a better installation method
|
|
||||||
- [x] serve images and videos from libremdb itself
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
As libremdb is made with Next.js, you can deploy it anywhere where Next.js is supported. Below are a few other methods:
|
|
||||||
|
|
||||||
### Manual
|
|
||||||
|
|
||||||
1. Install Node.js and Git.
|
|
||||||
for Node.js, visit [their website](https://nodejs.org/en/).
|
|
||||||
for Git, run `sudo apt install git` if you're on a Debian-based distro. Else visit [their website](https://git-scm.com/).
|
|
||||||
|
|
||||||
2. Install redis(optional).
|
|
||||||
You can install redis from [here](https://redis.io).
|
|
||||||
|
|
||||||
3. Clone and set up the repo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/zyachel/libremdb.git # replace github.com with codeberg.org if you wish so.
|
|
||||||
cd libremdb
|
|
||||||
# change the configuration file to your liking.
|
|
||||||
cp .env.local.example .env.local
|
|
||||||
# replace 'pnpm' with yarn or npm if you use those.
|
|
||||||
pnpm install
|
|
||||||
pnpm build
|
|
||||||
pnpm start
|
|
||||||
# optional: if you're using redis
|
|
||||||
redis-server
|
|
||||||
```
|
|
||||||
|
|
||||||
libremdb will start running at http://localhost:3000.
|
|
||||||
To change port, modify the last command like this: `pnpm start -- -p <port-number>`.
|
|
||||||
|
|
||||||
### Docker (Local)
|
|
||||||
|
|
||||||
You can build the docker image using the provided Dockerfile(thanks to [@httpjamesm](https://github.com/httpjamesm)) and set it up using the [example docker-compose file](./docker-compose.example.yml).
|
|
||||||
|
|
||||||
Change the docker-compose file to your liking and run `docker-compose up -d` to start the container, that's all!
|
|
||||||
|
|
||||||
### Docker (Built)
|
|
||||||
|
|
||||||
There's a [docker image](https://github.com/PussTheCat-org/docker-libremdb-quay) made by [@TheFrenchGhosty](https://github.com/TheFrenchGhosty) for [PussTheCat.org's instance](https://libremdb.pussthecat.org). You can use that as well.
|
|
||||||
|
|
||||||
## Miscellaneous
|
|
||||||
|
|
||||||
### Automatic redirection
|
|
||||||
|
|
||||||
- [Redirector](https://github.com/einaregilsson/Redirector)
|
|
||||||
config:
|
|
||||||
|
|
||||||
```
|
|
||||||
Description: redirect IMDb to libremdb
|
|
||||||
Example URL: https://www.imdb.com/title/tt0258463/?ref_=tt_sims_tt_t_4
|
|
||||||
Include pattern: https?:\/\/(www\.)?imdb\.com\/(.*)
|
|
||||||
Redirect to: https://libremdb.iket.me/$2
|
|
||||||
Pattern type: Regular Expression
|
|
||||||
```
|
|
||||||
|
|
||||||
- [LibRedirect](https://github.com/libredirect/libredirect/)
|
|
||||||
|
|
||||||
- [Privacy Redirector](https://github.com/dybdeskarphet/privacy-redirector)
|
|
||||||
|
|
||||||
### Similar projects
|
|
||||||
|
|
||||||
- [Teddit](https://codeberg.org/teddit/teddit)
|
|
||||||
Teddit is an alternative Reddit front-end focused on privacy.
|
|
||||||
- [Nitter](https://github.com/zedeus/nitter)
|
|
||||||
Nitter is a free and open source alternative Twitter front-end focused on privacy.
|
|
||||||
- [Bibliogram](https://sr.ht/~cadence/bibliogram/)
|
|
||||||
Bibliogram is an alternative front-end for Instagram.
|
|
||||||
- [Invidious](https://invidious.io)
|
|
||||||
Invidious is an alternative front-end to YouTube.
|
|
||||||
- [Libreddit](https://github.com/spikecodes/libreddit)
|
|
||||||
Libreddit is an alternative private front-end to Reddit.
|
|
||||||
- [Scribe](https://git.sr.ht/~edwardloveall/scribe)
|
|
||||||
Scribe is an alternative Medium frontend.
|
|
||||||
- [full list →](https://github.com/digitalblossom/alternative-frontends)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contact
|
|
||||||
|
|
||||||
I'm availabe on [[matrix]](https://matrix.to/#/@ninal:matrix.org) and [email](mailto:aricla@protonmail.com) in case you wish to contact me personally.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Licensed under GNU AGPLv3.
|
|
||||||
See [License](./LICENSE) for full legalese.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
_libremdb does not host any content. All content on libremdb is from IMDb. IMDb is a trademark of IMDb.com, Inc._
|
|
||||||
|
@ -1,47 +1,31 @@
|
|||||||
# docker-compose.yml
|
|
||||||
|
|
||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
libremdb:
|
libremdb:
|
||||||
container_name: libremdb
|
container_name: libremdb
|
||||||
build:
|
image: git.ngn.tf/ngn/libremdb
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- 80:3000
|
||||||
env_file: .env.local.example
|
env_file: .env.example
|
||||||
depends_on:
|
depends_on:
|
||||||
- libremdb-redis
|
- libremdb-redis
|
||||||
restart: always
|
|
||||||
user: 65534:65534 # equivalent to the nobody user
|
|
||||||
read_only: true
|
|
||||||
tmpfs:
|
tmpfs:
|
||||||
- /opt/app/.next/cache/:size=10M,mode=0770,uid=65534,gid=65534,noexec,nosuid,nodev
|
- /opt/app/.next/cache/:size=10M,mode=0770,uid=65534,gid=65534,noexec,nosuid,nodev
|
||||||
security_opt:
|
security_opt:
|
||||||
- no-new-privileges:true
|
- no-new-privileges:true
|
||||||
cap_drop:
|
cap_drop:
|
||||||
- ALL
|
- ALL
|
||||||
networks:
|
user: 65534:65534 # equivalent to the nobody user
|
||||||
- libremdb
|
read_only: true
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
libremdb-redis:
|
libremdb_redis:
|
||||||
container_name: libremdb_redis
|
container_name: libremdb_redis
|
||||||
image: redis
|
image: redis
|
||||||
# FOR DEBUGGING ONLY
|
|
||||||
# ports:
|
|
||||||
# - "6379:6379"
|
|
||||||
restart: always
|
|
||||||
user: nobody
|
user: nobody
|
||||||
read_only: true
|
|
||||||
security_opt:
|
|
||||||
- no-new-privileges:true
|
|
||||||
tmpfs:
|
tmpfs:
|
||||||
- /data:size=10M,mode=0770,uid=65534,gid=65534,noexec,nosuid,nodev
|
- /data:size=10M,mode=0770,uid=65534,gid=65534,noexec,nosuid,nodev
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
cap_drop:
|
cap_drop:
|
||||||
- ALL
|
- ALL
|
||||||
networks:
|
read_only: true
|
||||||
- libremdb
|
restart: unless-stopped
|
||||||
|
|
||||||
networks:
|
|
||||||
libremdb:
|
|
||||||
|
@ -115,5 +115,15 @@
|
|||||||
"clearnet": "https://imdb.nerdvpn.de/",
|
"clearnet": "https://imdb.nerdvpn.de/",
|
||||||
"cdn": false,
|
"cdn": false,
|
||||||
"country": "UA"
|
"country": "UA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clearnet": "https://libremdb.canine.tools/",
|
||||||
|
"cdn": false,
|
||||||
|
"country": "US"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clearnet": "https://libremdb-fly.fly.dev/",
|
||||||
|
"cdn": false,
|
||||||
|
"country": "US"
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "libremdb",
|
"name": "libremdb",
|
||||||
"version": "4.0.0",
|
"version": "4.1.0",
|
||||||
"description": "a free & open source IMDb front-end",
|
"description": "a free & open source IMDb front-end",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import { themeContext } from 'src/context/theme-context';
|
|
||||||
import styles from 'src/styles/modules/components/buttons/themeToggler.module.scss';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
className: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ThemeToggler = (props: Props) => {
|
|
||||||
const { theme, setTheme } = useContext(themeContext);
|
|
||||||
const clickHandler = () => {
|
|
||||||
const themeToSet = theme === 'light' ? 'dark' : 'light';
|
|
||||||
setTheme(themeToSet);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
className={`${styles.button} ${props.className}`}
|
|
||||||
onClick={clickHandler}
|
|
||||||
>
|
|
||||||
<span className='visually-hidden'>Change theme</span>
|
|
||||||
<svg
|
|
||||||
className={`icon ${styles.icon}`}
|
|
||||||
focusable='false'
|
|
||||||
aria-hidden='true'
|
|
||||||
role='img'
|
|
||||||
>
|
|
||||||
<use href='/svg/sprite.svg#icon-theme-switcher'></use>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ThemeToggler;
|
|
@ -1,32 +1,30 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import styles from 'src/styles/modules/layout/footer.module.scss';
|
import styles from 'src/styles/modules/layout/footer.module.scss';
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
{ path: '/about', text: 'About' },
|
{ url: 'https://github.com/zyachel/libremdb', text: 'Source' },
|
||||||
{ path: '/find', text: 'Find' },
|
{ url: 'https://git.ngn.tf/ngn/libremdb', text: 'Modified Source' },
|
||||||
{ path: '/privacy', text: 'Privacy' },
|
|
||||||
{ path: '/contact', text: 'Contact' },
|
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
const { pathname } = useRouter();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer id='footer' className={styles.footer}>
|
<footer id='footer' className={styles.footer}>
|
||||||
<nav aria-label='primary navigation' className={styles.nav}>
|
<nav aria-label='primary navigation' className={styles.nav}>
|
||||||
<ul className={styles.list}>
|
<ul className={styles.list}>
|
||||||
{links.map(link => (
|
{links.map(link => (
|
||||||
<li className={styles.nav__item} key={link.path}>
|
<li className={styles.nav__item} key={link.url}>
|
||||||
<Link href={link.path}>
|
<Link href={link.url}>
|
||||||
<a
|
<a
|
||||||
className={styles.nav__link}
|
className={styles.nav__link}
|
||||||
aria-current={pathname === link.path ? 'page' : undefined}
|
aria-current={undefined}
|
||||||
>
|
>
|
||||||
{link.text}
|
{link.text}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<span> | </span>
|
||||||
|
</li>
|
||||||
))}
|
))}
|
||||||
<li className={styles.nav__item}>
|
<li className={styles.nav__item}>
|
||||||
<a href='#' className={styles.nav__link}>
|
<a href='#' className={styles.nav__link}>
|
||||||
@ -35,10 +33,6 @@ const Footer = () => {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<em className={styles.licence}>
|
|
||||||
libremdb does not host any content. All content on libremdb is from IMDb. IMDb is a
|
|
||||||
trademark of IMDb.com, Inc.
|
|
||||||
</em>
|
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import ThemeToggler from 'src/components/buttons/ThemeToggler';
|
|
||||||
import styles from 'src/styles/modules/layout/header.module.scss';
|
import styles from 'src/styles/modules/layout/header.module.scss';
|
||||||
|
|
||||||
type Props = { full?: boolean; originalPath?: string };
|
type Props = { full?: boolean; originalPath?: string };
|
||||||
@ -52,7 +51,6 @@ const Header = ({ full, originalPath }: Props) => {
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
<ThemeToggler className={styles.themeToggler} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{full && (
|
{full && (
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import Footer from './Footer';
|
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -16,7 +15,6 @@ const Layout = ({ full, children, className, originalPath }: Props) => {
|
|||||||
<main id='main' className={`main ${className}`}>
|
<main id='main' className={`main ${className}`}>
|
||||||
{children}
|
{children}
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,205 +0,0 @@
|
|||||||
import Link from 'next/link';
|
|
||||||
import Meta from 'src/components/meta/Meta';
|
|
||||||
import Layout from 'src/components/layout';
|
|
||||||
import styles from 'src/styles/modules/pages/about/about.module.scss';
|
|
||||||
|
|
||||||
const About = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Meta
|
|
||||||
title='About'
|
|
||||||
description='libremdb is a free & open source IMDb front-end. It allows you to see information about movies, tv shows, video games without any ads or tracking.'
|
|
||||||
/>
|
|
||||||
<Layout full className={styles.about}>
|
|
||||||
<section id='features' className={styles.features}>
|
|
||||||
<h2
|
|
||||||
className={`heading heading__secondary ${styles.features__heading}`}
|
|
||||||
>
|
|
||||||
Some features
|
|
||||||
</h2>
|
|
||||||
<ul className={styles.features__list}>
|
|
||||||
<li className={styles.feature}>
|
|
||||||
<svg
|
|
||||||
aria-hidden='true'
|
|
||||||
focusable='false'
|
|
||||||
role='img'
|
|
||||||
className={styles.feature__icon}
|
|
||||||
>
|
|
||||||
<use href='/svg/sprite.svg#icon-eye-slash'></use>
|
|
||||||
</svg>
|
|
||||||
<h3
|
|
||||||
className={`heading heading__tertiary ${styles.feature__heading}`}
|
|
||||||
>
|
|
||||||
No ads or tracking
|
|
||||||
</h3>
|
|
||||||
<p className={styles.feature__text}>
|
|
||||||
Browse any movie info without being tracked or bombarded by
|
|
||||||
annoying ads.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li className={styles.feature}>
|
|
||||||
<svg
|
|
||||||
aria-hidden='true'
|
|
||||||
focusable='false'
|
|
||||||
role='img'
|
|
||||||
className={styles.feature__icon}
|
|
||||||
>
|
|
||||||
<use href='/svg/sprite.svg#icon-palette'></use>
|
|
||||||
</svg>
|
|
||||||
<h3
|
|
||||||
className={`heading heading__tertiary ${styles.feature__heading}`}
|
|
||||||
>
|
|
||||||
Modern interface
|
|
||||||
</h3>
|
|
||||||
<p className={styles.feature__text}>
|
|
||||||
Modern interface with curated colors supporting both dark and
|
|
||||||
light themes.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li className={styles.feature}>
|
|
||||||
<svg
|
|
||||||
aria-hidden='true'
|
|
||||||
focusable='false'
|
|
||||||
role='img'
|
|
||||||
className={styles.feature__icon}
|
|
||||||
>
|
|
||||||
<use href='/svg/sprite.svg#icon-responsive'></use>
|
|
||||||
</svg>
|
|
||||||
<h3
|
|
||||||
className={`heading heading__tertiary ${styles.feature__heading}`}
|
|
||||||
>
|
|
||||||
Responsive design
|
|
||||||
</h3>
|
|
||||||
<p className={styles.feature__text}>
|
|
||||||
Be it your small mobile or big computer screen, it's fully
|
|
||||||
responsive.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<section id='faq' className={styles.faqs}>
|
|
||||||
<h2 className={`heading heading__secondary ${styles.faqs__heading}`}>
|
|
||||||
Questions you may have
|
|
||||||
</h2>
|
|
||||||
<div className={styles.faqs__list}>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
How do I use this?
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
Replace `imdb.com` in any IMDb URL with any of the instances.
|
|
||||||
For example: `
|
|
||||||
<a
|
|
||||||
href='https://imdb.com/title/tt1049413'
|
|
||||||
className='link'
|
|
||||||
target='_blank'
|
|
||||||
rel='noreferrer'
|
|
||||||
>
|
|
||||||
imdb.com/title/tt1049413
|
|
||||||
</a>
|
|
||||||
` to `
|
|
||||||
<Link href='/title/tt1049413'>
|
|
||||||
<a className='link'>
|
|
||||||
{process.env.NEXT_PUBLIC_URL || ''}/title/tt1049413
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
` . To avoid changing the URLs manually, you can use extensions
|
|
||||||
like{' '}
|
|
||||||
<a
|
|
||||||
href='https://github.com/libredirect/libredirect/'
|
|
||||||
className='link'
|
|
||||||
>
|
|
||||||
LibRedirect
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>Why is it slow?</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
Whenever you request info about a movie/show on libremdb, 4
|
|
||||||
trips are made(2 between your browser and libremdb's server, and
|
|
||||||
2 between libremdb's server and IMDb's server) instead of the
|
|
||||||
usual 2 trips when you visit a website. For this reason there's
|
|
||||||
a noticable delay. This is a bit of inconvenience you'll have to
|
|
||||||
face should you wish to use this website.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
It doesn't have all routes.
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
I'll implement more with time :)
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
Is content served from third-parties, like Amazon?
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
Nope, libremdb proxies all image and video requests through the
|
|
||||||
instance to avoid exposing your IP address, browser information
|
|
||||||
and other personally identifiable metadata (
|
|
||||||
<a
|
|
||||||
href='https://github.com/httpjamesm'
|
|
||||||
target='_blank'
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
className='link'
|
|
||||||
>
|
|
||||||
Contributor
|
|
||||||
</a>
|
|
||||||
).
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
Why not just use IMDb?
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
Refer to the{' '}
|
|
||||||
<a className='link' href='#features'>
|
|
||||||
features section
|
|
||||||
</a>{' '}
|
|
||||||
above.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
Why didn't you use other databases like TMDB or OMDb?
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
IMDb simply has superior dataset compared to all other
|
|
||||||
alternatives. With that being said, I'd encourage you to check
|
|
||||||
out those alternatives too.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
Your website name is quite, ehm, lame.
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
Let's just say I'm not very good at naming things.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
<details className={styles.faq}>
|
|
||||||
<summary className={styles.faq__summary}>
|
|
||||||
I have some ideas/features/suggestions.
|
|
||||||
</summary>
|
|
||||||
<p className={styles.faq__description}>
|
|
||||||
That's great! I've a couple of{' '}
|
|
||||||
<Link href='/contact'>
|
|
||||||
<a className='link'>contact methods</a>
|
|
||||||
</Link>
|
|
||||||
. Send your beautiful suggestions(or complaints), or just drop a
|
|
||||||
hi.
|
|
||||||
</p>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</Layout>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default About;
|
|
@ -1,68 +0,0 @@
|
|||||||
import Meta from 'src/components/meta/Meta';
|
|
||||||
import Layout from 'src/components/layout';
|
|
||||||
import styles from 'src/styles/modules/pages/contact/contact.module.scss';
|
|
||||||
|
|
||||||
const Contact = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Meta
|
|
||||||
title='Contact'
|
|
||||||
description='Contact page of libremdb, a free & open source IMDb front-end.'
|
|
||||||
/>
|
|
||||||
<Layout className=''>
|
|
||||||
<section className={styles.contact}>
|
|
||||||
<h1 className={`heading heading__primary ${styles.contact__heading}`}>
|
|
||||||
Contact
|
|
||||||
</h1>
|
|
||||||
<div className={styles.list}>
|
|
||||||
<div className={styles.item}>
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
For any issues, questions, bugs, or requests regarding the
|
|
||||||
service, you can go to{' '}
|
|
||||||
<a href='https://github.com/zyachel/libremdb' className='link'>
|
|
||||||
GitHub
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
Alternatively, you can visit{' '}
|
|
||||||
<a
|
|
||||||
href='https://codeberg.org/zyachel/libremdb'
|
|
||||||
className='link'
|
|
||||||
>
|
|
||||||
the repository on Codeberg
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{process.env.NEXT_PUBLIC_INSTANCE_MAIN_URL && (
|
|
||||||
<div className={styles.item}>
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
If you have some questions related to this instance,{' '}
|
|
||||||
<a
|
|
||||||
href={process.env.NEXT_PUBLIC_INSTANCE_MAIN_URL}
|
|
||||||
className='link'
|
|
||||||
>
|
|
||||||
contact instance maintainer(s)
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className={styles.item}>
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
In case you wish to contact me(the dev) personally,{' '}
|
|
||||||
<a href='https://iket.me/contact/' className='link'>
|
|
||||||
here you go
|
|
||||||
</a>
|
|
||||||
<span aria-label='smily text emoji'> :)</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</Layout>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Contact;
|
|
@ -1,89 +0,0 @@
|
|||||||
import Meta from 'src/components/meta/Meta';
|
|
||||||
import Layout from 'src/components/layout';
|
|
||||||
import packageInfo from 'src/../package.json';
|
|
||||||
import styles from 'src/styles/modules/pages/privacy/privacy.module.scss';
|
|
||||||
|
|
||||||
const Privacy = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Meta
|
|
||||||
title='Privacy'
|
|
||||||
description='Privacy policy of libremdb, a free & open source IMDb front-end.'
|
|
||||||
/>
|
|
||||||
<Layout className={styles.privacy}>
|
|
||||||
<section className={styles.policy}>
|
|
||||||
<h1 className={`heading heading__primary ${styles.policy__heading}`}>
|
|
||||||
Privacy Policy
|
|
||||||
</h1>
|
|
||||||
<div className={styles.list}>
|
|
||||||
<section className={styles.item}>
|
|
||||||
<h2
|
|
||||||
className={`heading heading__secondary ${styles.item__heading}`}
|
|
||||||
>
|
|
||||||
Information collected
|
|
||||||
</h2>
|
|
||||||
<p className={styles.item__text}>No information is collected.</p>
|
|
||||||
</section>
|
|
||||||
<section className={styles.item}>
|
|
||||||
<h2
|
|
||||||
className={`heading heading__secondary ${styles.item__heading}`}
|
|
||||||
>
|
|
||||||
Information stored in your browser
|
|
||||||
</h2>
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
A key named 'theme' is stored in Local Storage provided by your
|
|
||||||
browser, if you ever override the default theme. To remove it,
|
|
||||||
go to site data settings, and clear the data for this website.
|
|
||||||
</p>
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
To permamently disable libremdb from storing your theme
|
|
||||||
prefrences, either turn off JavaScript or disable access to
|
|
||||||
Local Storage for libremdb.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section className={styles.item}>
|
|
||||||
<h2
|
|
||||||
className={`heading heading__secondary ${styles.item__heading}`}
|
|
||||||
>
|
|
||||||
Instance information
|
|
||||||
</h2>
|
|
||||||
{process.env.NEXT_PUBLIC_INSTANCE_NAME &&
|
|
||||||
process.env.NEXT_PUBLIC_INSTANCE_MAIN_URL && (
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
Operated by:
|
|
||||||
<a
|
|
||||||
className='link'
|
|
||||||
href={process.env.NEXT_PUBLIC_INSTANCE_MAIN_URL}
|
|
||||||
>
|
|
||||||
{process.env.NEXT_PUBLIC_INSTANCE_NAME}
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<p className={styles.item__text}>
|
|
||||||
Version:
|
|
||||||
<a
|
|
||||||
className='link'
|
|
||||||
href={`https://github.com/zyachel/libremdb/tree/v${packageInfo.version}`}
|
|
||||||
>
|
|
||||||
{packageInfo.version}
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer className={styles.metadata}>
|
|
||||||
<p>
|
|
||||||
Privacy policy last updated on <time>31 october, 2022.</time>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You can see the full revision history of this privacy policy on
|
|
||||||
GitHub, or Codeberg.
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
</section>
|
|
||||||
</Layout>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Privacy;
|
|
@ -1,72 +0,0 @@
|
|||||||
import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
|
|
||||||
import Meta from 'src/components/meta/Meta';
|
|
||||||
import Layout from 'src/components/layout';
|
|
||||||
import ErrorInfo from 'src/components/error/ErrorInfo';
|
|
||||||
import { BasicCard, Filters, Pagination, Reviews } from 'src/components/titleReviews';
|
|
||||||
import { AppError } from 'src/interfaces/shared/error';
|
|
||||||
import getOrSetApiCache from 'src/utils/getOrSetApiCache';
|
|
||||||
import { cursoredReviews } from 'src/utils/fetchers/titleReviews';
|
|
||||||
import { cleanQueryStr, getErrorProperties } from 'src/utils/helpers';
|
|
||||||
import { titleReviewsKey } from 'src/utils/constants/keys';
|
|
||||||
import styles from 'src/styles/modules/pages/titleReviews/titleReviews.module.scss';
|
|
||||||
import { TitleReviewsCursored } from 'src/interfaces/shared/titleReviews';
|
|
||||||
import { keys as titleReviewsQueryKeys } from 'src/utils/constants/titleReviewsFilters';
|
|
||||||
|
|
||||||
type Props = InferGetServerSidePropsType<typeof getServerSideProps>;
|
|
||||||
|
|
||||||
const CursoredReviewsPage = ({ data, error, originalPath }: Props) => {
|
|
||||||
if (error) return <ErrorInfo {...error} originalPath={originalPath} />;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Meta
|
|
||||||
title={data.meta.title ?? 'User Reviews'}
|
|
||||||
description={data.meta.title ?? 'User Reviews'}
|
|
||||||
/>
|
|
||||||
<Layout className={styles.container} originalPath={originalPath}>
|
|
||||||
<BasicCard meta={data.meta} className={styles.card} />
|
|
||||||
<Reviews list={data.list} className={styles.results}>
|
|
||||||
<Pagination meta={data.meta} cursor={data.cursor} />
|
|
||||||
</Reviews>
|
|
||||||
<Filters titleId={data.meta.titleId} className={styles.form} />
|
|
||||||
</Layout>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TO-DO: make a getServerSideProps wrapper for handling errors
|
|
||||||
type Data = ({ data: TitleReviewsCursored; error: null } | { error: AppError; data: null }) & {
|
|
||||||
originalPath: string;
|
|
||||||
};
|
|
||||||
type Params = { titleId: string; paginationKey: string };
|
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps<Data, Params> = async ctx => {
|
|
||||||
const titleId = ctx.params!.titleId;
|
|
||||||
const paginationKey = ctx.params!.paginationKey;
|
|
||||||
const title = ctx.query.title as string | null;
|
|
||||||
|
|
||||||
const originalPath = `/title/${titleId}/reviews/_ajax?paginationKey=${paginationKey}`;
|
|
||||||
const queryObj = ctx.query as Record<string, string>;
|
|
||||||
const queryStr = cleanQueryStr(queryObj, titleReviewsQueryKeys);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = await getOrSetApiCache(
|
|
||||||
titleReviewsKey(titleId, queryStr, paginationKey),
|
|
||||||
cursoredReviews,
|
|
||||||
titleId,
|
|
||||||
paginationKey,
|
|
||||||
queryStr,
|
|
||||||
title
|
|
||||||
);
|
|
||||||
|
|
||||||
return { props: { data, error: null, originalPath } };
|
|
||||||
} catch (error) {
|
|
||||||
const { message, statusCode } = getErrorProperties(error);
|
|
||||||
ctx.res.statusCode = statusCode;
|
|
||||||
ctx.res.statusMessage = message;
|
|
||||||
|
|
||||||
return { props: { error: { message, statusCode }, data: null, originalPath } };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CursoredReviewsPage;
|
|
@ -1,92 +1,9 @@
|
|||||||
import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
|
|
||||||
import Meta from 'src/components/meta/Meta';
|
|
||||||
import Layout from 'src/components/layout';
|
|
||||||
import ErrorInfo from 'src/components/error/ErrorInfo';
|
import ErrorInfo from 'src/components/error/ErrorInfo';
|
||||||
import { Filters, Pagination, Reviews, TitleCard } from 'src/components/titleReviews';
|
import { useRouter } from 'next/router';
|
||||||
import { AppError } from 'src/interfaces/shared/error';
|
|
||||||
import getOrSetApiCache from 'src/utils/getOrSetApiCache';
|
|
||||||
import titleReviews from 'src/utils/fetchers/titleReviews';
|
|
||||||
import { cleanQueryStr, getErrorProperties, getProxiedIMDbImgUrl } from 'src/utils/helpers';
|
|
||||||
import { titleReviewsKey } from 'src/utils/constants/keys';
|
|
||||||
import styles from 'src/styles/modules/pages/titleReviews/titleReviews.module.scss';
|
|
||||||
import TitleReviews from 'src/interfaces/shared/titleReviews';
|
|
||||||
import { keys as titleReviewFiltersQueryKeys } from 'src/utils/constants/titleReviewsFilters';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import ProgressBar from 'src/components/loaders/ProgressBar';
|
|
||||||
|
|
||||||
type Props = InferGetServerSidePropsType<typeof getServerSideProps>;
|
const ReviewsPage = () => {
|
||||||
|
const router = useRouter();
|
||||||
// TO-DO: make a wrapper page component to display errors, if present in props
|
return <ErrorInfo message='Not yet implemented' statusCode={503} originalPath={router.asPath} />;
|
||||||
const ReviewsPage = ({ data, error, originalPath }: Props) => {
|
|
||||||
const [allData, setAllData] = useState({ list: data?.list ?? [], cursor: data?.cursor ?? null });
|
|
||||||
const [isFetching, setIsFetching] = useState(false);
|
|
||||||
|
|
||||||
if (error) return <ErrorInfo {...error} originalPath={originalPath} />;
|
|
||||||
|
|
||||||
const handleOnClickLoadMore = (queryStr = '') => {
|
|
||||||
if (!data.cursor) return;
|
|
||||||
setIsFetching(true);
|
|
||||||
fetch(`/api/title/${data.meta.titleId}/reviews/${allData.cursor}?${queryStr}`)
|
|
||||||
.then(res => {
|
|
||||||
if (!res.ok) throw new Error('something went wrong');
|
|
||||||
return res.json();
|
|
||||||
})
|
|
||||||
.then((newData: { data: NonNullable<Props['data']> }) =>
|
|
||||||
setAllData(prev => ({
|
|
||||||
list: prev.list.concat(newData.data.list),
|
|
||||||
cursor: newData.data.cursor ?? null,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
.catch(console.log)
|
|
||||||
.finally(() => setIsFetching(false));
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{isFetching && <ProgressBar />}
|
|
||||||
<Meta
|
|
||||||
title={data.meta.title}
|
|
||||||
description={data.meta.title}
|
|
||||||
imgUrl={data.meta?.image ? getProxiedIMDbImgUrl(data.meta.image) : undefined}
|
|
||||||
/>
|
|
||||||
<Layout className={styles.container} originalPath={originalPath}>
|
|
||||||
<TitleCard meta={data.meta} className={styles.card} />
|
|
||||||
<Reviews list={allData.list} className={styles.results}>
|
|
||||||
<Pagination meta={data.meta} cursor={allData.cursor} onClick={handleOnClickLoadMore} />
|
|
||||||
</Reviews>
|
|
||||||
<Filters titleId={data.meta.titleId} className={styles.form} />
|
|
||||||
</Layout>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TO-DO: make a getServerSideProps wrapper for handling errors
|
|
||||||
type Data = ({ data: TitleReviews; error: null } | { error: AppError; data: null }) & {
|
|
||||||
originalPath: string;
|
|
||||||
};
|
|
||||||
type Params = { titleId: string };
|
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps<Data, Params> = async ctx => {
|
|
||||||
const titleId = ctx.params!.titleId;
|
|
||||||
const originalPath = ctx.resolvedUrl;
|
|
||||||
const queryParams = ctx.query as Record<string, string>;
|
|
||||||
const queryStr = cleanQueryStr(queryParams, titleReviewFiltersQueryKeys);
|
|
||||||
try {
|
|
||||||
const data = await getOrSetApiCache(
|
|
||||||
titleReviewsKey(titleId, queryStr, null),
|
|
||||||
titleReviews,
|
|
||||||
titleId,
|
|
||||||
queryStr
|
|
||||||
);
|
|
||||||
|
|
||||||
return { props: { data, error: null, originalPath } };
|
|
||||||
} catch (error) {
|
|
||||||
const { message, statusCode } = getErrorProperties(error);
|
|
||||||
ctx.res.statusCode = statusCode;
|
|
||||||
ctx.res.statusMessage = message;
|
|
||||||
|
|
||||||
return { props: { error: { message, statusCode }, data: null, originalPath } };
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReviewsPage;
|
export default ReviewsPage;
|
||||||
|
@ -1,46 +1,9 @@
|
|||||||
$_light: (
|
|
||||||
// 1. text
|
|
||||||
// 1.1 for headings
|
|
||||||
text-accent: hsl(240, 31%, 25%),
|
|
||||||
// 1.2 for base text
|
|
||||||
text: hsl(0, 0%, 24%),
|
|
||||||
// 1.3 for subtle text like metadata
|
|
||||||
text-muted: hsl(204, 4%, 35%),
|
|
||||||
// 2. bg
|
|
||||||
// 2.1 for cards, headers, footers,
|
|
||||||
bg-accent: hsl(339, 100%, 97%),
|
|
||||||
// 2.2 for base bg
|
|
||||||
bg: hsl(0, 0%, 100%),
|
|
||||||
// 2.3 for hover state of cards
|
|
||||||
bg-muted: rgb(255, 229, 239),
|
|
||||||
// 3. links
|
|
||||||
// 3.1 the default one.
|
|
||||||
link: hsl(219, 100%, 20%),
|
|
||||||
link-muted: hsl(344, 79%, 40%),
|
|
||||||
// 4. for icons, borders
|
|
||||||
fill: hsl(339, 100%, 36%),
|
|
||||||
// 4.2 for borders, primarily
|
|
||||||
fill-muted: hsl(0, 0%, 80%),
|
|
||||||
// shadows on cards
|
|
||||||
shadow: 0 0 0.5em hsla(0, 0%, 0%, 0.2),
|
|
||||||
// keyboard, focus hightlight
|
|
||||||
highlight: hsl(176, 43%, 46%),
|
|
||||||
// for gradient behind hero text on about page.
|
|
||||||
gradient:
|
|
||||||
(
|
|
||||||
radial-gradient(at 23% 32%, hsla(344, 79%, 40%, 0.15) 0px, transparent 70%),
|
|
||||||
radial-gradient(at 72% 55%, hsla(344, 79%, 40%, 0.2) 0px, transparent 50%)
|
|
||||||
),
|
|
||||||
// changes color of native html elemnts, either 'light' or 'dark' must be set.
|
|
||||||
scheme: light
|
|
||||||
);
|
|
||||||
|
|
||||||
$_dark: (
|
$_dark: (
|
||||||
text-accent: hsl(0, 0%, 100%),
|
text-accent: hsl(0, 0%, 100%),
|
||||||
text: hsl(0, 0%, 96%),
|
text: hsl(0, 0%, 96%),
|
||||||
text-muted: hsl(0, 0%, 80%),
|
text-muted: hsl(0, 0%, 80%),
|
||||||
bg-accent: hsl(221, 39%, 15%),
|
bg-accent: hsl(221, 39%, 15%),
|
||||||
bg: hsl(221, 39%, 11%),
|
bg: #000,
|
||||||
bg-muted: rgb(20, 28, 46),
|
bg-muted: rgb(20, 28, 46),
|
||||||
link: hsl(339, 95%, 80%),
|
link: hsl(339, 95%, 80%),
|
||||||
link-muted: hsl(344, 79%, 80%),
|
link-muted: hsl(344, 79%, 80%),
|
||||||
@ -56,6 +19,5 @@ $_dark: (
|
|||||||
);
|
);
|
||||||
|
|
||||||
$themes: (
|
$themes: (
|
||||||
light: $_light,
|
light: $_dark, // yes
|
||||||
dark: $_dark,
|
|
||||||
);
|
);
|
||||||
|
@ -15,9 +15,14 @@
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacer-2) var(--spacer-4);
|
gap: var(--spacer-2) var(--spacer-4);
|
||||||
justify-content: space-evenly;
|
justify-content: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user