Merge redesign into main (#111)
|
@ -0,0 +1,47 @@
|
||||||
|
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format
|
||||||
|
|
||||||
|
# Working directory
|
||||||
|
# . or absolute path, please note that the directories following must be under root.
|
||||||
|
root = "."
|
||||||
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
# Just plain old shell command. You could use `make` as well.
|
||||||
|
cmd = "ENV=dev go build -o ./tmp/rimgo ./main.go"
|
||||||
|
# Binary file yields from `cmd`.
|
||||||
|
bin = "./tmp/rimgo"
|
||||||
|
# Customize binary.
|
||||||
|
full_bin = "./tmp/rimgo"
|
||||||
|
# Watch these filename extensions.
|
||||||
|
include_ext = ["go", "tpl", "tmpl", "html", "mustache", "hbs", "pug", "css"]
|
||||||
|
# Ignore these filename extensions or directories.
|
||||||
|
exclude_dir = ["tmp", "vendor", "node_modules"]
|
||||||
|
# Watch these directories if you specified.
|
||||||
|
include_dir = []
|
||||||
|
# Exclude files.
|
||||||
|
exclude_file = []
|
||||||
|
# This log file places in your tmp_dir.
|
||||||
|
log = "air.log"
|
||||||
|
# It's not necessary to trigger build each time file changes if it's too frequent.
|
||||||
|
delay = 1000 # ms
|
||||||
|
# Stop running old binary when build errors occur.
|
||||||
|
stop_on_error = true
|
||||||
|
# Send Interrupt signal before killing process (windows does not support this feature)
|
||||||
|
send_interrupt = false
|
||||||
|
# Delay after sending Interrupt signal
|
||||||
|
kill_delay = 500 # ms
|
||||||
|
|
||||||
|
[log]
|
||||||
|
# Show log time
|
||||||
|
time = false
|
||||||
|
|
||||||
|
[color]
|
||||||
|
# Customize each part's color. If no color found, use the raw app log.
|
||||||
|
main = "magenta"
|
||||||
|
watcher = "cyan"
|
||||||
|
build = "yellow"
|
||||||
|
runner = "green"
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
# Delete tmp directory on exit
|
||||||
|
clean_on_exit = true
|
|
@ -1,3 +1,3 @@
|
||||||
node_modules
|
.env
|
||||||
samples
|
tmp
|
||||||
dist
|
static/app.css
|
|
@ -1,3 +1,3 @@
|
||||||
dist
|
.env
|
||||||
node_modules
|
tmp
|
||||||
.env
|
static/app.css
|
10
api/user.go
|
@ -3,6 +3,7 @@ package api
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -34,6 +35,8 @@ type Submission struct {
|
||||||
IsAlbum bool
|
IsAlbum bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var imgurRe = regexp.MustCompile(`https?://i?\.?imgur\.com`)
|
||||||
|
|
||||||
func (client *Client) FetchUser(username string) (User, error) {
|
func (client *Client) FetchUser(username string) (User, error) {
|
||||||
cacheData, found := client.Cache.Get(username + "-user")
|
cacheData, found := client.Cache.Get(username + "-user")
|
||||||
if found {
|
if found {
|
||||||
|
@ -108,10 +111,15 @@ func (client *Client) FetchSubmissions(username string, sort string, page string
|
||||||
}
|
}
|
||||||
|
|
||||||
id := value.Get("id").String()
|
id := value.Get("id").String()
|
||||||
|
|
||||||
|
link := "/a/" + id
|
||||||
|
if value.Get("in_gallery").Bool() {
|
||||||
|
link = "/gallery/" + id
|
||||||
|
}
|
||||||
|
|
||||||
submissions = append(submissions, Submission{
|
submissions = append(submissions, Submission{
|
||||||
Id: id,
|
Id: id,
|
||||||
Link: "/a/" + id,
|
Link: link,
|
||||||
Title: value.Get("title").String(),
|
Title: value.Get("title").String(),
|
||||||
Cover: cover,
|
Cover: cover,
|
||||||
Points: value.Get("points").Int(),
|
Points: value.Get("points").Int(),
|
||||||
|
|
51
main.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"codeberg.org/video-prize-ranch/rimgo/pages"
|
"codeberg.org/video-prize-ranch/rimgo/pages"
|
||||||
|
@ -29,8 +30,12 @@ func main() {
|
||||||
|
|
||||||
pages.InitializeApiClient()
|
pages.InitializeApiClient()
|
||||||
|
|
||||||
engine := handlebars.NewFileSystem(http.FS(views.GetFiles()), ".hbs")
|
views := http.FS(views.GetFiles())
|
||||||
|
if os.Getenv("ENV") == "dev" {
|
||||||
|
views = http.Dir("./views")
|
||||||
|
}
|
||||||
|
engine := handlebars.NewFileSystem(views, ".hbs")
|
||||||
|
|
||||||
engine.AddFunc("noteq", func(a interface{}, b interface{}, options *raymond.Options) interface{} {
|
engine.AddFunc("noteq", func(a interface{}, b interface{}, options *raymond.Options) interface{} {
|
||||||
if raymond.Str(a) != raymond.Str(b) {
|
if raymond.Str(a) != raymond.Str(b) {
|
||||||
return options.Fn()
|
return options.Fn()
|
||||||
|
@ -67,19 +72,34 @@ func main() {
|
||||||
fmt.Println(e)
|
fmt.Println(e)
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
app.Use("/static", filesystem.New(filesystem.Config{
|
|
||||||
Next: func(c *fiber.Ctx) bool {
|
if os.Getenv("ENV") == "dev" {
|
||||||
c.Response().Header.Add("Cache-Control", "public,max-age=2592000")
|
app.Use("/static", filesystem.New(filesystem.Config{
|
||||||
return false
|
MaxAge: 2592000,
|
||||||
},
|
Root: http.Dir("./static"),
|
||||||
Root: http.FS(static.GetFiles()),
|
}))
|
||||||
}))
|
app.Get("/errors/429", func(c *fiber.Ctx) error {
|
||||||
app.Use(cache.New(cache.Config{
|
return c.Render("errors/429", nil)
|
||||||
Expiration: 30 * time.Minute,
|
})
|
||||||
MaxBytes: 25000000,
|
app.Get("/errors/404", func(c *fiber.Ctx) error {
|
||||||
CacheControl: true,
|
return c.Render("errors/404", nil)
|
||||||
StoreResponseHeaders: true,
|
})
|
||||||
}))
|
app.Get("/errors/error", func(c *fiber.Ctx) error {
|
||||||
|
return c.Render("errors/error", fiber.Map{
|
||||||
|
"err": "Test error",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
app.Use("/static", filesystem.New(filesystem.Config{
|
||||||
|
Root: http.FS(static.GetFiles()),
|
||||||
|
}))
|
||||||
|
app.Use(cache.New(cache.Config{
|
||||||
|
Expiration: 30 * time.Minute,
|
||||||
|
MaxBytes: 25000000,
|
||||||
|
CacheControl: true,
|
||||||
|
StoreResponseHeaders: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
app.Get("/robots.txt", func(c *fiber.Ctx) error {
|
app.Get("/robots.txt", func(c *fiber.Ctx) error {
|
||||||
file, _ := static.GetFiles().ReadFile("robots.txt")
|
file, _ := static.GetFiles().ReadFile("robots.txt")
|
||||||
|
@ -93,6 +113,7 @@ func main() {
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/", pages.HandleFrontpage)
|
app.Get("/", pages.HandleFrontpage)
|
||||||
|
app.Get("/about", pages.HandleAbout)
|
||||||
app.Get("/privacy", pages.HandlePrivacy)
|
app.Get("/privacy", pages.HandlePrivacy)
|
||||||
app.Get("/a/:postID", pages.HandlePost)
|
app.Get("/a/:postID", pages.HandlePost)
|
||||||
app.Get("/a/:postID/embed", pages.HandleEmbed)
|
app.Get("/a/:postID/embed", pages.HandleEmbed)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package pages
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"codeberg.org/video-prize-ranch/rimgo/utils"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func HandleAbout(c *fiber.Ctx) error {
|
||||||
|
utils.SetHeaders(c)
|
||||||
|
c.Set("X-Frame-Options", "DENY")
|
||||||
|
c.Set("Cache-Control", "public,max-age=31557600")
|
||||||
|
c.Set("Content-Security-Policy", "default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'; style-src 'self'; img-src 'self'; manifest-src 'self'; block-all-mixed-content")
|
||||||
|
|
||||||
|
return c.Render("about", fiber.Map{
|
||||||
|
"proto": c.Protocol(),
|
||||||
|
"domain": c.Hostname(),
|
||||||
|
"force_webp": os.Getenv("FORCE_WEBP"),
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package pages
|
package pages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
|
|
||||||
"codeberg.org/video-prize-ranch/rimgo/utils"
|
"codeberg.org/video-prize-ranch/rimgo/utils"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var VersionInfo string
|
||||||
|
|
||||||
func HandleFrontpage(c *fiber.Ctx) error {
|
func HandleFrontpage(c *fiber.Ctx) error {
|
||||||
utils.SetHeaders(c)
|
utils.SetHeaders(c)
|
||||||
c.Set("X-Frame-Options", "DENY")
|
c.Set("X-Frame-Options", "DENY")
|
||||||
|
@ -14,8 +14,7 @@ func HandleFrontpage(c *fiber.Ctx) error {
|
||||||
c.Set("Content-Security-Policy", "default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'; style-src 'self'; img-src 'self'; manifest-src 'self'; block-all-mixed-content")
|
c.Set("Content-Security-Policy", "default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'; style-src 'self'; img-src 'self'; manifest-src 'self'; block-all-mixed-content")
|
||||||
|
|
||||||
return c.Render("frontpage", fiber.Map{
|
return c.Render("frontpage", fiber.Map{
|
||||||
"proto": c.Protocol(),
|
"config": utils.Config,
|
||||||
"domain": c.Hostname(),
|
"version": VersionInfo,
|
||||||
"force_webp": os.Getenv("FORCE_WEBP"),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -59,17 +59,21 @@ func handleMedia(c *fiber.Ctx, url string) error {
|
||||||
|
|
||||||
c.Status(res.StatusCode)
|
c.Status(res.StatusCode)
|
||||||
if res.StatusCode == 404 {
|
if res.StatusCode == 404 {
|
||||||
return c.Render("errors/404", nil)
|
return c.Render("errors/404", fiber.Map{
|
||||||
|
"path": c.Path(),
|
||||||
|
})
|
||||||
} else if res.StatusCode == 429 {
|
} else if res.StatusCode == 429 {
|
||||||
return c.Render("errors/429", nil)
|
return c.Render("errors/429", fiber.Map{
|
||||||
|
"path": c.Path(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Set("Accept-Ranges", "bytes")
|
c.Set("Accept-Ranges", "bytes")
|
||||||
c.Set("Content-Type", res.Header.Get("Content-Type"));
|
c.Set("Content-Type", res.Header.Get("Content-Type"));
|
||||||
c.Set("Content-Length", res.Header.Get("Content-Length"))
|
c.Set("Content-Length", res.Header.Get("Content-Length"))
|
||||||
if res.Header.Get("Content-Range") != "" {
|
if res.Header.Get("Content-Range") != "" {
|
||||||
c.Set("Content-Range", res.Header.Get("Content-Range"))
|
c.Set("Content-Range", res.Header.Get("Content-Range"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SendStream(res.Body)
|
return c.SendStream(res.Body)
|
||||||
}
|
}
|
|
@ -24,7 +24,9 @@ func HandlePost(c *fiber.Ctx) error {
|
||||||
post, err = ApiClient.FetchMedia(c.Params("postID"))
|
post, err = ApiClient.FetchMedia(c.Params("postID"))
|
||||||
}
|
}
|
||||||
if err != nil && err.Error() == "ratelimited by imgur" {
|
if err != nil && err.Error() == "ratelimited by imgur" {
|
||||||
return c.Status(429).Render("errors/429", nil)
|
return c.Status(429).Render("errors/429", fiber.Map{
|
||||||
|
"path": c.Path(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if err != nil && post.Id == "" && strings.Contains(err.Error(), "404") {
|
if err != nil && post.Id == "" && strings.Contains(err.Error(), "404") {
|
||||||
return c.Status(404).Render("errors/404", nil)
|
return c.Status(404).Render("errors/404", nil)
|
||||||
|
|
|
@ -6,8 +6,6 @@ import (
|
||||||
"codeberg.org/video-prize-ranch/rimgo/utils"
|
"codeberg.org/video-prize-ranch/rimgo/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var VersionInfo string
|
|
||||||
|
|
||||||
func HandlePrivacy(c *fiber.Ctx) error {
|
func HandlePrivacy(c *fiber.Ctx) error {
|
||||||
utils.SetHeaders(c)
|
utils.SetHeaders(c)
|
||||||
c.Set("X-Frame-Options", "DENY")
|
c.Set("X-Frame-Options", "DENY")
|
||||||
|
|
|
@ -30,7 +30,9 @@ func HandleTag(c *fiber.Ctx) error {
|
||||||
|
|
||||||
tag, err := ApiClient.FetchTag(c.Params("tag"), c.Query("sort"), page)
|
tag, err := ApiClient.FetchTag(c.Params("tag"), c.Query("sort"), page)
|
||||||
if err != nil && err.Error() == "ratelimited by imgur" {
|
if err != nil && err.Error() == "ratelimited by imgur" {
|
||||||
return c.Status(429).Render("errors/429", nil)
|
return c.Status(429).Render("errors/429", fiber.Map{
|
||||||
|
"path": c.Path(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -25,7 +25,9 @@ func HandleUser(c *fiber.Ctx) error {
|
||||||
|
|
||||||
user, err := ApiClient.FetchUser(c.Params("userID"))
|
user, err := ApiClient.FetchUser(c.Params("userID"))
|
||||||
if err != nil && err.Error() == "ratelimited by imgur" {
|
if err != nil && err.Error() == "ratelimited by imgur" {
|
||||||
return c.Status(429).Render("errors/429", nil)
|
return c.Status(429).Render("errors/429", fiber.Map{
|
||||||
|
"path": c.Path(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -37,7 +39,9 @@ func HandleUser(c *fiber.Ctx) error {
|
||||||
submissions, err := ApiClient.FetchSubmissions(c.Params("userID"), "newest", page)
|
submissions, err := ApiClient.FetchSubmissions(c.Params("userID"), "newest", page)
|
||||||
if err != nil && err.Error() == "ratelimited by imgur" {
|
if err != nil && err.Error() == "ratelimited by imgur" {
|
||||||
c.Status(429)
|
c.Status(429)
|
||||||
return c.Render("errors/429", nil)
|
return c.Render("errors/429", fiber.Map{
|
||||||
|
"path": c.Path(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M231.39 132.94A8 8 0 0 0 224 128h-40V48a16 16 0 0 0-16-16H88a16 16 0 0 0-16 16v80H32a8 8 0 0 0-5.66 13.66l96 96a8 8 0 0 0 11.32 0l96-96a8 8 0 0 0 1.73-8.72ZM128 220.69L51.31 144H80a8 8 0 0 0 8-8V48h80v88a8 8 0 0 0 8 8h28.69Z"/></svg>
|
After Width: | Height: | Size: 347 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="m229.66 114.34l-96-96a8 8 0 0 0-11.32 0l-96 96A8 8 0 0 0 32 128h40v80a16 16 0 0 0 16 16h80a16 16 0 0 0 16-16v-80h40a8 8 0 0 0 5.66-13.66ZM176 112a8 8 0 0 0-8 8v88H88v-88a8 8 0 0 0-8-8H51.31L128 35.31L204.69 112Z"/></svg>
|
After Width: | Height: | Size: 334 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M216 48H40a16 16 0 0 0-16 16v160a15.84 15.84 0 0 0 9.25 14.5A16.05 16.05 0 0 0 40 240a15.89 15.89 0 0 0 10.25-3.78a.69.69 0 0 0 .13-.11L82.5 208H216a16 16 0 0 0 16-16V64a16 16 0 0 0-16-16ZM40 224Zm176-32H82.5a16 16 0 0 0-10.3 3.75l-.12.11L40 224V64h176Z"/></svg>
|
After Width: | Height: | Size: 376 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M173.66 98.34a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0ZM232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104Zm-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88Z"/></svg>
|
After Width: | Height: | Size: 355 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M224 72h-16v-8a24 24 0 0 0-24-24H40a24 24 0 0 0-24 24v96a24 24 0 0 0 24 24h112v8a24 24 0 0 0 24 24h48a24 24 0 0 0 24-24V96a24 24 0 0 0-24-24ZM40 168a8 8 0 0 1-8-8V64a8 8 0 0 1 8-8h144a8 8 0 0 1 8 8v8h-16a24 24 0 0 0-24 24v72Zm192 24a8 8 0 0 1-8 8h-48a8 8 0 0 1-8-8V96a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8Zm-96 16a8 8 0 0 1-8 8H88a8 8 0 0 1 0-16h40a8 8 0 0 1 8 8Zm80-96a8 8 0 0 1-8 8h-16a8 8 0 0 1 0-16h16a8 8 0 0 1 8 8Z"/></svg>
|
After Width: | Height: | Size: 536 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M247.31 124.76c-.35-.79-8.82-19.58-27.65-38.41C194.57 61.26 162.88 48 128 48S61.43 61.26 36.34 86.35C17.51 105.18 9 124 8.69 124.76a8 8 0 0 0 0 6.5c.35.79 8.82 19.57 27.65 38.4C61.43 194.74 93.12 208 128 208s66.57-13.26 91.66-38.34c18.83-18.83 27.3-37.61 27.65-38.4a8 8 0 0 0 0-6.5ZM128 192c-30.78 0-57.67-11.19-79.93-33.25A133.47 133.47 0 0 1 25 128a133.33 133.33 0 0 1 23.07-30.75C70.33 75.19 97.22 64 128 64s57.67 11.19 79.93 33.25A133.46 133.46 0 0 1 231.05 128c-7.21 13.46-38.62 64-103.05 64Zm0-112a48 48 0 1 0 48 48a48.05 48.05 0 0 0-48-48Zm0 80a32 32 0 1 1 32-32a32 32 0 0 1-32 32Z"/></svg>
|
After Width: | Height: | Size: 711 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24Zm-26.37 144h52.74C149 186.34 140 202.87 128 215.89c-12-13.02-21-29.55-26.37-47.89ZM98 152a145.72 145.72 0 0 1 0-48h60a145.72 145.72 0 0 1 0 48Zm-58-24a87.61 87.61 0 0 1 3.33-24h38.46a161.79 161.79 0 0 0 0 48H43.33A87.61 87.61 0 0 1 40 128Zm114.37-40h-52.74C107 69.66 116 53.13 128 40.11c12 13.02 21 29.55 26.37 47.89Zm19.84 16h38.46a88.15 88.15 0 0 1 0 48h-38.46a161.79 161.79 0 0 0 0-48Zm32.16-16h-35.43a142.39 142.39 0 0 0-20.26-45a88.37 88.37 0 0 1 55.69 45ZM105.32 43a142.39 142.39 0 0 0-20.26 45H49.63a88.37 88.37 0 0 1 55.69-45ZM49.63 168h35.43a142.39 142.39 0 0 0 20.26 45a88.37 88.37 0 0 1-55.69-45Zm101.05 45a142.39 142.39 0 0 0 20.26-45h35.43a88.37 88.37 0 0 1-55.69 45Z"/></svg>
|
After Width: | Height: | Size: 860 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M137.54 186.36a8 8 0 0 1 0 11.31l-9.94 10a56 56 0 0 1-79.22-79.27l24.12-24.12a56 56 0 0 1 76.81-2.28a8 8 0 1 1-10.64 12a40 40 0 0 0-54.85 1.63L59.7 139.72a40 40 0 0 0 56.58 56.58l9.94-9.94a8 8 0 0 1 11.32 0Zm70.08-138a56.08 56.08 0 0 0-79.22 0l-9.94 9.95a8 8 0 0 0 11.32 11.31l9.94-9.94a40 40 0 0 1 56.58 56.58l-24.12 24.14a40 40 0 0 1-54.85 1.6a8 8 0 1 0-10.64 12a56 56 0 0 0 76.81-2.26l24.12-24.12a56.08 56.08 0 0 0 0-79.24Z"/></svg>
|
After Width: | Height: | Size: 549 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M236.8 188.09L149.35 36.22a24.76 24.76 0 0 0-42.7 0L19.2 188.09a23.51 23.51 0 0 0 0 23.72A24.35 24.35 0 0 0 40.55 224h174.9a24.35 24.35 0 0 0 21.33-12.19a23.51 23.51 0 0 0 .02-23.72Zm-13.87 15.71a8.5 8.5 0 0 1-7.48 4.2H40.55a8.5 8.5 0 0 1-7.48-4.2a7.59 7.59 0 0 1 0-7.72l87.45-151.87a8.75 8.75 0 0 1 15 0l87.45 151.87a7.59 7.59 0 0 1-.04 7.72ZM120 144v-40a8 8 0 0 1 16 0v40a8 8 0 0 1-16 0Zm20 36a12 12 0 1 1-12-12a12 12 0 0 1 12 12Z"/></svg>
|
After Width: | Height: | Size: 555 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24Zm0 192a88 88 0 1 1 88-88a88.1 88.1 0 0 1-88 88Zm-8-80V80a8 8 0 0 1 16 0v56a8 8 0 0 1-16 0Zm20 36a12 12 0 1 1-12-12a12 12 0 0 1 12 12Z"/></svg>
|
After Width: | Height: | Size: 313 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="currentColor" d="M226.76 69a8 8 0 0 0-12.84-2.88l-40.3 37.19l-17.23-3.7l-3.7-17.23l37.19-40.3A8 8 0 0 0 187 29.24A72 72 0 0 0 88 96a72.34 72.34 0 0 0 6 28.94L33.79 177c-.15.12-.29.26-.43.39a32 32 0 0 0 45.26 45.26c.13-.13.27-.28.39-.42L131.06 162A72 72 0 0 0 232 96a71.56 71.56 0 0 0-5.24-27ZM160 152a56.14 56.14 0 0 1-27.07-7a8 8 0 0 0-9.92 1.77l-55.9 64.74a16 16 0 0 1-22.62-22.62L109.18 133a8 8 0 0 0 1.77-9.93a56 56 0 0 1 58.36-82.31l-31.2 33.81a8 8 0 0 0-1.94 7.1l5.66 26.33a8 8 0 0 0 6.14 6.14l26.35 5.66a8 8 0 0 0 7.1-1.94l33.81-31.2A56.06 56.06 0 0 1 160 152Z"/></svg>
|
After Width: | Height: | Size: 673 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#2b95f2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-alert-circle"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
|
|
Before Width: | Height: | Size: 351 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#2b95f2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-alert-triangle"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
|
Before Width: | Height: | Size: 419 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#2b95f2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check-circle"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
|
|
Before Width: | Height: | Size: 323 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-down"><polyline points="6 9 12 15 18 9"></polyline></svg>
|
|
Before Width: | Height: | Size: 269 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-up"><polyline points="18 15 12 9 6 15"></polyline></svg>
|
|
Before Width: | Height: | Size: 268 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
|
|
Before Width: | Height: | Size: 316 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-hash"><line x1="4" y1="9" x2="20" y2="9"></line><line x1="4" y1="15" x2="20" y2="15"></line><line x1="10" y1="3" x2="8" y2="21"></line><line x1="16" y1="3" x2="14" y2="21"></line></svg>
|
|
Before Width: | Height: | Size: 389 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
|
Before Width: | Height: | Size: 371 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-message-square"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
|
|
Before Width: | Height: | Size: 305 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-smartphone"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line></svg>
|
|
Before Width: | Height: | Size: 332 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tool"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg>
|
|
Before Width: | Height: | Size: 386 B |
|
@ -0,0 +1,74 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0 24vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
p a {
|
||||||
|
text-decoration: underline
|
||||||
|
}
|
||||||
|
|
||||||
|
.posts {
|
||||||
|
margin-top: 1em;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.posts img:not(.icon),
|
||||||
|
.posts video:not(:fullscreen) {
|
||||||
|
object-fit: cover;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#comments__expandBtn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comments__expandBtn__label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
.comments__expandBtn__icon {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#comments__expandBtn ~ .comments__expandBtn__label > span::after {
|
||||||
|
content: "⌄";
|
||||||
|
}
|
||||||
|
|
||||||
|
#comments__expandBtn:checked ~ .comments__expandBtn__label > span::after {
|
||||||
|
content: "⌃";
|
||||||
|
}
|
||||||
|
|
||||||
|
#comments__expandBtn:checked ~ .comments {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment__media {
|
||||||
|
height: 12em;
|
||||||
|
display: block;
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1280px) {
|
||||||
|
body {
|
||||||
|
margin: 0 8vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 812px) {
|
||||||
|
body {
|
||||||
|
margin: 0 4vw;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
content: ["./views/*.hbs", "./views/**/*.hbs"],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
variants: {},
|
||||||
|
plugins: [],
|
||||||
|
};
|
|
@ -0,0 +1,105 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>About - rimgo</title>
|
||||||
|
|
||||||
|
{{> partials/head }}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
|
{{> partials/nav }}
|
||||||
|
|
||||||
|
<main class="my-8">
|
||||||
|
<p>An alternative frontend for Imgur. Originally based on <a href="https://codeberg.org/3np/rimgu" rel="noreferrer">rimgu</a>.</p>
|
||||||
|
|
||||||
|
<h2 class="font-bold text-2xl my-2">Features</h2>
|
||||||
|
<ul class="list-disc ml-4">
|
||||||
|
<li>Lightweight</li>
|
||||||
|
<li>No JavaScript</li>
|
||||||
|
<li>No ads or tracking</li>
|
||||||
|
<li>No sign up or app install prompts</li>
|
||||||
|
<li>Bandwidth efficient - automatically uses newer image formats (if enabled)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2 class="font-bold text-2xl my-2">Comparison</h2>
|
||||||
|
<p>Comparing rimgo to Imgur.</p>
|
||||||
|
|
||||||
|
<h3 class="font-bold text-xl my-2">Speed</h3>
|
||||||
|
<p>Tested using <a href="https://pagespeed.web.dev/" rel="nofollow noreferrer">Google PageSpeed Insights</a>.</p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td><a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fi.bcow.xyz%2Fgallery%2FgYiQLWy" rel="nofollow noreferrer">rimgo</a></td>
|
||||||
|
<td><a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fimgur.com%2Fgallery%2FgYiQLWy" rel="nofollow noreferrer">Imgur</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Performance</td>
|
||||||
|
<td>91</td>
|
||||||
|
<td>28</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Request count</td>
|
||||||
|
<td>29</td>
|
||||||
|
<td>340</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Resource Size</td>
|
||||||
|
<td>218 KiB</td>
|
||||||
|
<td>2,542 KiB</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Time to Interactive</td>
|
||||||
|
<td>1.6s</td>
|
||||||
|
<td>23.8s</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3 class="font-bold text-xl my-2">Privacy</h3>
|
||||||
|
<p>Imgur collects information about your device and uses tracking cookies for advertising, this is mentioned in their <a href="https://imgur.com/privacy/" rel="nofollow noreferrer">privacy policy</a>. <a href="https://themarkup.org/blacklight" rel="nofollow noreferrer">Blacklight</a> found 31 trackers and 87 third-party cookies.</p>
|
||||||
|
<p>See what cookies and trackers Imgur uses and where your data gets sent: <a href="https://themarkup.org/blacklight?url=imgur.com" rel="nofollow noreferrer">https://themarkup.org/blacklight?url=imgur.com</a></p>
|
||||||
|
|
||||||
|
<h2 class="font-bold text-2xl my-2">Usage</h2>
|
||||||
|
<p>Just replace imgur.com or i.imgur.com with <code>{{domain}}</code> (add stack/ before the media ID for i.stack.imgur.com). You can setup automatic redirects using <a href="https://github.com/libredirect/libredirect" rel="nofollow noreferrer">LibRedirect</a> (recommended) or <a href="https://github.com/einaregilsson/Redirector" rel="nofollow noreferrer">Redirector</a>.</p>
|
||||||
|
|
||||||
|
{{#if force_webp}}
|
||||||
|
<p>To download images as their original filetype, add <code>?no_webp=1</code> to the end of the image URL.</p>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<h2 class="font-bold text-2xl my-2">Automatically redirect links</h2>
|
||||||
|
|
||||||
|
<h3 class="font-bold text-xl my-2">LibRedirect</h3>
|
||||||
|
<p>Use <a href="https://github.com/libredirect/libredirect" rel="nofollow noreferrer">LibRedirect</a> to automatically redirect Imgur links to rimgo!</p>
|
||||||
|
|
||||||
|
<h3 class="font-bold text-xl my-2">GreaseMonkey script</h3>
|
||||||
|
<p>There is a script to redirect Imgur links to rimgo. <a rel="noreferrer" href="https://codeberg.org/zortazert/GreaseMonkey-Redirect/src/branch/main/imgur-to-rimgo.user.js">https://codeberg.org/zortazert/GreaseMonkey-Redirect/src/branch/main/imgur-to-rimgo.user.js</a></p>
|
||||||
|
|
||||||
|
<h3 class="font-bold text-xl my-2">Redirector</h3>
|
||||||
|
<p>You can use the <a href="https://github.com/einaregilsson/Redirector" rel="nofollow noreferrer">Redirector</a> extension to redirect Imgur links to rimgo with the configuration below:</p>
|
||||||
|
<ul class="list-disc ml-4">
|
||||||
|
<li>Description: Imgur -> rimgo</li>
|
||||||
|
<li>Example URL: https://imgur.com/a/H8M4rcp</li>
|
||||||
|
<li>Include pattern: <code>^https?://i?.?imgur.com(/.*)?$</code></li>
|
||||||
|
<li>Redirect to: <code>{{proto}}://{{domain}}$1</code></li>
|
||||||
|
<li>Pattern type: Regular Expression</li>
|
||||||
|
<li>Advanced Options > Apply to: Check Images</li>
|
||||||
|
</ul>
|
||||||
|
<br/>
|
||||||
|
<p>For Stack Overflow Images:</p>
|
||||||
|
<ul class="list-disc ml-4">
|
||||||
|
<li>Description: Stack Overflow Imgur -> rimgo</li>
|
||||||
|
<li>Example URL: https://i.stack.imgur.com/BTKqD.png?s=128&g=1</li>
|
||||||
|
<li>Include pattern: <code>^https?://i\.stack\.imgur\.com(/.*)?$</code></li>
|
||||||
|
<li>Redirect to: <code>{{proto}}://{{domain}}/stack$1</code></li>
|
||||||
|
<li>Pattern type: Regular Expression</li>
|
||||||
|
<li>Advanced Options > Apply to: Check Images</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2 class="font-bold text-2xl my-2">Notice</h2>
|
||||||
|
<p>All images and media are from Imgur. rimgo does not allow uploads or comments. Any issues with content should be reported to Imgur.</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{{> partials/footer }}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -2,21 +2,20 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{{> 'partials/head' }}
|
<title>Not Found - rimgo</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/error.css" />
|
{{> partials/head }}
|
||||||
|
|
||||||
<title>404 Not Found - rimgo</title>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> 'partials/header' }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<h2 class="errorTitle">404 Not Found</h2>
|
<h2 class="text-2xl font-bold">Not Found</h2>
|
||||||
<p class="errorTitle">Click <a href="/">here</a> to return to home.</p>
|
<p>Click <a href="/">here</a> to return to home.</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{{> partials/footer }}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -2,21 +2,20 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{{> 'partials/head' }}
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/error.css" />
|
|
||||||
|
|
||||||
<title>Rate limited by Imgur - rimgo</title>
|
<title>Rate limited by Imgur - rimgo</title>
|
||||||
|
|
||||||
|
{{> partials/head }}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> 'partials/header' }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<h2 class="errorTitle">Rate limited by Imgur</h2>
|
<h2 class="text-2xl font-bold">Rate limited by Imgur</h2>
|
||||||
<p class="errorTitle">This instance has been temporarily blocked by Imgur. <a href="https://rimgo.codeberg.page/">Try using another instance</a>.</p>
|
<p>This instance has been temporarily blocked by Imgur. <a href="https://rimgo.codeberg.page/#{{ path }}">Try using another instance ></a></p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{{> partials/footer }}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -2,22 +2,21 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{{> 'partials/head' }}
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/error.css" />
|
|
||||||
|
|
||||||
<title>Error - rimgo</title>
|
<title>Error - rimgo</title>
|
||||||
|
|
||||||
|
{{> partials/head }}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> 'partials/header' }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<main>
|
<main class="flex flex-col">
|
||||||
<h2 class="errorTitle">An error occurred</h2>
|
<h2 class="text-2xl font-bold">An error occurred</h2>
|
||||||
<p>You may have found a bug in rimgo. If this is a bug, open an issue on <a href="https://codeberg.org/video-prize-ranch/rimgo/issues/new">Codeberg</a>.</p>
|
<p>You may have found a bug in rimgo. If this is a bug, open an issue on <a href="https://codeberg.org/video-prize-ranch/rimgo/issues/new">Codeberg</a>.</p>
|
||||||
<code>{{err}}</code>
|
<code class="mt-4 p-2 bg-slate-600 rounded-md">{{err}}</code>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{{> partials/footer }}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -5,104 +5,49 @@
|
||||||
<title>rimgo</title>
|
<title>rimgo</title>
|
||||||
|
|
||||||
{{> partials/head }}
|
{{> partials/head }}
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/frontpage.css" />
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> partials/header }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<main>
|
<header class="my-8 p-8 rounded-xl flex flex-col gap-4 items-center justify-center bg-gradient-to-r from-blue-400 to-emerald-400">
|
||||||
<p>An alternative frontend for Imgur. Originally based on <a href="https://codeberg.org/3np/rimgu" rel="noreferrer">rimgu</a>.</p>
|
<h2 class="font-bold text-white text-2xl">The fast, private image viewer for Imgur.</h2>
|
||||||
|
<!--<input class="p-2 rounded-lg bg-slate-200 text-black w-full lg:w-1/2" type="text" placeholder="Search or paste a link">-->
|
||||||
<h2>Features</h2>
|
</header>
|
||||||
<ul>
|
|
||||||
<li>Lightweight</li>
|
<main class="my-8">
|
||||||
<li>No JavaScript</li>
|
<h2 class="font-bold text-2xl">What is rimgo?</h2>
|
||||||
<li>No ads or tracking</li>
|
<p>
|
||||||
<li>No sign up or app install prompts</li>
|
rimgo is an alternative frontend for Imgur.
|
||||||
<li>Bandwidth efficient - automatically uses newer image formats (if enabled)</li>
|
Originally based on <a href="https://codeberg.org/3np/rimgu" rel="noreferrer">rimgu</a>.
|
||||||
</ul>
|
It's a way to access Imgur without the ads, tracking, and other garbage.
|
||||||
|
rimgo is not affiliated with Imgur, all content is proxied from Imgur.
|
||||||
<h2>Comparison</h2>
|
</p>
|
||||||
<p>Comparing rimgo to Imgur.</p>
|
<br/>
|
||||||
|
<h3 class="font-bold text-xl">Notice</h3>
|
||||||
<h3>Speed</h3>
|
|
||||||
<p>Tested using <a href="https://pagespeed.web.dev/" rel="nofollow noreferrer">Google PageSpeed Insights</a>.</p>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td><a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fi.bcow.xyz%2Fgallery%2FgYiQLWy" rel="nofollow noreferrer">rimgo</a></td>
|
|
||||||
<td><a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fimgur.com%2Fgallery%2FgYiQLWy" rel="nofollow noreferrer">Imgur</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Performance</td>
|
|
||||||
<td>91</td>
|
|
||||||
<td>28</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Request count</td>
|
|
||||||
<td>29</td>
|
|
||||||
<td>340</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Resource Size</td>
|
|
||||||
<td>218 KiB</td>
|
|
||||||
<td>2,542 KiB</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Time to Interactive</td>
|
|
||||||
<td>1.6s</td>
|
|
||||||
<td>23.8s</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>Privacy</h3>
|
|
||||||
<p>Imgur collects information about your device and uses tracking cookies for advertising, this is mentioned in their <a href="https://imgur.com/privacy/" rel="nofollow noreferrer">privacy policy</a>. <a href="https://themarkup.org/blacklight" rel="nofollow noreferrer">Blacklight</a> found 31 trackers and 87 third-party cookies.</p>
|
|
||||||
<p>See what cookies and trackers Imgur uses and where your data gets sent: <a href="https://themarkup.org/blacklight?url=imgur.com" rel="nofollow noreferrer">https://themarkup.org/blacklight?url=imgur.com</a></p>
|
|
||||||
|
|
||||||
<h2>Usage</h2>
|
|
||||||
<p>Just replace imgur.com or i.imgur.com with <code>{{domain}}</code> (add stack/ before the media ID for i.stack.imgur.com). You can setup automatic redirects using <a href="https://github.com/libredirect/libredirect" rel="nofollow noreferrer">LibRedirect</a> (recommended) or <a href="https://github.com/einaregilsson/Redirector" rel="nofollow noreferrer">Redirector</a>.</p>
|
|
||||||
|
|
||||||
{{#if force_webp}}
|
|
||||||
<p>To download images as their original filetype, add <code>?no_webp=1</code> to the end of the image URL.</p>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<h2>Automatically redirect links</h2>
|
|
||||||
|
|
||||||
<h3>LibRedirect</h3>
|
|
||||||
<p>Use <a href="https://github.com/libredirect/libredirect" rel="nofollow noreferrer">LibRedirect</a> to automatically redirect Imgur links to rimgo!</p>
|
|
||||||
|
|
||||||
<h3>GreaseMonkey script</h3>
|
|
||||||
<p>There is a script to redirect Imgur links to rimgo. <a rel="noreferrer" href="https://codeberg.org/zortazert/GreaseMonkey-Redirect/src/branch/main/imgur-to-rimgo.user.js">https://codeberg.org/zortazert/GreaseMonkey-Redirect/src/branch/main/imgur-to-rimgo.user.js</a></p>
|
|
||||||
|
|
||||||
<h3>Redirector</h3>
|
|
||||||
<p>You can use the <a href="https://github.com/einaregilsson/Redirector" rel="nofollow noreferrer">Redirector</a> extension to redirect Imgur links to rimgo with the configuration below:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Description: Imgur -> rimgo</li>
|
|
||||||
<li>Example URL: https://imgur.com/a/H8M4rcp</li>
|
|
||||||
<li>Include pattern: <code>^https?://i?.?imgur.com(/.*)?$</code></li>
|
|
||||||
<li>Redirect to: <code>{{proto}}://{{domain}}$1</code></li>
|
|
||||||
<li>Pattern type: Regular Expression</li>
|
|
||||||
<li>Advanced Options > Apply to: Check Images</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>For Stack Overflow Images:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Description: Stack Overflow Imgur -> rimgo</li>
|
|
||||||
<li>Example URL: https://i.stack.imgur.com/BTKqD.png?s=128&g=1</li>
|
|
||||||
<li>Include pattern: <code>^https?://i\.stack\.imgur\.com(/.*)?$</code></li>
|
|
||||||
<li>Redirect to: <code>{{proto}}://{{domain}}/stack$1</code></li>
|
|
||||||
<li>Pattern type: Regular Expression</li>
|
|
||||||
<li>Advanced Options > Apply to: Check Images</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Notice</h2>
|
|
||||||
<p>All images and media are from Imgur. rimgo does not allow uploads or comments. Any issues with content should be reported to Imgur.</p>
|
<p>All images and media are from Imgur. rimgo does not allow uploads or comments. Any issues with content should be reported to Imgur.</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<h2 class="font-bold text-2xl">This instance</h2>
|
||||||
|
<section class="my-4 lg:m-4 flex flex-col lg:flex-row gap-4 items-center">
|
||||||
|
{{> partials/privacy }}
|
||||||
|
<div class="self-start">
|
||||||
|
<h2 class="text-xl my-2 font-bold">Additional information</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Version: {{version}}</li>
|
||||||
|
<li>Country: {{config.Privacy.country}}</li>
|
||||||
|
<li>Provider: {{config.Privacy.provider}}</li>
|
||||||
|
{{#if config.Privacy.cloudflare}}
|
||||||
|
<li>Using Cloudflare?: Yes</li>
|
||||||
|
{{else}}
|
||||||
|
<li>Using Cloudflare?: No</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<p><a href="/privacy">Learn more about instance privacy ></a></p>
|
||||||
|
|
||||||
{{> partials/footer }}
|
{{> partials/footer }}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -1,30 +1,32 @@
|
||||||
<div class="comment flex flex-col">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="comment__user">
|
<div class="flex gap-2 items-center">
|
||||||
{{#noteq this.User.Username "[deleted]"}}
|
{{#noteq this.User.Username "[deleted]"}}
|
||||||
<img src="{{this.User.Avatar}}" class="pfp" width="24" height="24" loading="lazy">
|
<img src="{{this.User.Avatar}}" class="rounded-full" width="24" height="24" loading="lazy">
|
||||||
<a href="/user/{{this.User.Username}}">
|
<a href="/user/{{this.User.Username}}">
|
||||||
<p class="comment__user__username"><b>{{this.User.Username}}</b></p>
|
<p class="whitespace-nowrap text-ellipsis overflow-hidden"><b>{{this.User.Username}}</b></p>
|
||||||
</a>
|
</a>
|
||||||
{{/noteq}}
|
{{/noteq}}
|
||||||
{{#equal this.User.Username "[deleted]"}}
|
{{#equal this.User.Username "[deleted]"}}
|
||||||
<p class="comment__user__username"><b>[deleted]</b></p>
|
<p class="whitespace-nowrap text-ellipsis overflow-hidden"><b>[deleted]</b></p>
|
||||||
{{/equal}}
|
{{/equal}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>{{{this.Comment}}}</p>
|
<p>{{{this.Comment}}}</p>
|
||||||
<div>
|
<div class="flex gap-2">
|
||||||
<span title="{{this.CreatedAt}}">{{this.RelTime}}</span>
|
<span title="{{this.CreatedAt}}">{{this.RelTime}}</span>
|
||||||
{{#if this.DeletedAt}}
|
{{#if this.DeletedAt}}
|
||||||
<span class="comment__updatedDate">(deleted {{this.DeletedAt}})</span>
|
<span class="text-md">(deleted {{this.DeletedAt}})</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
|
||||||
<img class="icon" src="/static/icons/chevron-up.svg" alt="Likes"> {{this.Upvotes}}
|
<img class="invert icon" src="/static/icons/PhArrowFatUp.svg" alt="Likes" width="24px" height="24px"> {{this.Upvotes}}
|
||||||
<img class="icon" src="/static/icons/chevron-down.svg" alt="Dislikes"> {{this.Downvotes}}
|
<img class="invert icon" src="/static/icons/PhArrowFatDown.svg" alt="Dislikes" width="24px" height="24px"> {{this.Downvotes}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="replies">
|
{{#if this.Comments}}
|
||||||
|
<div class="ml-4 p-2 border-solid border-l-2 border-slate-400">
|
||||||
{{#each this.Comments}}
|
{{#each this.Comments}}
|
||||||
{{> partials/comment }}
|
{{> partials/comment }}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
|
@ -1,4 +1,14 @@
|
||||||
<footer class="flex flex-center">
|
<footer class="mt-24 mb-12">
|
||||||
<a href="/privacy">Privacy</a>
|
<div class="mb-1 flex gap-4 font-bold">
|
||||||
<a href="https://codeberg.org/video-prize-ranch/rimgo" rel="noreferrer">Source Code</a>
|
<a href="/">
|
||||||
|
<div class="flex">
|
||||||
|
<img src="/static/img/rimgo.svg" class="invert hue-rotate-180" width="32" height="32" />
|
||||||
|
<h1 class="text-md font-extrabold">rimgo</h1>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="https://codeberg.org/rimgo/rimgo">Source Code</a>
|
||||||
|
<a href="/about">About</a>
|
||||||
|
<a href="/privacy">Privacy</a>
|
||||||
|
</div>
|
||||||
|
<p class="text-md text-slate-200">rimgo does not allow uploads or host any content. Issues with content should be reported to Imgur.</p>
|
||||||
</footer>
|
</footer>
|
|
@ -12,5 +12,4 @@
|
||||||
<meta name="msapplication-config" content="/static/favicon/browserconfig.xml">
|
<meta name="msapplication-config" content="/static/favicon/browserconfig.xml">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/normalize.css"/>
|
<link rel="stylesheet" href="/static/app.css" />
|
||||||
<link rel="stylesheet" href="/static/css/base.css"/>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<nav class="flex flex-center">
|
|
||||||
<a href="/">
|
|
||||||
<img src="/static/img/rimgo.svg" width="64" height="64" class="logo" alt="Logo">
|
|
||||||
</a>
|
|
||||||
<a href="/">
|
|
||||||
<h2>rimgo</h2>
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<a href="/">
|
||||||
|
<nav class="m-4 flex items-center justify-center">
|
||||||
|
<img src="/static/img/rimgo.svg" class="invert hue-rotate-180" width="72" height="72" />
|
||||||
|
<h1 class="font-extrabold text-3xl">rimgo</h1>
|
||||||
|
</nav>
|
||||||
|
</a>
|
|
@ -1,5 +1,5 @@
|
||||||
<a href="{{Link}}">
|
<a href="{{Link}}">
|
||||||
<div class="post">
|
<div class="bg-slate-600 rounded-lg">
|
||||||
{{#equal Cover.Type "video"}}
|
{{#equal Cover.Type "video"}}
|
||||||
<video controls loop poster="/{{Cover.Id}}.webp" preload="none" width="100%" height="100%">
|
<video controls loop poster="/{{Cover.Id}}.webp" preload="none" width="100%" height="100%">
|
||||||
<source src="{{Cover.Url}}" type="video/mp4" />
|
<source src="{{Cover.Url}}" type="video/mp4" />
|
||||||
|
@ -8,18 +8,18 @@
|
||||||
{{#equal Cover.Type "image"}}
|
{{#equal Cover.Type "image"}}
|
||||||
<img src="{{Cover.Url}}" loading="lazy" width="100%" height="100%">
|
<img src="{{Cover.Url}}" loading="lazy" width="100%" height="100%">
|
||||||
{{/equal}}
|
{{/equal}}
|
||||||
<p class="post__title">{{Title}}</p>
|
<p class="m-2 text-ellipsis whitespace-nowrap overflow-hidden">{{Title}}</p>
|
||||||
<div class="flex gap-2 p-2">
|
<div class="flex gap-2 p-2">
|
||||||
<div>
|
<div class="flex gap-1">
|
||||||
<img class="icon" src="/static/icons/chevron-up.svg" alt="Points">
|
<img class="invert icon" src="/static/icons/PhArrowFatUp.svg" alt="Points" width="18px" height="18px">
|
||||||
{{Points}}
|
{{Points}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="flex gap-1">
|
||||||
<img class="icon" src="/static/icons/message-square.svg" alt="Comments">
|
<img class="invert icon" src="/static/icons/PhChat.svg" alt="Comments" width="18px" height="18px">
|
||||||
{{Comments}}
|
{{Comments}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="flex gap-1">
|
||||||
<img class="icon" src="/static/icons/eye.svg" alt="Views">
|
<img class="invert icon" src="/static/icons/PhEye.svg" alt="Views" width="18px" height="18px">
|
||||||
{{Views}}
|
{{Views}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
{{#if config.Privacy.not_collected}}
|
||||||
|
<div class="flex flex-col items-center w-full lg:w-1/2 p-4 bg-slate-600 rounded-lg">
|
||||||
|
<img class="invert" src="/static/icons/PhCheckCircle.svg" alt="" height="36" width="36" />
|
||||||
|
<h2 class="font-bold text-xl">Data not collected</h2>
|
||||||
|
<p class="text-lg">This instance does not collect any data.</p>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#unless config.Privacy.set}}
|
||||||
|
<div class="flex flex-col items-center w-full lg:w-1/2 p-4 bg-slate-600 rounded-lg">
|
||||||
|
<img class="invert" src="/static/icons/PhWarning.svg" alt="" height="36" width="36" />
|
||||||
|
<h2 class="font-bold text-xl">No details provided</h2>
|
||||||
|
<p class="text-lg">The operator of this instance will be required to provide privacy details to be added to the instance list.</p>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{#unless config.Privacy.not_collected}}
|
||||||
|
<div class="flex flex-col items-center w-full lg:w-1/2 p-4 bg-slate-600 rounded-lg">
|
||||||
|
<img class="invert" src="/static/icons/PhWarningCircle.svg" alt="" height="36" width="36" />
|
||||||
|
<h2 class="font-bold text-xl">Data collected</h2>
|
||||||
|
<p class="text-lg">The following data may be collected:</p>
|
||||||
|
<ul class="flex flex-col">
|
||||||
|
{{#if config.Privacy.ip}}
|
||||||
|
<li class="flex gap-1">
|
||||||
|
<img class="invert" src="/static/icons/PhGlobe.svg" alt="" width="24px" height="24px" />
|
||||||
|
Internet address (IP Address)
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if config.Privacy.url}}
|
||||||
|
<li class="flex gap-1">
|
||||||
|
<img class="invert" src="/static/icons/PhLink.svg" alt="" width="24px" height="24px" />
|
||||||
|
Page viewed (Request URL)
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if config.Privacy.device}}
|
||||||
|
<li class="flex gap-1">
|
||||||
|
<img class="invert" src="/static/icons/PhDevices.svg" alt="" width="24px" height="24px" />
|
||||||
|
Device Type (User agent)
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if config.Privacy.diagnostics}}
|
||||||
|
<li class="flex gap-1">
|
||||||
|
<img class="invert" src="/static/icons/PhWrench.svg" alt="" width="24px" height="24px" />
|
||||||
|
Diagnostics
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
{{/unless}}
|
|
@ -7,62 +7,58 @@
|
||||||
{{post.Title}} -
|
{{post.Title}} -
|
||||||
{{/if}}
|
{{/if}}
|
||||||
rimgo
|
rimgo
|
||||||
</title>
|
</title>
|
||||||
|
|
||||||
{{> partials/head }}
|
{{> partials/head }}
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/album.css" />
|
|
||||||
<link rel="stylesheet" href="/static/css/comments.css" />
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> partials/header }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h1>{{post.Title}}</h1>
|
<h1 class="text-3xl font-bold">{{post.Title}}</h1>
|
||||||
<p>{{post.CreatedAt}}</p>
|
<p>{{post.CreatedAt}}</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div class="flex flex-center-y gap-4">
|
<div class="flex gap-4 items-center my-4">
|
||||||
{{#if post.User.Username}}
|
{{#if post.User.Username}}
|
||||||
<a href="/user/{{post.User.Username}}" class="user">
|
<a href="/user/{{post.User.Username}}" class="flex gap-2 items-center">
|
||||||
<img src="{{post.User.Avatar}}" class="pfp" width="36" height="36" />
|
<img src="{{post.User.Avatar}}" class="rounded-full" width="36" height="36" />
|
||||||
<p>
|
<p>
|
||||||
<b>{{post.User.Username}}</b>
|
<b>{{post.User.Username}}</b>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="flex flex-center-y gap-2">
|
<div class="flex gap-2 items-center">
|
||||||
<div class="flex flex-center gap-2">
|
<div class="flex flex-center gap-2">
|
||||||
<img class="icon" src="/static/icons/eye.svg" alt="Views">
|
<img class="icon invert" src="/static/icons/PhEye.svg" alt="Views" width="24px" height="24px">
|
||||||
<p>{{post.Views}}</p>
|
<p>{{post.Views}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{#if post.SharedWithCommunity}}
|
{{#if post.SharedWithCommunity}}
|
||||||
<div class="flex flex-center gap-2">
|
<div class="flex flex-center gap-2">
|
||||||
<img class="icon" src="/static/icons/chevron-up.svg" alt="Likes">
|
<img class="icon invert" src="/static/icons/PhArrowFatUp.svg" alt="Likes" width="24px" height="24px">
|
||||||
<p>{{post.Upvotes}}</p>
|
<p>{{post.Upvotes}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-center gap-2">
|
<div class="flex flex-center gap-2">
|
||||||
<img class="icon" src="/static/icons/chevron-down.svg" alt="Dislikes">
|
<img class="icon invert" src="/static/icons/PhArrowFatDown.svg" alt="Dislikes" width="24px" height="24px">
|
||||||
<p>{{post.Downvotes}}</p>
|
<p>{{post.Downvotes}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="post__media flex flex-center flex-col">
|
<div class="flex flex-center flex-col">
|
||||||
{{#each post.Media}}
|
{{#each post.Media}}
|
||||||
{{#if this.Title}}
|
{{#if this.Title}}
|
||||||
<h4>{{this.Title}}</h4>
|
<h4 class="font-bold">{{this.Title}}</h4>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#equal this.Type "image"}}
|
{{#equal this.Type "image"}}
|
||||||
<img src="{{this.Url}}" loading="lazy">
|
<img class="my-2 max-h-96 object-contain" src="{{this.Url}}" loading="lazy">
|
||||||
{{/equal}}
|
{{/equal}}
|
||||||
{{#equal this.Type "video"}}
|
{{#equal this.Type "video"}}
|
||||||
<video controls loop>
|
<video class="my-2 max-h-96 object-contain" controls loop>
|
||||||
<source type="{{this.MimeType}}" src="{{this.Url}}" />
|
<source type="{{this.MimeType}}" src="{{this.Url}}" />
|
||||||
</video>
|
</video>
|
||||||
{{/equal}}
|
{{/equal}}
|
||||||
|
@ -74,7 +70,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if post.tags}}
|
{{#if post.tags}}
|
||||||
<div class="tags">
|
<div class="flex gap-2 my-2 flex-flow-wrap">
|
||||||
<style nonce="{{nonce}}">
|
<style nonce="{{nonce}}">
|
||||||
{{#each post.tags}}
|
{{#each post.tags}}
|
||||||
.{{this.BackgroundId}} { background-image: url('{{this.Background}}') }
|
.{{this.BackgroundId}} { background-image: url('{{this.Background}}') }
|
||||||
|
@ -82,8 +78,8 @@
|
||||||
</style>
|
</style>
|
||||||
{{#each post.tags}}
|
{{#each post.tags}}
|
||||||
<a href="/t/{{this.Tag}}">
|
<a href="/t/{{this.Tag}}">
|
||||||
<div class="tag {{this.BackgroundId}}">
|
<div class="rounded-md p-4 min-w-[110px] bg-slate-500 {{this.BackgroundId}}">
|
||||||
<p class="tag__display">{{this.Display}}</p>
|
<p class="font-bold text-white text-center">{{this.Display}}</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -94,13 +90,12 @@
|
||||||
<section>
|
<section>
|
||||||
{{#if comments}}
|
{{#if comments}}
|
||||||
<div>
|
<div>
|
||||||
<hr>
|
<input id="comments__expandBtn" type="checkbox" checked>
|
||||||
<input id="comments__expandBtn" type="checkbox">
|
<label class="comments__expandBtn__label my-2 py-4 border-solid border-t-2 border-slate-400" for="comments__expandBtn">
|
||||||
<label class="comments__expandBtn__label" for="comments__expandBtn">
|
<h3 class="text-xl font-bold">Comments ({{post.Comments}})</h3>
|
||||||
<h3>Comments ({{post.Comments}})</h3>
|
<span class="text-xl font-bold"></span>
|
||||||
<span class="comments__expandBtn__icon"></span>
|
|
||||||
</label>
|
</label>
|
||||||
<div class="comments flex flex-col">
|
<div class="comments flex flex-col gap-2">
|
||||||
{{#each comments}}
|
{{#each comments}}
|
||||||
{{> partials/comment }}
|
{{> partials/comment }}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -2,18 +2,16 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{{> 'partials/head' }}
|
<title>Privacy - rimgo</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/privacy.css">
|
{{> partials/head }}
|
||||||
|
|
||||||
<title>Instance privacy - rimgo</title>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> 'partials/header' }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<main>
|
<header>
|
||||||
<h1>Instance Privacy</h1>
|
<h1 class="text-3xl font-bold">Instance Privacy</h1>
|
||||||
{{#if config.Privacy.policy}}
|
{{#if config.Privacy.policy}}
|
||||||
<p>The instance operator has indicated their instance's privacy practices below. For more information, see the
|
<p>The instance operator has indicated their instance's privacy practices below. For more information, see the
|
||||||
instance operator's <a href="{{config.Privacy.policy}}">privacy policy</a>.</p>
|
instance operator's <a href="{{config.Privacy.policy}}">privacy policy</a>.</p>
|
||||||
|
@ -22,95 +20,42 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if config.Privacy.message}}
|
{{#if config.Privacy.message}}
|
||||||
<p>{{{config.Privacy.message}}}</p>
|
<p class="my-4">{{{config.Privacy.message}}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</header>
|
||||||
{{#if config.Privacy.not_collected}}
|
|
||||||
<div class="badge">
|
<main class="flex justify-center w-full">
|
||||||
<div class="flex flex-col flex-center p-2 gap-2">
|
{{> partials/privacy }}
|
||||||
<img class="icon largeIcon" src="/static/icons/check-circle.svg" alt="">
|
</main>
|
||||||
<h2>Data Not Collected</h2>
|
|
||||||
<p>The instance operator does not collect any data from this instance.</p>
|
<section>
|
||||||
</div>
|
<h2 class="text-2xl my-4 font-bold">What is instance privacy?</h2>
|
||||||
</div>
|
<p>Instance privacy aims to bring transparency to the data collected by frontends and encourage privacy friendly practices. There is often no privacy policy and users are forced to trust that the instance operator is not collecting data. However, there is a possibility that the instance operator can put false information so we encourage looking at other factors when selecting an instance.</p>
|
||||||
{{/if}}
|
<ul class="flex flex-col list-outside list-disc mt-2 ml-4">
|
||||||
|
<li>
|
||||||
{{#unless config.Privacy.set}}
|
<img class="inline invert" src="/static/icons/PhGlobe.svg" alt="" width="24px" height="24px" />
|
||||||
<div class="badge">
|
Internet address (IP Address) - This is an address that is given to your computer or internet connection.
|
||||||
<div class="flex flex-col flex-center p-2 gap-2">
|
This can be used to find your city or region and internet provider but can change depending on your connection.
|
||||||
<img class="icon largeIcon" src="/static/icons/alert-triangle.svg" alt="">
|
</li>
|
||||||
<h3>No Details Provided</h3>
|
<li>
|
||||||
<p>The operator of this instance will be required to provide privacy details to be added to the instance list.
|
<img class="inline invert" src="/static/icons/PhLink.svg" alt="" width="24px" height="24px" />
|
||||||
</p>
|
Page viewed (Request URL) - This is what page you are viewing.
|
||||||
</div>
|
</li>
|
||||||
</div>
|
<li>
|
||||||
{{else}}
|
<img class="inline invert" src="/static/icons/PhDevices.svg" alt="" width="24px" height="24px" />
|
||||||
{{#unless config.Privacy.not_collected}}
|
Device Type (User agent) - This is what browser, device, and operating system you are using.
|
||||||
<div class="badge">
|
Advanced users can change this with an extension or browser setting.
|
||||||
<div class="flex flex-col flex-center p-2 gap-2">
|
</li>
|
||||||
<img class="icon largeIcon" src="/static/icons/alert-circle.svg" alt="">
|
<li>
|
||||||
<h2>Data Collected</h2>
|
<img class="inline invert" src="/static/icons/PhWrench.svg" alt="" width="24px" height="24px" />
|
||||||
<p>The following data may be collected:</p>
|
Diagnostics - When this data is only collected when there is an error or only a short amount of time while
|
||||||
<ul>
|
diagnosing an issue.
|
||||||
{{#if config.Privacy.ip}}
|
</li>
|
||||||
<li>
|
</ul>
|
||||||
<img class="icon" src="/static/icons/hash.svg" alt="">
|
</section>
|
||||||
Internet address (IP Address)
|
|
||||||
</li>
|
<section>
|
||||||
{{/if}}
|
<h2 class="text-2xl my-4 font-bold">Additional information</h2>
|
||||||
{{#if config.Privacy.url}}
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/link.svg" alt="">
|
|
||||||
Page viewed (Request URL)
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
{{#if config.Privacy.device}}
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/smartphone.svg" alt="">
|
|
||||||
Device Type (User agent)
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
{{#if config.Privacy.diagnostics}}
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/tool.svg" alt="">
|
|
||||||
Diagnostics
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/unless}}
|
|
||||||
{{/unless}}
|
|
||||||
|
|
||||||
<details class="privacyDetails">
|
|
||||||
<summary>What's this?</summary>
|
|
||||||
<p>
|
|
||||||
Instance privacy aims to bring transparency to the data collected by frontends and encourage privacy friendly practices. There is often no privacy policy and users are forced to trust that the instance operator is not collecting data. However, there is a possibility that the instance operator can put false information so we encourage looking at other factors when selecting an instance.
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/hash.svg" alt="">
|
|
||||||
Internet address (IP Address) - This is an address that is given to your computer or internet connection.
|
|
||||||
This can be used to find your city or region and internet provider but can change depending on your connection.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/link.svg" alt="">
|
|
||||||
Page viewed (Request URL) - This is what page you are viewing. Searches are kept private.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/smartphone.svg" alt="">
|
|
||||||
Device Type (User agent) - This is what browser, device, and operating system you are using.
|
|
||||||
Advanced users can change this with an extension or browser setting.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<img class="icon" src="/static/icons/tool.svg" alt="">
|
|
||||||
Diagnostics - When this data is only collected when there is an error or only a short amount of time while
|
|
||||||
diagnosing an issue.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<h2 class="addInfo">Additional information</h2>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Version: {{version}}</li>
|
<li>Version: {{version}}</li>
|
||||||
<li>Country: {{config.Privacy.country}}</li>
|
<li>Country: {{config.Privacy.country}}</li>
|
||||||
|
@ -121,7 +66,7 @@
|
||||||
<li>Using Cloudflare?: No</li>
|
<li>Using Cloudflare?: No</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</ul>
|
</ul>
|
||||||
</main>
|
</section>
|
||||||
|
|
||||||
{{> 'partials/footer' }}
|
{{> 'partials/footer' }}
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -5,46 +5,43 @@
|
||||||
<title>{{tag.Display}} - rimgo</title>
|
<title>{{tag.Display}} - rimgo</title>
|
||||||
|
|
||||||
{{> partials/head }}
|
{{> partials/head }}
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/base.css" />
|
|
||||||
<link rel="stylesheet" href="/static/css/tag.css" />
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> partials/header }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
<main>
|
<header class="p-4 rounded-xl text-white mb-4" style="background-image: url('{{tag.Background}}');">
|
||||||
<div class="tagMeta" style="background-image: url('{{tag.Background}}');">
|
<div class="flex flex-col items-center justify-center text-center">
|
||||||
<div class="flex flex-center flex-col text-center">
|
<h2 class="text-2xl font-bold">{{tag.Display}}</h2>
|
||||||
<h2>{{tag.Display}}</h2>
|
<p>{{tag.PostCount}} posts</p>
|
||||||
<p>{{tag.PostCount}} posts</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
{{#equal tag.Sort "popular"}}
|
|
||||||
<a href="?sort=popular"><b>Popular</b></a>
|
|
||||||
<a href="?sort=newest">Newest</a>
|
|
||||||
<a href="?sort=best">Best</a>
|
|
||||||
{{/equal}}
|
|
||||||
{{#equal tag.Sort "newest"}}
|
|
||||||
<a href="?sort=popular">Popular</a>
|
|
||||||
<a href="?sort=newest"><b>Newest</b></a>
|
|
||||||
<a href="?sort=best">Best</a>
|
|
||||||
{{/equal}}
|
|
||||||
{{#equal tag.Sort "best"}}
|
|
||||||
<a href="?sort=popular">Popular</a>
|
|
||||||
<a href="?sort=newest">Newest</a>
|
|
||||||
<a href="?sort=best"><b>Best</b></a>
|
|
||||||
{{/equal}}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
{{#equal tag.Sort "popular"}}
|
||||||
|
<a href="?sort=popular"><b>Popular</b></a>
|
||||||
|
<a href="?sort=newest">Newest</a>
|
||||||
|
<a href="?sort=best">Best</a>
|
||||||
|
{{/equal}}
|
||||||
|
{{#equal tag.Sort "newest"}}
|
||||||
|
<a href="?sort=popular">Popular</a>
|
||||||
|
<a href="?sort=newest"><b>Newest</b></a>
|
||||||
|
<a href="?sort=best">Best</a>
|
||||||
|
{{/equal}}
|
||||||
|
{{#equal tag.Sort "best"}}
|
||||||
|
<a href="?sort=popular">Popular</a>
|
||||||
|
<a href="?sort=newest">Newest</a>
|
||||||
|
<a href="?sort=best"><b>Best</b></a>
|
||||||
|
{{/equal}}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
<div class="posts">
|
<div class="posts">
|
||||||
{{#each tag.Posts}}
|
{{#each tag.Posts}}
|
||||||
{{> partials/post }}
|
{{> partials/post }}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pageSelector">
|
<div class="mt-4 font-bold">
|
||||||
{{#if displayPrev}}
|
{{#if displayPrev}}
|
||||||
<a href="{{channel.RelUrl}}?page={{prevPage}}">Previous page</a>
|
<a href="{{channel.RelUrl}}?page={{prevPage}}">Previous page</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -5,33 +5,30 @@
|
||||||
<title>{{user.Username}} - rimgo</title>
|
<title>{{user.Username}} - rimgo</title>
|
||||||
|
|
||||||
{{> partials/head }}
|
{{> partials/head }}
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/user.css" />
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="font-sans text-lg bg-slate-800 text-white">
|
||||||
{{> partials/header }}
|
{{> partials/nav }}
|
||||||
|
|
||||||
|
<header class="p-4 rounded-xl text-white mb-4" style="background-image: url('{{user.Cover}}');">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<img class="rounded-full" src="{{user.Avatar}}" width="72" height="72">
|
||||||
|
<div>
|
||||||
|
<h2 class="font-bold text-2xl">{{user.Username}}</h2>
|
||||||
|
<p>{{user.Points}} pts · {{user.CreatedAt}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2">{{user.Bio}}</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div class="userMeta" style="background-image: url('{{user.Cover}}');">
|
|
||||||
<div class="flex flex-center-y gap-2">
|
|
||||||
<img class="pfp" src="{{user.Avatar}}" width="72" height="72">
|
|
||||||
<div>
|
|
||||||
<h2>{{user.Username}}</h2>
|
|
||||||
<p>{{user.Points}} pts · {{user.CreatedAt}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p>{{user.Bio}}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="posts">
|
<div class="posts">
|
||||||
{{#each submissions}}
|
{{#each submissions}}
|
||||||
{{> partials/post }}
|
{{> partials/post }}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pageSelector">
|
<div class="mt-4 font-bold">
|
||||||
{{#equal page "0" }}
|
{{#equal page "0" }}
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="{{channel.RelUrl}}?page={{prevPage}}">Previous page</a>
|
<a href="{{channel.RelUrl}}?page={{prevPage}}">Previous page</a>
|
||||||
|
|