Compare commits

..

41 Commits

Author SHA1 Message Date
1cccef12a4 Add settings helper for HLS toggle 2021-11-23 22:43:25 -08:00
8e332b0630 Show full subreddit results in search 2021-11-23 22:24:23 -08:00
85ae7c1f60 Fix indentation and formatting 2021-11-23 22:23:29 -08:00
6d73024183 Remove obselete HTML comment 2021-11-22 18:16:06 -08:00
923ff776bd Fix HLS + autoplay from breaking videos 2021-11-22 18:07:00 -08:00
e181e3f57d Improve Replit deployment method 2021-11-22 13:01:34 -08:00
79bb913fa6 Condense free hosting options into one deployment method 2021-11-22 13:00:39 -08:00
632b64c98b Add Glitch deployment option. Closes #339 2021-11-22 20:50:12 +00:00
2878d9c799 Shrink and widen comment scores to fit better 2021-11-22 12:19:51 -08:00
9f8d36cb00 Prevent post previews from overflowing on Chromium 2021-11-22 08:40:36 -08:00
25e641e7b3 Don't run GitHub Workflow when README.md changes 2021-11-21 22:46:01 -08:00
4faa9d46d6 Fix HTTPS connector 2021-11-21 22:44:05 -08:00
7220190811 Link subscriptions in settings to their respective feeds 2021-11-21 22:30:44 -08:00
768820cd4c Render markdown correctly in text post previews by using selftext_html. (#335)
* Render markdown correctly in text post previews by using selftext_html.

I was mistakenly under the impression that we somehow render markdown ourselves, but turns out we just take whatever HTML reddit gives us, and we also need to do this for text previews.

Use CSS to limit the size of the previews instead of truncating in the template.

Fix table CSS.

* Fix post_body padding and trim post_previews

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2021-11-21 23:17:52 +00:00
2ef7957a66 Create feature parity issue template 2021-11-21 19:48:48 +00:00
7df8e7b4c6 Tweak feature request template 2021-11-21 19:27:33 +00:00
67d3be06e1 Fix Jamie's instance address 2021-11-21 04:17:06 +00:00
6be5eb8991 Update README.md 2021-11-21 04:15:35 +00:00
5d9c320a7e Format post and comment votes with a decimal place, like vanilla reddit does. (#324)
* Format post and comment votes with a decimal place, like vanilla reddit does.

Before this change, a vote count of 1999 was displayed as 1k, which is a pretty big gap. The displayed count also differed from what Reddit does. Now, the behaviour is consistent.

Added some tests for format_num.

* Provide more space for post scores

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2021-11-21 04:07:45 +00:00
f7de5285e4 Hide post preview in compact mode. (#329) 2021-11-21 02:05:37 +00:00
c2053524c7 Add text post previews. (#328)
* Add text post previews.

* Add mask gradient over post preview text

* Increase post title font weight for contrast

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2021-11-20 21:13:50 +00:00
3a9e6b4ca0 Add mutahar.rocks instance 2021-11-20 17:29:27 +00:00
731a407466 Collapse (sticky) bot comments by default. (#321)
* Collapse bot comments by default.

Comments are considered bot comments if they are posted by a moderator and are stickied. Some false positives are expected.

* Remove unneeded String conversion

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2021-11-19 05:42:53 +00:00
34ea679519 Update crates and optimize parameters 2021-11-14 18:51:36 -08:00
0f7ba3c61d Add "open in reddit" button to all pages (#304)
* Pass the url parameter to all templates. Add a reddit_link to the navbar, which opens the current url on reddit.

* Add icon for reddit link

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2021-11-15 02:39:33 +00:00
2486347b14 Fix follows not being case-sensitive (#316) 2021-11-15 00:45:18 +00:00
c298109a7b Change healthcheck script to utilise "wget" (#309)
* Change healthcheck script to utilise "wget"

* add "tries=1" option
2021-11-11 00:47:13 +00:00
a0509890b7 Add Riverside onion (#314) 2021-11-11 00:45:22 +00:00
5644d621f7 Remove cloudflare checkmark from my instance. (#313) 2021-11-11 00:45:13 +00:00
1fc5bda486 Move libreddit.dothq.co to German server (#311) 2021-11-06 02:58:36 +00:00
b3255c22cf Add libreddit.pussthecat.org (#310) 2021-11-05 01:36:39 +00:00
1d4ea50a45 Add setting to autoplay videos 2021-10-25 21:27:55 -07:00
546c8a4cda Add poster attribute and disable autoplay on GIFs
* Add the poster attribute even if a post claims to be type gif. Default to none-preloading for gifs like video-typed posts do.

* Disable autoplay for videos in feeds

Co-authored-by: Spike <19519553+spikecodes@users.noreply.github.com>
2021-10-23 21:25:51 +00:00
03336ecafd Add libreddit.de and onion host. Closes #300 2021-10-19 13:59:46 -07:00
957e1c7728 Add oversold.host instance. Closes #289 2021-10-08 23:28:21 +00:00
09053ef0ad Add drivet.xyz instance. Closes #287 2021-10-07 00:13:48 +00:00
aff030fc3a Remove bcow instances 2021-10-02 05:12:49 +00:00
97555dbfdd Fix silkky.cloud Cloudflare Status (#284) 2021-09-29 00:56:09 +00:00
32360e5165 Update v0.15.3 2021-09-19 14:37:31 -07:00
350b796571 Support Deployment to Heroku (#280)
* Added heroku.yml

* Added app.json

* PORT as env var
2021-09-19 19:03:01 +00:00
567556711b Update style.css (#282)
Add cursor pointer on hover of summary bar
2021-09-19 19:00:07 +00:00
27 changed files with 440 additions and 231 deletions

View File

@ -0,0 +1,28 @@
---
name: ✨ Feature parity
about: Suggest implementing a feature into Libreddit that is found in Reddit.com
title: ''
labels: feature parity
assignees: ''
---
## How does this feature work on Reddit?
<!--
A clear and concise description of what the feature is.
-->
## Describe the implementation into Libreddit
<!--
A clear and concise description of what you want to happen.
-->
## Describe alternatives you've considered
<!--
A clear and concise description of any alternative solutions or features you've considered.
-->
## Additional context
<!--
Add any other context or screenshots about the feature parity request here.
-->

View File

@ -1,6 +1,6 @@
--- ---
name: 💡 Feature request name: 💡 Feature request
about: Suggest an idea for this project about: Suggest a feature for Libreddit that is not found in Reddit
title: '' title: ''
labels: enhancement labels: enhancement
assignees: '' assignees: ''

View File

@ -2,9 +2,10 @@ name: Rust
on: on:
push: push:
branches: [master] paths-ignore:
pull_request: - "**.md"
branches: [master] branches:
- master
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@ -49,7 +50,5 @@ jobs:
libreddit.sha512 libreddit.sha512
body: | body: |
- ${{ github.event.head_commit.message }} ${{ github.sha }} - ${{ github.event.head_commit.message }} ${{ github.sha }}
See full list of changes [here](https://github.com/spikecodes/libreddit/compare/${{ steps.version.outputs.tag }}...${{ steps.version.outputs.version }}).
env: env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}

2
.replit Normal file
View File

@ -0,0 +1,2 @@
run = "while true; do wget -O libreddit https://github.com/spikecodes/libreddit/releases/latest/download/libreddit;chmod +x libreddit;./libreddit -H 63115200;sleep 1;done"
language = "bash"

241
Cargo.lock generated
View File

@ -78,6 +78,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "async-rwlock"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "261803dcc39ba9e72760ba6e16d0199b1eef9fc44e81bffabbebb9f5aea3906c"
dependencies = [
"async-mutex",
"event-listener",
]
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.51" version = "0.1.51"
@ -115,9 +125,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
version = "0.19.5" version = "0.19.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33"
dependencies = [ dependencies = [
"funty", "funty",
"radium", "radium",
@ -127,9 +137,9 @@ dependencies = [
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.7.0" version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]] [[package]]
name = "bytes" name = "bytes"
@ -139,26 +149,26 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]] [[package]]
name = "cached" name = "cached"
version = "0.23.0" version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e2afe73808fbaac302e39c9754bfc3c4b4d0f99c9c240b9f4e4efc841ad1b74" checksum = "c2bc2fd249a24a9cdd4276f3a3e0461713271ab63b0e9e656e200e8e21c8c927"
dependencies = [ dependencies = [
"async-mutex", "async-mutex",
"async-rwlock",
"async-trait", "async-trait",
"cached_proc_macro", "cached_proc_macro",
"cached_proc_macro_types", "cached_proc_macro_types",
"futures", "futures",
"hashbrown 0.9.1", "hashbrown",
"once_cell", "once_cell",
] ]
[[package]] [[package]]
name = "cached_proc_macro" name = "cached_proc_macro"
version = "0.6.1" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a685ba39b57a91a53d149dcbef854f50fbe204d1ff6081ea0bec3529a0c456" checksum = "ac3531903b39df48a378a7ed515baee7c1fff32488489c7d0725eb1749b22a91"
dependencies = [ dependencies = [
"async-mutex",
"cached_proc_macro_types", "cached_proc_macro_types",
"darling", "darling",
"quote", "quote",
@ -173,9 +183,9 @@ checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.70" version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -212,9 +222,9 @@ dependencies = [
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.1" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
dependencies = [ dependencies = [
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
@ -222,24 +232,15 @@ dependencies = [
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.2" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "ct-logs"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8"
dependencies = [
"sct",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.10.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" checksum = "757c0ded2af11d8e739c4daea1ac623dd1624b06c844cf3f5a39f1bdbd99bb12"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"darling_macro", "darling_macro",
@ -247,9 +248,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.10.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" checksum = "2c34d8efb62d0c2d7f60ece80f75e5c63c1588ba68032740494b0b9a996466e3"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
@ -261,9 +262,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.10.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" checksum = "ade7bff147130fe5e6d39f089c6bd49ec0250f35d70b2eebf72afdfc919f15cc"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
@ -424,9 +425,9 @@ dependencies = [
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.4" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472" checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
@ -441,12 +442,6 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.11.2"
@ -464,9 +459,9 @@ dependencies = [
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
@ -475,9 +470,9 @@ dependencies = [
[[package]] [[package]]
name = "http-body" name = "http-body"
version = "0.4.3" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
dependencies = [ dependencies = [
"bytes", "bytes",
"http", "http",
@ -492,15 +487,15 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
[[package]] [[package]]
name = "httpdate" name = "httpdate"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.12" version = "0.14.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13f67199e765030fa08fe0bd581af683f0d5bc04ea09c2b1102012c5fb90e7fd" checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -522,19 +517,17 @@ dependencies = [
[[package]] [[package]]
name = "hyper-rustls" name = "hyper-rustls"
version = "0.22.1" version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
dependencies = [ dependencies = [
"ct-logs", "http",
"futures-util",
"hyper", "hyper",
"log", "log",
"rustls", "rustls",
"rustls-native-certs", "rustls-native-certs",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"webpki",
] ]
[[package]] [[package]]
@ -561,14 +554,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown 0.11.2", "hashbrown",
] ]
[[package]] [[package]]
name = "instant" name = "instant"
version = "0.1.10" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
@ -581,9 +574,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.54" version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1866b355d9c878e5e607473cbe3f63282c0b7aad2db1dbebf55076c686918254" checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@ -609,13 +602,13 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.101" version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
[[package]] [[package]]
name = "libreddit" name = "libreddit"
version = "0.15.2" version = "0.19.1"
dependencies = [ dependencies = [
"askama", "askama",
"async-recursion", "async-recursion",
@ -666,9 +659,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.7.13" version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@ -793,18 +786,18 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.29" version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -858,9 +851,9 @@ dependencies = [
[[package]] [[package]]
name = "route-recognizer" name = "route-recognizer"
version = "0.3.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824172f0afccf3773c3905f5550ac94572144efe0deaf49a1f22bbca188d193e" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
@ -873,11 +866,10 @@ dependencies = [
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.19.1" version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
dependencies = [ dependencies = [
"base64",
"log", "log",
"ring", "ring",
"sct", "sct",
@ -886,16 +878,25 @@ dependencies = [
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.5.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" checksum = "5ca9ebdfa27d3fc180e42879037b5338ab1c040c06affd00d8338598e7800943"
dependencies = [ dependencies = [
"openssl-probe", "openssl-probe",
"rustls", "rustls-pemfile",
"schannel", "schannel",
"security-framework", "security-framework",
] ]
[[package]]
name = "rustls-pemfile"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9"
dependencies = [
"base64",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.5"
@ -920,9 +921,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "sct" name = "sct"
version = "0.6.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [ dependencies = [
"ring", "ring",
"untrusted", "untrusted",
@ -988,9 +989,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.67" version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -1014,21 +1015,21 @@ dependencies = [
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.4" version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.6.1" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.1" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516"
dependencies = [ dependencies = [
"libc", "libc",
"winapi", "winapi",
@ -1106,15 +1107,15 @@ checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.9.3" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.76" version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1176,9 +1177,9 @@ dependencies = [
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.3.1" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
dependencies = [ dependencies = [
"tinyvec_macros", "tinyvec_macros",
] ]
@ -1191,9 +1192,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.11.0" version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4efe6fc2395938c8155973d7be49fe8d03a843726e285e100a8a383cc0154ce" checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",
@ -1211,9 +1212,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "1.3.0" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1222,9 +1223,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.22.0" version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" checksum = "4baa378e417d780beff82bf54ceb0d195193ea6a00c14e22359e7f39456b5689"
dependencies = [ dependencies = [
"rustls", "rustls",
"tokio", "tokio",
@ -1233,9 +1234,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.6.8" version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
@ -1253,9 +1254,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.26" version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"pin-project-lite", "pin-project-lite",
@ -1264,9 +1265,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.19" version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
] ]
@ -1279,9 +1280,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.6" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@ -1294,9 +1295,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
@ -1346,9 +1347,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.77" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e68338db6becec24d3c7977b5bf8a48be992c934b5d07177e3931f5dc9b076c" checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@ -1356,9 +1357,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.77" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f34c405b4f0658583dba0c1c7c9b694f3cac32655db463b56c254a1c75269523" checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static", "lazy_static",
@ -1371,9 +1372,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.77" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d5a6580be83b19dc570a8f9c324251687ab2184e57086f71625feb57ec77c8" checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -1381,9 +1382,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.77" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3775a030dc6f5a0afd8a84981a21cc92a781eb429acef9ecce476d0c9113e92" checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1394,15 +1395,15 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.77" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c279e376c7a8e8752a8f1eaa35b7b0bee6bb9fb0cdacfa97cc3f1f289c87e2b4" checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.54" version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a84d70d1ec7d2da2d26a5bd78f4bca1b8c3254805363ce743b7a05bc30d195a" checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@ -1410,9 +1411,9 @@ dependencies = [
[[package]] [[package]]
name = "webpki" name = "webpki"
version = "0.21.4" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [ dependencies = [
"ring", "ring",
"untrusted", "untrusted",

View File

@ -3,23 +3,23 @@ name = "libreddit"
description = " Alternative private front-end to Reddit" description = " Alternative private front-end to Reddit"
license = "AGPL-3.0" license = "AGPL-3.0"
repository = "https://github.com/spikecodes/libreddit" repository = "https://github.com/spikecodes/libreddit"
version = "0.15.2" version = "0.19.1"
authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"] authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
askama = { version = "0.10.5", default-features = false } askama = { version = "0.10.5", default-features = false }
async-recursion = "0.3.2" async-recursion = "0.3.2"
cached = "0.23.0" cached = "0.26.2"
clap = { version = "2.33.3", default-features = false } clap = { version = "2.33.3", default-features = false }
regex = "1.5.4" regex = "1.5.4"
serde = { version = "1.0.126", features = ["derive"] } serde = { version = "1.0.130", features = ["derive"] }
cookie = "0.15.0" cookie = "0.15.1"
futures-lite = "1.12.0" futures-lite = "1.12.0"
hyper = { version = "0.14.10", features = ["full"] } hyper = { version = "0.14.15", features = ["full"] }
hyper-rustls = "0.22.1" hyper-rustls = "0.23.0"
route-recognizer = "0.3.0" route-recognizer = "0.3.1"
serde_json = "1.0.64" serde_json = "1.0.71"
tokio = { version = "1.8.1", features = ["full"] } tokio = { version = "1.14.0", features = ["full"] }
time = "0.2.27" time = "0.2.7"
url = "2.2.2" url = "2.2.2"

View File

@ -29,19 +29,18 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
|-|-|-| |-|-|-|
| [libredd.it](https://libredd.it) (official) | 🇺🇸 US | | | [libredd.it](https://libredd.it) (official) | 🇺🇸 US | |
| [libreddit.spike.codes](https://libreddit.spike.codes) (official) | 🇺🇸 US | | | [libreddit.spike.codes](https://libreddit.spike.codes) (official) | 🇺🇸 US | |
| [libreddit.dothq.co](https://libreddit.dothq.co) | 🇺🇸 US | | | [libreddit.dothq.co](https://libreddit.dothq.co) | 🇩🇪 DE | |
| [libreddit.kavin.rocks](https://libreddit.kavin.rocks) | 🇮🇳 IN | | | [libreddit.kavin.rocks](https://libreddit.kavin.rocks) | 🇮🇳 IN | |
| [libreddit.bcow.xyz](https://libreddit.bcow.xyz) | 🇺🇸 US | |
| [libreddit.40two.app](https://libreddit.40two.app) | 🇳🇱 NL | | | [libreddit.40two.app](https://libreddit.40two.app) | 🇳🇱 NL | |
| [reddit.invak.id](https://reddit.invak.id) | 🇧🇬 BG | | | [reddit.invak.id](https://reddit.invak.id) | 🇧🇬 BG | |
| [reddit.phii.me](https://reddit.phii.me) | 🇺🇸 US | | | [reddit.phii.me](https://reddit.phii.me) | 🇺🇸 US | |
| [lr.riverside.rocks](https://lr.riverside.rocks) | 🇺🇸 US | | | [lr.riverside.rocks](https://lr.riverside.rocks) | 🇺🇸 US | |
| [libreddit.silkky.cloud](https://libreddit.silkky.cloud) | 🇫🇮 FI | | | [libreddit.silkky.cloud](https://libreddit.silkky.cloud) | 🇫🇮 FI | |
| [libreddit.database.red](https://libreddit.database.red) | 🇺🇸 US | ✅ | | [libreddit.database.red](https://libreddit.database.red) | 🇺🇸 US | ✅ |
| [libreddit.exonip.de](https://libreddit.exonip.de) | 🇩🇪 DE | | | [libreddit.exonip.de](https://libreddit.exonip.de) | 🇩🇪 DE | |
| [libreddit.domain.glass](https://libreddit.domain.glass) | 🇺🇸 US | ✅ | | [libreddit.domain.glass](https://libreddit.domain.glass) | 🇺🇸 US | ✅ |
| [libreddit.sugoma.tk](https://libreddit.sugoma.tk) | 🇺🇸 US | | | [libreddit.sugoma.tk](https://libreddit.sugoma.tk) | 🇺🇸 US | |
| [libreddit.trevorthalacker.com](https://libreddit.trevorthalacker.com) | 🇺🇸 US | ✅ | | [libreddit.jamiethalacker.dev](https://libreddit.jamiethalacker.dev) | 🇺🇸 US | ✅ |
| [reddit.artemislena.eu](https://reddit.artemislena.eu) | 🇩🇪 DE | | | [reddit.artemislena.eu](https://reddit.artemislena.eu) | 🇩🇪 DE | |
| [r.nf](https://r.nf) | 🇩🇪 DE | ✅ | | [r.nf](https://r.nf) | 🇩🇪 DE | ✅ |
| [libreddit.awesomehub.io](https://libreddit.awesomehub.io) | 🇫🇮 FI | | | [libreddit.awesomehub.io](https://libreddit.awesomehub.io) | 🇫🇮 FI | |
@ -52,11 +51,18 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [libreddit.igna.rocks](https://libreddit.igna.rocks) | 🇺🇸 US | | | [libreddit.igna.rocks](https://libreddit.igna.rocks) | 🇺🇸 US | |
| [libreddit.autarkic.org](https://libreddit.autarkic.org) | 🇺🇸 US | | | [libreddit.autarkic.org](https://libreddit.autarkic.org) | 🇺🇸 US | |
| [libreddit.flux.industries](https://libreddit.flux.industries) | 🇩🇪 DE | ✅ | | [libreddit.flux.industries](https://libreddit.flux.industries) | 🇩🇪 DE | ✅ |
| [libreddit.drivet.xyz](https://libreddit.drivet.xyz) | 🇫🇮 FI | ✅ |
| [lr.oversold.host](https://lr.oversold.host) | 🇱🇺 LU | |
| [libreddit.de](https://libreddit.de) | 🇩🇪 DE | |
| [libreddit.pussthecat.org](https://libreddit.pussthecat.org) | 🇩🇪 DE | |
| [libreddit.mutahar.rocks](https://libreddit.mutahar.rocks) | 🇫🇷 FR | |
| [spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion](http://spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion) | 🇮🇳 IN | | | [spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion](http://spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion) | 🇮🇳 IN | |
| [fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion](http://fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion) | 🇩🇪 DE | | | [fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion](http://fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion) | 🇩🇪 DE | |
| [dflv6yjt7il3n3tggf4qhcmkzbti2ppytqx3o7pjrzwgntutpewscyid.onion](http://dflv6yjt7il3n3tggf4qhcmkzbti2ppytqx3o7pjrzwgntutpewscyid.onion) | 🇺🇸 US | |
| [kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion](http://kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion) | 🇳🇱 NL | | | [kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion](http://kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion) | 🇳🇱 NL | |
| [inytumdgnri7xsqtvpntjevaelxtgbjqkuqhtf6txxhwbll2fwqtakqd.onion](http://inytumdgnri7xsqtvpntjevaelxtgbjqkuqhtf6txxhwbll2fwqtakqd.onion) | 🇨🇭 CH | | | [inytumdgnri7xsqtvpntjevaelxtgbjqkuqhtf6txxhwbll2fwqtakqd.onion](http://inytumdgnri7xsqtvpntjevaelxtgbjqkuqhtf6txxhwbll2fwqtakqd.onion) | 🇨🇭 CH | |
| [liredejj74h5xjqr2dylnl5howb2bpikfowqoveub55ru27x43357iid.onion](http://liredejj74h5xjqr2dylnl5howb2bpikfowqoveub55ru27x43357iid.onion) | 🇩🇪 DE | |
| [kzhfp3nvb4qp575vy23ccbrgfocezjtl5dx66uthgrhu7nscu6rcwjyd.onion](http://kzhfp3nvb4qp575vy23ccbrgfocezjtl5dx66uthgrhu7nscu6rcwjyd.onion) | 🇺🇸 US | |
A checkmark in the "Cloudflare" category here refers to the use of the reverse proxy, [Cloudflare](https://cloudflare). The checkmark will not be listed for a site which uses Cloudflare DNS but rather the proxying service which grants Cloudflare the ability to monitor traffic to the website. A checkmark in the "Cloudflare" category here refers to the use of the reverse proxy, [Cloudflare](https://cloudflare). The checkmark will not be listed for a site which uses Cloudflare DNS but rather the proxying service which grants Cloudflare the ability to monitor traffic to the website.
@ -189,15 +195,13 @@ yay -S libreddit-git
If you're on Linux and none of these methods work for you, you can grab a Linux binary from [the newest release](https://github.com/spikecodes/libreddit/releases/latest). If you're on Linux and none of these methods work for you, you can grab a Linux binary from [the newest release](https://github.com/spikecodes/libreddit/releases/latest).
## 5) Replit ## 5) Replit/Heroku/Glitch
**Note:** Replit is a free option but they are *not* private and will monitor server usage to prevent abuse. If you need a free and easy setup, this method may work best for you. **Note:** These are free hosting options but they are *not* private and will monitor server usage to prevent abuse. If you need a free and easy setup, this method may work best for you.
1. Create a Replit account (see note above) <a href="https://repl.it/github/spikecodes/libreddit"><img src="https://repl.it/badge/github/spikecodes/libreddit" alt="Run on Repl.it" height="32" /></a>
2. Visit [the official Repl](https://replit.com/@spikethecoder/libreddit) and fork it [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/spikecodes/libreddit)
3. Hit the run button to download the latest Libreddit version and start it [![Remix on Glitch](https://cdn.glitch.com/2703baf2-b643-4da7-ab91-7ee2a2d00b5b%2Fremix-button-v2.svg)](https://glitch.com/edit/#!/remix/libreddit)
In the web preview (defaults to top right), you should see your instance hosted where you can assign a [custom domain](https://docs.replit.com/repls/web-hosting#custom-domains).
--- ---

42
app.json Normal file
View File

@ -0,0 +1,42 @@
{
"name": "Libreddit",
"description": "Private front-end for Reddit",
"buildpacks": [
{
"url": "https://github.com/emk/heroku-buildpack-rust"
},
{
"url": "emk/rust"
}
],
"stack": "container",
"env": {
"LIBREDDIT_DEFAULT_THEME": {
"required": false
},
"LIBREDDIT_DEFAULT_FRONT_PAGE": {
"required": false
},
"LIBREDDIT_DEFAULT_LAYOUT": {
"required": false
},
"LIBREDDIT_DEFAULT_WIDE": {
"required": false
},
"LIBREDDIT_DEFAULT_COMMENT_SORT": {
"required": false
},
"LIBREDDIT_DEFAULT_POST_SORT": {
"required": false
},
"LIBREDDIT_DEFAULT_SHOW_NSFW": {
"required": false
},
"LIBREDDIT_USE_HLS": {
"required": false
},
"LIBREDDIT_HIDE_HLS_NOTIFICATION": {
"required": false
}
}
}

View File

@ -8,6 +8,6 @@ services:
ports: ports:
- 8080:8080 - 8080:8080
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/settings"] test: ["CMD", "wget", "--spider", "-q", "--tries=1", "http://localhost:8080/settings"]
interval: 5m interval: 5m
timeout: 3s timeout: 3s

3
heroku.yml Normal file
View File

@ -0,0 +1,3 @@
build:
docker:
web: Dockerfile

View File

@ -23,7 +23,7 @@ async fn stream(url: &str, req: &Request<Body>) -> Result<Response<Body>, String
let url = Uri::from_str(url).map_err(|_| "Couldn't parse URL".to_string())?; let url = Uri::from_str(url).map_err(|_| "Couldn't parse URL".to_string())?;
// Prepare the HTTPS connector. // Prepare the HTTPS connector.
let https = hyper_rustls::HttpsConnector::with_native_roots(); let https = hyper_rustls::HttpsConnectorBuilder::new().with_native_roots().https_only().enable_http1().build();
// Build the hyper client from the HTTPS connector. // Build the hyper client from the HTTPS connector.
let client: client::Client<_, hyper::Body> = client::Client::builder().build(https); let client: client::Client<_, hyper::Body> = client::Client::builder().build(https);
@ -63,7 +63,7 @@ async fn stream(url: &str, req: &Request<Body>) -> Result<Response<Body>, String
fn request(url: String, quarantine: bool) -> Boxed<Result<Response<Body>, String>> { fn request(url: String, quarantine: bool) -> Boxed<Result<Response<Body>, String>> {
// Prepare the HTTPS connector. // Prepare the HTTPS connector.
let https = hyper_rustls::HttpsConnector::with_native_roots(); let https = hyper_rustls::HttpsConnectorBuilder::new().with_native_roots().https_or_http().enable_http1().build();
// Construct the hyper client from the HTTPS connector. // Construct the hyper client from the HTTPS connector.
let client: client::Client<_, hyper::Body> = client::Client::builder().build(https); let client: client::Client<_, hyper::Body> = client::Client::builder().build(https);

View File

@ -133,10 +133,10 @@ async fn main() {
.get_matches(); .get_matches();
let address = matches.value_of("address").unwrap_or("0.0.0.0"); let address = matches.value_of("address").unwrap_or("0.0.0.0");
let port = matches.value_of("port").unwrap_or("8080"); let port = std::env::var("PORT").unwrap_or_else(|_| matches.value_of("port").unwrap_or("8080").to_string());
let hsts = matches.value_of("hsts"); let hsts = matches.value_of("hsts");
let listener = [address, ":", port].concat(); let listener = [address, ":", &port].concat();
println!("Starting Libreddit..."); println!("Starting Libreddit...");

View File

@ -18,6 +18,7 @@ struct PostTemplate {
sort: String, sort: String,
prefs: Preferences, prefs: Preferences,
single_thread: bool, single_thread: bool,
url: String,
} }
pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> { pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
@ -54,6 +55,7 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
// Parse the JSON into Post and Comment structs // Parse the JSON into Post and Comment structs
let post = parse_post(&response[0]).await; let post = parse_post(&response[0]).await;
let comments = parse_comments(&response[1], &post.permalink, &post.author.name, highlighted_comment); let comments = parse_comments(&response[1], &post.permalink, &post.author.name, highlighted_comment);
let url = req.uri().to_string();
// Use the Post and Comment structs to generate a website to show users // Use the Post and Comment structs to generate a website to show users
template(PostTemplate { template(PostTemplate {
@ -62,6 +64,7 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
sort, sort,
prefs: Preferences::new(req), prefs: Preferences::new(req),
single_thread, single_thread,
url,
}) })
} }
// If the Reddit API returns an error, exit and send error page to user // If the Reddit API returns an error, exit and send error page to user
@ -181,6 +184,14 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
let id = val(&comment, "id"); let id = val(&comment, "id");
let highlighted = id == highlighted_comment; let highlighted = id == highlighted_comment;
// Many subreddits have a default comment posted about the sub's rules etc.
// Many libreddit users do not wish to see this kind of comment by default.
// Reddit does not tell us which users are "bots", so a good heuristic is to
// collapse stickied moderator comments.
let is_moderator_comment = data["distinguished"].as_str().unwrap_or_default() == "moderator";
let is_stickied = data["stickied"].as_bool().unwrap_or_default();
let collapsed = is_moderator_comment && is_stickied;
Comment { Comment {
id, id,
kind, kind,
@ -213,6 +224,7 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
edited, edited,
replies, replies,
highlighted, highlighted,
collapsed,
} }
}) })
.collect() .collect()

View File

@ -16,6 +16,7 @@ struct SearchParams {
before: String, before: String,
after: String, after: String,
restrict_sr: String, restrict_sr: String,
typed: String,
} }
// STRUCTS // STRUCTS
@ -55,10 +56,12 @@ pub async fn find(req: Request<Body>) -> Result<Response<Body>, String> {
return Ok(random); return Ok(random);
} }
let typed = param(&path, "type").unwrap_or_default();
let sort = param(&path, "sort").unwrap_or_else(|| "relevance".to_string()); let sort = param(&path, "sort").unwrap_or_else(|| "relevance".to_string());
// If search is not restricted to this subreddit, show other subreddits in search results // If search is not restricted to this subreddit, show other subreddits in search results
let subreddits = param(&path, "restrict_sr").map_or(search_subreddits(&query).await, |_| Vec::new()); let subreddits = param(&path, "restrict_sr").map_or(search_subreddits(&query, &typed).await, |_| Vec::new());
let url = String::from(req.uri().path_and_query().map_or("", |val| val.as_str())); let url = String::from(req.uri().path_and_query().map_or("", |val| val.as_str()));
@ -74,6 +77,7 @@ pub async fn find(req: Request<Body>) -> Result<Response<Body>, String> {
before: param(&path, "after").unwrap_or_default(), before: param(&path, "after").unwrap_or_default(),
after, after,
restrict_sr: param(&path, "restrict_sr").unwrap_or_default(), restrict_sr: param(&path, "restrict_sr").unwrap_or_default(),
typed,
}, },
prefs: Preferences::new(req), prefs: Preferences::new(req),
url, url,
@ -89,8 +93,9 @@ pub async fn find(req: Request<Body>) -> Result<Response<Body>, String> {
} }
} }
async fn search_subreddits(q: &str) -> Vec<Subreddit> { async fn search_subreddits(q: &str, typed: &str) -> Vec<Subreddit> {
let subreddit_search_path = format!("/subreddits/search.json?q={}&limit=3", q.replace(' ', "+")); let limit = if typed == "sr_user" { "50" } else { "3" };
let subreddit_search_path = format!("/subreddits/search.json?q={}&limit={}", q.replace(' ', "+"), limit);
// Send a request to the url // Send a request to the url
json(subreddit_search_path, false).await.unwrap_or_default()["data"]["children"] json(subreddit_search_path, false).await.unwrap_or_default()["data"]["children"]
@ -101,9 +106,7 @@ async fn search_subreddits(q: &str) -> Vec<Subreddit> {
.map(|subreddit| { .map(|subreddit| {
// For each subreddit from subreddit list // For each subreddit from subreddit list
// Fetch subreddit icon either from the community_icon or icon_img value // Fetch subreddit icon either from the community_icon or icon_img value
let icon = subreddit["data"]["community_icon"] let icon = subreddit["data"]["community_icon"].as_str().map_or_else(|| val(subreddit, "icon_img"), ToString::to_string);
.as_str()
.map_or_else(|| val(subreddit, "icon_img"), ToString::to_string);
Subreddit { Subreddit {
name: val(subreddit, "display_name_prefixed"), name: val(subreddit, "display_name_prefixed"),

View File

@ -14,11 +14,12 @@ use time::{Duration, OffsetDateTime};
#[template(path = "settings.html")] #[template(path = "settings.html")]
struct SettingsTemplate { struct SettingsTemplate {
prefs: Preferences, prefs: Preferences,
url: String,
} }
// CONSTANTS // CONSTANTS
const PREFS: [&str; 9] = [ const PREFS: [&str; 10] = [
"theme", "theme",
"front_page", "front_page",
"layout", "layout",
@ -28,13 +29,18 @@ const PREFS: [&str; 9] = [
"show_nsfw", "show_nsfw",
"use_hls", "use_hls",
"hide_hls_notification", "hide_hls_notification",
"autoplay_videos",
]; ];
// FUNCTIONS // FUNCTIONS
// Retrieve cookies from request "Cookie" header // Retrieve cookies from request "Cookie" header
pub async fn get(req: Request<Body>) -> Result<Response<Body>, String> { pub async fn get(req: Request<Body>) -> Result<Response<Body>, String> {
template(SettingsTemplate { prefs: Preferences::new(req) }) let url = req.uri().to_string();
template(SettingsTemplate {
prefs: Preferences::new(req),
url,
})
} }
// Set cookies using response "Set-Cookie" header // Set cookies using response "Set-Cookie" header

View File

@ -26,6 +26,7 @@ struct WikiTemplate {
wiki: String, wiki: String,
page: String, page: String,
prefs: Preferences, prefs: Preferences,
url: String,
} }
#[derive(Template)] #[derive(Template)]
@ -239,6 +240,7 @@ pub async fn wiki(req: Request<Body>) -> Result<Response<Body>, String> {
let page = req.param("page").unwrap_or_else(|| "index".to_string()); let page = req.param("page").unwrap_or_else(|| "index".to_string());
let path: String = format!("/r/{}/wiki/{}.json?raw_json=1", sub, page); let path: String = format!("/r/{}/wiki/{}.json?raw_json=1", sub, page);
let url = req.uri().to_string();
match json(path, quarantined).await { match json(path, quarantined).await {
Ok(response) => template(WikiTemplate { Ok(response) => template(WikiTemplate {
@ -246,6 +248,7 @@ pub async fn wiki(req: Request<Body>) -> Result<Response<Body>, String> {
wiki: rewrite_urls(response["data"]["content_html"].as_str().unwrap_or("<h3>Wiki not found</h3>")), wiki: rewrite_urls(response["data"]["content_html"].as_str().unwrap_or("<h3>Wiki not found</h3>")),
page, page,
prefs: Preferences::new(req), prefs: Preferences::new(req),
url,
}), }),
Err(msg) => { Err(msg) => {
if msg == "quarantined" { if msg == "quarantined" {
@ -268,6 +271,7 @@ pub async fn sidebar(req: Request<Body>) -> Result<Response<Body>, String> {
// Build the Reddit JSON API url // Build the Reddit JSON API url
let path: String = format!("/r/{}/about.json?raw_json=1", sub); let path: String = format!("/r/{}/about.json?raw_json=1", sub);
let url = req.uri().to_string();
// Send a request to the url // Send a request to the url
match json(path, quarantined).await { match json(path, quarantined).await {
@ -282,6 +286,7 @@ pub async fn sidebar(req: Request<Body>) -> Result<Response<Body>, String> {
sub, sub,
page: "Sidebar".to_string(), page: "Sidebar".to_string(),
prefs: Preferences::new(req), prefs: Preferences::new(req),
url,
}), }),
Err(msg) => { Err(msg) => {
if msg == "quarantined" { if msg == "quarantined" {

View File

@ -70,7 +70,7 @@ async fn user(name: &str) -> Result<User, String> {
// Parse the JSON output into a User struct // Parse the JSON output into a User struct
User { User {
name: name.to_string(), name: res["data"]["name"].as_str().unwrap_or(name).to_owned(),
title: esc!(about("title")), title: esc!(about("title")),
icon: format_url(&about("icon_img")), icon: format_url(&about("icon_img")),
karma: res["data"]["total_karma"].as_i64().unwrap_or(0), karma: res["data"]["total_karma"].as_i64().unwrap_or(0),

View File

@ -251,11 +251,17 @@ impl Post {
// Determine the type of media along with the media URL // Determine the type of media along with the media URL
let (post_type, media, gallery) = Media::parse(data).await; let (post_type, media, gallery) = Media::parse(data).await;
// selftext_html is set for text posts when browsing.
let mut body = rewrite_urls(&val(post, "selftext_html"));
if body == "" {
body = rewrite_urls(&val(post, "body_html"))
}
posts.push(Self { posts.push(Self {
id: val(post, "id"), id: val(post, "id"),
title: esc!(if title.is_empty() { fallback_title.clone() } else { title }), title: esc!(if title.is_empty() { fallback_title.clone() } else { title }),
community: val(post, "subreddit"), community: val(post, "subreddit"),
body: rewrite_urls(&val(post, "body_html")), body,
author: Author { author: Author {
name: val(post, "author"), name: val(post, "author"),
flair: Flair { flair: Flair {
@ -334,6 +340,7 @@ pub struct Comment {
pub edited: (String, String), pub edited: (String, String),
pub replies: Vec<Comment>, pub replies: Vec<Comment>,
pub highlighted: bool, pub highlighted: bool,
pub collapsed: bool,
} }
#[derive(Template)] #[derive(Template)]
@ -341,6 +348,7 @@ pub struct Comment {
pub struct ErrorTemplate { pub struct ErrorTemplate {
pub msg: String, pub msg: String,
pub prefs: Preferences, pub prefs: Preferences,
pub url: String,
} }
#[derive(Default)] #[derive(Default)]
@ -388,6 +396,7 @@ pub struct Preferences {
pub show_nsfw: String, pub show_nsfw: String,
pub hide_hls_notification: String, pub hide_hls_notification: String,
pub use_hls: String, pub use_hls: String,
pub autoplay_videos: String,
pub comment_sort: String, pub comment_sort: String,
pub post_sort: String, pub post_sort: String,
pub subscriptions: Vec<String>, pub subscriptions: Vec<String>,
@ -404,6 +413,7 @@ impl Preferences {
show_nsfw: setting(&req, "show_nsfw"), show_nsfw: setting(&req, "show_nsfw"),
use_hls: setting(&req, "use_hls"), use_hls: setting(&req, "use_hls"),
hide_hls_notification: setting(&req, "hide_hls_notification"), hide_hls_notification: setting(&req, "hide_hls_notification"),
autoplay_videos: setting(&req, "autoplay_videos"),
comment_sort: setting(&req, "comment_sort"), comment_sort: setting(&req, "comment_sort"),
post_sort: setting(&req, "post_sort"), post_sort: setting(&req, "post_sort"),
subscriptions: setting(&req, "subscriptions").split('+').map(String::from).filter(|s| !s.is_empty()).collect(), subscriptions: setting(&req, "subscriptions").split('+').map(String::from).filter(|s| !s.is_empty()).collect(),
@ -531,12 +541,14 @@ pub fn rewrite_urls(input_text: &str) -> String {
}) })
} }
// Append `m` and `k` for millions and thousands respectively // Format vote count to a string that will be displayed.
// Append `m` and `k` for millions and thousands respectively, and
// round to the nearest tenth.
pub fn format_num(num: i64) -> (String, String) { pub fn format_num(num: i64) -> (String, String) {
let truncated = if num >= 1_000_000 || num <= -1_000_000 { let truncated = if num >= 1_000_000 || num <= -1_000_000 {
format!("{}m", num / 1_000_000) format!("{:.1}m", num as f64 / 1_000_000.0)
} else if num >= 1000 || num <= -1000 { } else if num >= 1000 || num <= -1000 {
format!("{}k", num / 1_000) format!("{:.1}k", num as f64 / 1_000.0)
} else { } else {
num.to_string() num.to_string()
}; };
@ -604,12 +616,28 @@ pub fn redirect(path: String) -> Response<Body> {
} }
pub async fn error(req: Request<Body>, msg: String) -> Result<Response<Body>, String> { pub async fn error(req: Request<Body>, msg: String) -> Result<Response<Body>, String> {
let url = req.uri().to_string();
let body = ErrorTemplate { let body = ErrorTemplate {
msg, msg,
prefs: Preferences::new(req), prefs: Preferences::new(req),
url,
} }
.render() .render()
.unwrap_or_default(); .unwrap_or_default();
Ok(Response::builder().status(404).header("content-type", "text/html").body(body.into()).unwrap_or_default()) Ok(Response::builder().status(404).header("content-type", "text/html").body(body.into()).unwrap_or_default())
} }
#[cfg(test)]
mod tests {
use super::format_num;
#[test]
fn format_num_works() {
assert_eq!(format_num(567), ("567".to_string(), "567".to_string()));
assert_eq!(format_num(1234), ("1.2k".to_string(), "1234".to_string()));
assert_eq!(format_num(1999), ("2.0k".to_string(), "1999".to_string()));
assert_eq!(format_num(1001), ("1.0k".to_string(), "1001".to_string()));
assert_eq!(format_num(1_999_999), ("2.0m".to_string(), "1999999".to_string()));
}
}

View File

@ -227,10 +227,15 @@ nav #libreddit {
#settings_link { #settings_link {
opacity: 0.8; opacity: 0.8;
margin-left: 10px;
}
#reddit_link {
opacity: 0.8;
} }
#code { #code {
margin-left: 5px; margin-left: 10px;
} }
main { main {
@ -653,6 +658,13 @@ a.search_subreddit:hover {
opacity: 0.5; opacity: 0.5;
} }
#more_subreddits {
justify-content: center;
color: var(--accent);
font-weight: 600;
text-align: center;
}
/* Post */ /* Post */
.sep { .sep {
@ -692,12 +704,12 @@ a.search_subreddit:hover {
.post_score { .post_score {
padding-top: 16px; padding-top: 16px;
padding-left: 12px;
font-size: 13px; font-size: 13px;
font-weight: bold; font-weight: bold;
text-align: end;
color: var(--accent); color: var(--accent);
grid-area: post_score; grid-area: post_score;
text-align: end; text-align: center;
border-radius: 5px 0 0 5px; border-radius: 5px 0 0 5px;
transition: 0.2s background; transition: 0.2s background;
} }
@ -707,7 +719,7 @@ a.search_subreddit:hover {
} }
.post_header { .post_header {
margin: 15px 20px 5px 15px; margin: 15px 20px 5px 12px;
grid-area: post_header; grid-area: post_header;
} }
@ -717,8 +729,9 @@ a.search_subreddit:hover {
.post_title { .post_title {
font-size: 16px; font-size: 16px;
font-weight: 500;
line-height: 1.5; line-height: 1.5;
margin: 5px 15px; margin: 5px 15px 5px 12px;
grid-area: post_title; grid-area: post_title;
} }
@ -832,11 +845,20 @@ a.search_subreddit:hover {
.post_body { .post_body {
opacity: 0.9; opacity: 0.9;
font-weight: normal; font-weight: normal;
margin: 5px 15px; padding: 5px 15px 5px 12px;
grid-area: post_body; grid-area: post_body;
width: calc(100% - 30px); width: calc(100% - 30px);
} }
/* Used only for text post preview */
.post_preview {
-webkit-mask-image: linear-gradient(180deg,#000 60%,transparent);;
mask-image: linear-gradient(180deg,#000 60%,transparent);
opacity: 0.8;
max-height: 250px;
overflow: hidden;
}
.post_footer { .post_footer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -956,7 +978,8 @@ a.search_subreddit:hover {
min-width: 40px; min-width: 40px;
border-radius: 5px; border-radius: 5px;
padding: 10px 0; padding: 10px 0;
font-size: 16px; font-size: 14px;
font-weight: 600;
} }
.comment_right { .comment_right {
@ -1027,6 +1050,10 @@ a.search_subreddit:hover {
background: var(--foreground); background: var(--foreground);
} }
summary.comment_data {
cursor: pointer;
}
.moderator, .admin { opacity: 1; } .moderator, .admin { opacity: 1; }
.op, .moderator, .admin { font-weight: bold; } .op, .moderator, .admin { font-weight: bold; }
@ -1061,7 +1088,7 @@ a.search_subreddit:hover {
} }
.compact .post_header { .compact .post_header {
margin: 15px 15px 2.5px 15px; margin: 15px 15px 2.5px 12px;
font-size: 14px; font-size: 14px;
} }
@ -1069,6 +1096,10 @@ a.search_subreddit:hover {
margin: 2.5px 15px; margin: 2.5px 15px;
} }
.compact .post_preview {
display: none;
}
.compact .post_media { .compact .post_media {
max-width: calc(100% - 30px); max-width: calc(100% - 30px);
margin: 2.5px auto; margin: 2.5px auto;
@ -1124,6 +1155,10 @@ a.search_subreddit:hover {
margin-top: 10px; margin-top: 10px;
} }
.prefs > p {
font-weight: 500;
}
.prefs select { .prefs select {
border-radius: 5px; border-radius: 5px;
box-shadow: var(--shadow); box-shadow: var(--shadow);
@ -1152,6 +1187,16 @@ input[type="submit"] {
margin-left: 30px; margin-left: 30px;
} }
#settings_subs a {
color: var(--accent);
}
.helper {
padding: 10px;
width: 250px;
background: var(--highlighted) !important;
}
/* Markdown */ /* Markdown */
.md { .md {
@ -1204,7 +1249,6 @@ input[type="submit"] {
.md table { .md table {
margin: 5px; margin: 5px;
display: block;
overflow-x: auto; overflow-x: auto;
} }

View File

@ -35,6 +35,12 @@
</div> </div>
{% block search %}{% endblock %} {% block search %}{% endblock %}
<div id="links"> <div id="links">
<a id="reddit_link" href="https://www.reddit.com{{ url }}">
<span>reddit</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M23 12.0737C23 10.7308 21.9222 9.64226 20.5926 9.64226C19.9435 9.64226 19.3557 9.90274 18.923 10.3244C17.2772 9.12492 15.0099 8.35046 12.4849 8.26135L13.5814 3.05002L17.1643 3.8195C17.2081 4.73947 17.9539 5.47368 18.8757 5.47368C19.8254 5.47368 20.5951 4.69626 20.5951 3.73684C20.5951 2.77769 19.8254 2 18.8758 2C18.2001 2 17.6214 2.39712 17.3404 2.96952L13.3393 2.11066C13.2279 2.08679 13.1116 2.10858 13.016 2.17125C12.9204 2.23393 12.8533 2.33235 12.8295 2.44491L11.6051 8.25987C9.04278 8.33175 6.73904 9.10729 5.07224 10.3201C4.63988 9.90099 4.05398 9.64226 3.40757 9.64226C2.0781 9.64226 1 10.7308 1 12.0737C1 13.0618 1.58457 13.9105 2.4225 14.2909C2.38466 14.5342 2.36545 14.78 2.36505 15.0263C2.36505 18.7673 6.67626 21.8 11.9945 21.8C17.3131 21.8 21.6243 18.7673 21.6243 15.0263C21.6243 14.7794 21.6043 14.5359 21.5678 14.2957C22.4109 13.9175 23 13.0657 23 12.0737Z"/>
</svg>
</a>
<a id="settings_link" href="/settings"> <a id="settings_link" href="/settings">
<span>settings</span> <span>settings</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">

View File

@ -8,7 +8,7 @@
<p class="comment_score" title="{{ score.1 }}">{{ score.0 }}</p> <p class="comment_score" title="{{ score.1 }}">{{ score.0 }}</p>
<div class="line"></div> <div class="line"></div>
</div> </div>
<details class="comment_right" open> <details class="comment_right" {% if collapsed == false %}open{% endif %}>
<summary class="comment_data"> <summary class="comment_data">
<a class="comment_author {{ author.distinguished }} {% if author.name == post_author %}op{% endif %}" href="/user/{{ author.name }}">u/{{ author.name }}</a> <a class="comment_author {{ author.distinguished }} {% if author.name == post_author %}op{% endif %}" href="/user/{{ author.name }}">u/{{ author.name }}</a>
{% if author.flair.flair_parts.len() > 0 %} {% if author.flair.flair_parts.len() > 0 %}

View File

@ -55,6 +55,7 @@
</p> </p>
<!-- POST MEDIA --> <!-- POST MEDIA -->
<!-- post_type: {{ post.post_type }} -->
{% if post.post_type == "image" %} {% if post.post_type == "image" %}
<a href="{{ post.media.url }}" class="post_media_image" > <a href="{{ post.media.url }}" class="post_media_image" >
<svg <svg
@ -70,13 +71,13 @@
{% else if post.post_type == "video" || post.post_type == "gif" %} {% else if post.post_type == "video" || post.post_type == "gif" %}
{% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %} {% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %}
<script src="/hls.min.js"></script> <script src="/hls.min.js"></script>
<video class="post_media_video short hls_autoplay" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" controls preload="none"> <video class="post_media_video short {% if prefs.autoplay_videos == "on" %}hls_autoplay{% endif %}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls>
<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" /> <source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
<source src="{{ post.media.url }}" type="video/mp4" /> <source src="{{ post.media.url }}" type="video/mp4" />
</video> </video>
<script src="/playHLSVideo.js"></script> <script src="/playHLSVideo.js"></script>
{% else %} {% else %}
<video class="post_media_video" src="{{ post.media.url }}" controls autoplay loop><a href={{ post.media.url }}>Video</a></video> <video class="post_media_video" src="{{ post.media.url }}" controls {% if prefs.autoplay_videos == "on" %}autoplay{% endif %} loop><a href={{ post.media.url }}>Video</a></video>
{% call utils::render_hls_notification(post.permalink[1..]) %} {% call utils::render_hls_notification(post.permalink[1..]) %}
{% endif %} {% endif %}
{% else if post.post_type == "gallery" %} {% else if post.post_type == "gallery" %}

View File

@ -17,6 +17,7 @@
<label for="restrict_sr" class="search_label">in r/{{ sub }}</label> <label for="restrict_sr" class="search_label">in r/{{ sub }}</label>
</div> </div>
{% endif %} {% endif %}
{% if params.typed == "sr_user" %}<input type="hidden" name="type" value="sr_user">{% endif %}
<select id="sort_options" name="sort" title="Sort results by"> <select id="sort_options" name="sort" title="Sort results by">
{% call utils::options(params.sort, ["relevance", "hot", "top", "new", "comments"], "") %} {% call utils::options(params.sort, ["relevance", "hot", "top", "new", "comments"], "") %}
</select>{% if params.sort != "new" %}<select id="timeframe" name="t" title="Timeframe"> </select>{% if params.sort != "new" %}<select id="timeframe" name="t" title="Timeframe">
@ -30,8 +31,11 @@
</button> </button>
</form> </form>
{% if subreddits.len() > 0 %} {% if subreddits.len() > 0 || params.typed == "sr_user" %}
<div id="search_subreddits"> <div id="search_subreddits">
{% if params.typed == "sr_user" %}
<a href="?q={{ params.q }}&sort={{ params.sort }}&t={{ params.t }}" class="search_subreddit" id="more_subreddits">← Back to post/comment results</a>
{% endif %}
{% for subreddit in subreddits %} {% for subreddit in subreddits %}
<a href="{{ subreddit.url }}" class="search_subreddit"> <a href="{{ subreddit.url }}" class="search_subreddit">
<div class="search_subreddit_left">{% if subreddit.icon != "" %}<img loading="lazy" src="{{ subreddit.icon }}" alt="r/{{ subreddit.name }} icon">{% endif %}</div> <div class="search_subreddit_left">{% if subreddit.icon != "" %}<img loading="lazy" src="{{ subreddit.icon }}" alt="r/{{ subreddit.name }} icon">{% endif %}</div>
@ -45,10 +49,13 @@
</div> </div>
</a> </a>
{% endfor %} {% endfor %}
{% if params.typed != "sr_user" %}
<a href="?q={{ params.q }}&sort={{ params.sort }}&t={{ params.t }}&type=sr_user" class="search_subreddit" id="more_subreddits">More subreddit results →</a>
{% endif %}
</div> </div>
{% endif %} {% endif %}
{% if params.typed != "sr_user" %}
{% for post in posts %} {% for post in posts %}
{% if post.flags.nsfw && prefs.show_nsfw != "on" %} {% if post.flags.nsfw && prefs.show_nsfw != "on" %}
{% else if post.title != "Comment" %} {% else if post.title != "Comment" %}
{% call utils::post_in_list(post) %} {% call utils::post_in_list(post) %}
@ -68,11 +75,13 @@
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %}
{% if prefs.use_hls == "on" %} {% if prefs.use_hls == "on" %}
<script src="/hls.min.js"></script> <script src="/hls.min.js"></script>
<script src="/playHLSVideo.js"></script> <script src="/playHLSVideo.js"></script>
{% endif %} {% endif %}
{% if params.typed != "sr_user" %}
<footer> <footer>
{% if params.before != "" %} {% if params.before != "" %}
<a href="?q={{ params.q }}&restrict_sr={{ params.restrict_sr }} <a href="?q={{ params.q }}&restrict_sr={{ params.restrict_sr }}
@ -86,5 +95,6 @@
&after={{ params.after }}">NEXT</a> &after={{ params.after }}">NEXT</a>
{% endif %} {% endif %}
</footer> </footer>
{% endif %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -54,8 +54,18 @@
<input type="hidden" value="off" name="show_nsfw"> <input type="hidden" value="off" name="show_nsfw">
<input type="checkbox" name="show_nsfw" {% if prefs.show_nsfw == "on" %}checked{% endif %}> <input type="checkbox" name="show_nsfw" {% if prefs.show_nsfw == "on" %}checked{% endif %}>
</div> </div>
<div id="autoplay_videos">
<label for="autoplay_videos">Autoplay videos</label>
<input type="hidden" value="off" name="autoplay_videos">
<input type="checkbox" name="autoplay_videos" {% if prefs.autoplay_videos == "on" %}checked{% endif %}>
</div>
<div id="use_hls"> <div id="use_hls">
<label for="use_hls">Use HLS for videos</label> <label for="use_hls">Use HLS for videos
<details id="feeds">
<summary>Why?</summary>
<div id="feed_list" class="helper">Reddit videos require JavaScript (via HLS.js) to be enabled to be played with audio. Therefore, this toggle lets you either use Libreddit JS-free or utilize this feature.</div>
</details>
</label>
<input type="hidden" value="off" name="use_hls"> <input type="hidden" value="off" name="use_hls">
<input type="checkbox" name="use_hls" {% if prefs.use_hls == "on" %}checked{% endif %}> <input type="checkbox" name="use_hls" {% if prefs.use_hls == "on" %}checked{% endif %}>
</div> </div>
@ -72,7 +82,9 @@
<p>Subscribed Feeds</p> <p>Subscribed Feeds</p>
{% for sub in prefs.subscriptions %} {% for sub in prefs.subscriptions %}
<div> <div>
<span>{% if sub.starts_with("u_") -%}{{ format!("u/{}", &sub[2..]) }}{% else -%}{{ format!("r/{}", sub) }}{% endif -%}</span> {% let feed -%}
{% if sub.starts_with("u_") -%}{% let feed = format!("u/{}", &sub[2..]) -%}{% else -%}{% let feed = format!("r/{}", sub) -%}{% endif -%}
<a href="/{{ feed }}">{{ feed }}</a>
<form action="/r/{{ sub }}/unsubscribe/?redirect=settings" method="POST"> <form action="/r/{{ sub }}/unsubscribe/?redirect=settings" method="POST">
<button class="unsubscribe">Unsubscribe</button> <button class="unsubscribe">Unsubscribe</button>
</form> </form>

View File

@ -99,15 +99,15 @@
</svg> </svg>
</a> </a>
{% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "gif" %} {% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "gif" %}
<video class="post_media_video short" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" controls loop autoplay><a href={{ post.media.url }}>Video</a></video> <video class="post_media_video short" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls loop {% if prefs.autoplay_videos == "on" %}autoplay{% endif %}><a href={{ post.media.url }}>Video</a></video>
{% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "video" %} {% else if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "video" %}
{% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %} {% if prefs.use_hls == "on" && !post.media.alt_url.is_empty() %}
<video class="post_media_video short" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" controls preload="none"> <video class="post_media_video short {% if prefs.autoplay_videos == "on" %}hls_autoplay{% endif %}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" controls preload="none">
<source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" /> <source src="{{ post.media.alt_url }}" type="application/vnd.apple.mpegurl" />
<source src="{{ post.media.url }}" type="video/mp4" /> <source src="{{ post.media.url }}" type="video/mp4" />
</video> </video>
{% else %} {% else %}
<video class="post_media_video short" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls autoplay><a href={{ post.media.url }}>Video</a></video> <video class="post_media_video short" src="{{ post.media.url }}" width="{{ post.media.width }}" height="{{ post.media.height }}" poster="{{ post.media.poster }}" preload="none" controls {% if prefs.autoplay_videos == "on" %}autoplay{% endif %}><a href={{ post.media.url }}>Video</a></video>
{% call render_hls_notification(format!("{}%23{}", &self.url[1..].replace("&", "%26").replace("+", "%2B"), post.id)) %} {% call render_hls_notification(format!("{}%23{}", &self.url[1..].replace("&", "%26").replace("+", "%2B"), post.id)) %}
{% endif %} {% endif %}
{% else if post.post_type != "self" %} {% else if post.post_type != "self" %}
@ -130,6 +130,9 @@
{% endif %} {% endif %}
<div class="post_score" title="{{ post.score.1 }}">{{ post.score.0 }}<span class="label"> Upvotes</span></div> <div class="post_score" title="{{ post.score.1 }}">{{ post.score.0 }}<span class="label"> Upvotes</span></div>
<div class="post_body post_preview">
{{ post.body }}
</div>
<div class="post_footer"> <div class="post_footer">
<a href="{{ post.permalink }}" class="post_comments" title="{{ post.comments.1 }} comments">{{ post.comments.0 }} comments</a> <a href="{{ post.permalink }}" class="post_comments" title="{{ post.comments.1 }} comments">{{ post.comments.0 }} comments</a>
</div> </div>