fix language/safe search gui
This commit is contained in:
parent
8fece91f75
commit
6b3373f7d6
13 changed files with 748 additions and 694 deletions
44
files.go
44
files.go
|
@ -59,27 +59,31 @@ func handleFileSearch(w http.ResponseWriter, settings UserSettings, query string
|
||||||
}
|
}
|
||||||
|
|
||||||
data := struct {
|
data := struct {
|
||||||
Results []TorrentResult
|
Results []TorrentResult
|
||||||
Query string
|
Query string
|
||||||
Fetched string
|
Fetched string
|
||||||
Category string
|
Category string
|
||||||
Sort string
|
Sort string
|
||||||
HasPrevPage bool
|
Page int
|
||||||
HasNextPage bool
|
HasPrevPage bool
|
||||||
Page int
|
HasNextPage bool
|
||||||
Settings Settings
|
LanguageOptions []LanguageOption
|
||||||
Theme string
|
CurrentLang string
|
||||||
|
Theme string
|
||||||
|
Safe string
|
||||||
}{
|
}{
|
||||||
Results: combinedResults,
|
Results: combinedResults,
|
||||||
Query: query,
|
Query: query,
|
||||||
Fetched: fmt.Sprintf("%.2f", elapsedTime.Seconds()),
|
Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()),
|
||||||
Category: "all",
|
Category: "all",
|
||||||
Sort: "seed",
|
Sort: "seed",
|
||||||
HasPrevPage: page > 1,
|
Page: page,
|
||||||
HasNextPage: len(combinedResults) > 0,
|
HasPrevPage: page > 1,
|
||||||
Page: page,
|
HasNextPage: len(combinedResults) > 0,
|
||||||
Settings: Settings{UxLang: settings.Language, Safe: settings.SafeSearch}, // Now this is painful, are there two Settings variables??
|
LanguageOptions: languageOptions,
|
||||||
Theme: settings.Theme,
|
CurrentLang: settings.Language,
|
||||||
|
Theme: settings.Theme,
|
||||||
|
Safe: settings.SafeSearch,
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Debugging: Print results before rendering template
|
// // Debugging: Print results before rendering template
|
||||||
|
|
10
forums.go
10
forums.go
|
@ -108,21 +108,23 @@ func handleForumsSearch(w http.ResponseWriter, settings UserSettings, query stri
|
||||||
data := struct {
|
data := struct {
|
||||||
Query string
|
Query string
|
||||||
Results []ForumSearchResult
|
Results []ForumSearchResult
|
||||||
LanguageOptions []LanguageOption
|
|
||||||
CurrentLang string
|
|
||||||
Page int
|
Page int
|
||||||
HasPrevPage bool
|
HasPrevPage bool
|
||||||
HasNextPage bool
|
HasNextPage bool
|
||||||
|
LanguageOptions []LanguageOption
|
||||||
|
CurrentLang string
|
||||||
Theme string
|
Theme string
|
||||||
|
Safe string
|
||||||
}{
|
}{
|
||||||
Query: query,
|
Query: query,
|
||||||
Results: results,
|
Results: results,
|
||||||
LanguageOptions: languageOptions,
|
|
||||||
CurrentLang: settings.Language,
|
|
||||||
Page: page,
|
Page: page,
|
||||||
HasPrevPage: page > 1,
|
HasPrevPage: page > 1,
|
||||||
HasNextPage: len(results) == 25,
|
HasNextPage: len(results) == 25,
|
||||||
|
LanguageOptions: languageOptions,
|
||||||
|
CurrentLang: settings.Language,
|
||||||
Theme: settings.Theme,
|
Theme: settings.Theme,
|
||||||
|
Safe: settings.SafeSearch,
|
||||||
}
|
}
|
||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
|
|
10
images.go
10
images.go
|
@ -37,23 +37,25 @@ func handleImageSearch(w http.ResponseWriter, settings UserSettings, query strin
|
||||||
Query string
|
Query string
|
||||||
Page int
|
Page int
|
||||||
Fetched string
|
Fetched string
|
||||||
LanguageOptions []LanguageOption
|
|
||||||
CurrentLang string
|
|
||||||
HasPrevPage bool
|
HasPrevPage bool
|
||||||
HasNextPage bool
|
HasNextPage bool
|
||||||
NoResults bool
|
NoResults bool
|
||||||
|
LanguageOptions []LanguageOption
|
||||||
|
CurrentLang string
|
||||||
Theme string
|
Theme string
|
||||||
|
Safe string
|
||||||
}{
|
}{
|
||||||
Results: combinedResults,
|
Results: combinedResults,
|
||||||
Query: query,
|
Query: query,
|
||||||
Page: page,
|
Page: page,
|
||||||
Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()),
|
Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()),
|
||||||
LanguageOptions: languageOptions,
|
|
||||||
CurrentLang: settings.Language,
|
|
||||||
HasPrevPage: page > 1,
|
HasPrevPage: page > 1,
|
||||||
HasNextPage: len(combinedResults) >= 50,
|
HasNextPage: len(combinedResults) >= 50,
|
||||||
NoResults: len(combinedResults) == 0,
|
NoResults: len(combinedResults) == 0,
|
||||||
|
LanguageOptions: languageOptions,
|
||||||
|
CurrentLang: settings.Language,
|
||||||
Theme: settings.Theme,
|
Theme: settings.Theme,
|
||||||
|
Safe: settings.SafeSearch,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tmpl.Execute(w, data)
|
err = tmpl.Execute(w, data)
|
||||||
|
|
14
main.go
14
main.go
|
@ -92,9 +92,21 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the search page template if no query
|
// Render the search page template if no query
|
||||||
|
|
||||||
|
data := struct {
|
||||||
|
LanguageOptions []LanguageOption
|
||||||
|
CurrentLang string
|
||||||
|
Theme string
|
||||||
|
Safe string
|
||||||
|
}{
|
||||||
|
LanguageOptions: languageOptions,
|
||||||
|
CurrentLang: settings.Language,
|
||||||
|
Theme: settings.Theme,
|
||||||
|
Safe: settings.SafeSearch,
|
||||||
|
}
|
||||||
if query == "" {
|
if query == "" {
|
||||||
tmpl := template.Must(template.ParseFiles("templates/search.html"))
|
tmpl := template.Must(template.ParseFiles("templates/search.html"))
|
||||||
tmpl.Execute(w, settings)
|
tmpl.Execute(w, data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
map.go
1
map.go
|
@ -59,6 +59,7 @@ func handleMapSearch(w http.ResponseWriter, settings UserSettings, query string)
|
||||||
"Longitude": longitude,
|
"Longitude": longitude,
|
||||||
"Found": found,
|
"Found": found,
|
||||||
"Theme": settings.Theme,
|
"Theme": settings.Theme,
|
||||||
|
"Safe": settings.SafeSearch,
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles("templates/map.html")
|
tmpl, err := template.ParseFiles("templates/map.html")
|
||||||
|
|
226
templates/files.html
Normal file → Executable file
226
templates/files.html
Normal file → Executable file
|
@ -1,113 +1,113 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{.Query}} - Ocásek</title>
|
<title>{{.Query}} - Ocásek</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
||||||
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
||||||
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="file">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="file">search</button>
|
||||||
<input type="submit" class="hide" name="t" value="file" />
|
<input type="submit" class="hide" name="t" value="file" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
||||||
<button name="t" value="text" class="clickable">Web</button>
|
<button name="t" value="text" class="clickable">Web</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
||||||
<button name="t" value="image" class="clickable">Images</button>
|
<button name="t" value="image" class="clickable">Images</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
||||||
<button name="t" value="video" class="clickable">Videos</button>
|
<button name="t" value="video" class="clickable">Videos</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
||||||
<button name="t" value="forum" class="clickable">Forums</button>
|
<button name="t" value="forum" class="clickable">Forums</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="content" class="js-enabled">
|
<div id="content" class="js-enabled">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
||||||
<button name="t" value="map" class="clickable">Maps</button>
|
<button name="t" value="map" class="clickable">Maps</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="file">share</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="file">share</button>
|
||||||
<button name="t" value="file" class="clickable search-active">Torrents</button>
|
<button name="t" value="file" class="clickable search-active">Torrents</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p class="fetched fetched_dif fetched_tor">Fetched in {{ .Fetched }} seconds</p>
|
<p class="fetched fetched_dif fetched_tor">Fetched in {{ .Fetched }} seconds</p>
|
||||||
|
|
||||||
{{ if .Results }}
|
{{ if .Results }}
|
||||||
<form action="/search" class="torrent-sort" method="GET">
|
<form action="/search" class="torrent-sort" method="GET">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<input type="hidden" name="t" value="file">
|
<input type="hidden" name="t" value="file">
|
||||||
<select class="torrent-settings" name="sort">
|
<select class="torrent-settings" name="sort">
|
||||||
<option value="seed" {{ if eq .Sort "seed" }} selected {{ end }}>Number of Seeders</option>
|
<option value="seed" {{ if eq .Sort "seed" }} selected {{ end }}>Number of Seeders</option>
|
||||||
<option value="leech" {{ if eq .Sort "leech" }} selected {{ end }}>Number of Leechers</option>
|
<option value="leech" {{ if eq .Sort "leech" }} selected {{ end }}>Number of Leechers</option>
|
||||||
<option value="lth" {{ if eq .Sort "lth" }} selected {{ end }}>Size (Low to High)</option>
|
<option value="lth" {{ if eq .Sort "lth" }} selected {{ end }}>Size (Low to High)</option>
|
||||||
<option value="htl" {{ if eq .Sort "htl" }} selected {{ end }}>Size (High to Low)</option>
|
<option value="htl" {{ if eq .Sort "htl" }} selected {{ end }}>Size (High to Low)</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="torrent-cat" name="cat">
|
<select class="torrent-cat" name="cat">
|
||||||
<option value="all" {{ if eq .Category "all" }} selected {{ end }}>All Categories</option>
|
<option value="all" {{ if eq .Category "all" }} selected {{ end }}>All Categories</option>
|
||||||
<option value="movie" {{ if eq .Category "movie" }} selected {{ end }}>Movies</option>
|
<option value="movie" {{ if eq .Category "movie" }} selected {{ end }}>Movies</option>
|
||||||
<option value="audiobook" {{ if eq .Category "audiobook" }} selected {{ end }}>Audiobooks</option>
|
<option value="audiobook" {{ if eq .Category "audiobook" }} selected {{ end }}>Audiobooks</option>
|
||||||
<option value="tv" {{ if eq .Category "tv" }} selected {{ end }}>TV Shows</option>
|
<option value="tv" {{ if eq .Category "tv" }} selected {{ end }}>TV Shows</option>
|
||||||
<option value="games" {{ if eq .Category "games" }} selected {{ end }}>Games</option>
|
<option value="games" {{ if eq .Category "games" }} selected {{ end }}>Games</option>
|
||||||
<option value="software" {{ if eq .Category "software" }} selected {{ end }}>Software</option>
|
<option value="software" {{ if eq .Category "software" }} selected {{ end }}>Software</option>
|
||||||
<option value="anime" {{ if eq .Category "anime" }} selected {{ end }}>Anime</option>
|
<option value="anime" {{ if eq .Category "anime" }} selected {{ end }}>Anime</option>
|
||||||
<option value="music" {{ if eq .Category "music" }} selected {{ end }}>Music</option>
|
<option value="music" {{ if eq .Category "music" }} selected {{ end }}>Music</option>
|
||||||
{{ if eq .Settings.Safe "inactive" }}
|
{{ if eq .Safe "disabled" }}
|
||||||
<option value="xxx" {{ if eq .Category "xxx" }} selected {{ end }}>XXX (18+)</option>
|
<option value="xxx" {{ if eq .Category "xxx" }} selected {{ end }}>XXX (18+)</option>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" class="torrent-sort-save">Apply settings</button>
|
<button type="submit" class="torrent-sort-save">Apply settings</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="clean">
|
<div class="clean">
|
||||||
{{ range .Results }}
|
{{ range .Results }}
|
||||||
<div class="results" id="results">
|
<div class="results" id="results">
|
||||||
{{ if .Error }}
|
{{ if .Error }}
|
||||||
<div class="error">{{ .Error }}</div>
|
<div class="error">{{ .Error }}</div>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<a id="link" href="{{ .URL }}">{{ .URL }}</a>
|
<a id="link" href="{{ .URL }}">{{ .URL }}</a>
|
||||||
<a class="torrent" href="magnet:{{ .Magnet }}"><h3>{{ .Title }}</h3></a>
|
<a class="torrent" href="magnet:{{ .Magnet }}"><h3>{{ .Title }}</h3></a>
|
||||||
<p class="stats">{{ if .Views }}{{ .Views }} views • {{ end }}{{ .Size }}</p>
|
<p class="stats">{{ if .Views }}{{ .Views }} views • {{ end }}{{ .Size }}</p>
|
||||||
<p class="publish__info"> Seeders: <span class="seeders">{{ .Seeders }}</span> | Leechers: <span class="leechers">{{ .Leechers }}</span></p>
|
<p class="publish__info"> Seeders: <span class="seeders">{{ .Seeders }}</span> | Leechers: <span class="leechers">{{ .Leechers }}</span></p>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<div class="prev-next prev-img">
|
<div class="prev-next prev-img">
|
||||||
<form action="/search" method="get">
|
<form action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<input type="hidden" name="t" value="file">
|
<input type="hidden" name="t" value="file">
|
||||||
{{ if .HasPrevPage }}
|
{{ if .HasPrevPage }}
|
||||||
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if .HasNextPage }}
|
{{ if .HasNextPage }}
|
||||||
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<div class="no-results-found">
|
<div class="no-results-found">
|
||||||
Your search '{{ .Query }}' came back with no results.<br>
|
Your search '{{ .Query }}' came back with no results.<br>
|
||||||
Try rephrasing your search term and/or recorrect any spelling mistakes.
|
Try rephrasing your search term and/or recorrect any spelling mistakes.
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
184
templates/forums.html
Normal file → Executable file
184
templates/forums.html
Normal file → Executable file
|
@ -1,92 +1,92 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{.Query}} - Ocásek</title>
|
<title>{{.Query}} - Ocásek</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
||||||
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
||||||
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="forum">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="forum">search</button>
|
||||||
<input type="submit" class="hide" name="t" value="forum" />
|
<input type="submit" class="hide" name="t" value="forum" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
||||||
<button name="t" value="text" class="clickable">Web</button>
|
<button name="t" value="text" class="clickable">Web</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
||||||
<button name="t" value="image" class="clickable">Images</button>
|
<button name="t" value="image" class="clickable">Images</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
||||||
<button name="t" value="video" class="clickable">Videos</button>
|
<button name="t" value="video" class="clickable">Videos</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="forum">forum</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="forum">forum</button>
|
||||||
<button name="t" value="forum" class="clickable search-active">Forums</button>
|
<button name="t" value="forum" class="clickable search-active">Forums</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="content" class="js-enabled">
|
<div id="content" class="js-enabled">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
||||||
<button name="t" value="map" class="clickable">Maps</button>
|
<button name="t" value="map" class="clickable">Maps</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
||||||
<button name="t" value="file" class="clickable">Torrents</button>
|
<button name="t" value="file" class="clickable">Torrents</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form class="results_settings" action="/search" method="get">
|
<form class="results_settings" action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<select class="results-settings" name="safe" id="safeSearchSelect">
|
<select class="results-settings" name="safe" id="safeSearchSelect">
|
||||||
<option value="">Safe Search Off</option>
|
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>Safe Search Off</option>
|
||||||
<option value="active">Safe Search On</option>
|
<option value="active" {{if eq .Safe "active"}}selected{{end}}>Safe Search On</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="results-settings" name="lang" id="languageSelect">
|
<select class="results-settings" name="lang" id="languageSelect">
|
||||||
{{range .LanguageOptions}}
|
{{range .LanguageOptions}}
|
||||||
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
<button class="results-save" name="t" value="text">Apply settings</button>
|
<button class="results-save" name="t" value="text">Apply settings</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="results">
|
<div class="results">
|
||||||
{{if .Results}}
|
{{if .Results}}
|
||||||
{{range .Results}}
|
{{range .Results}}
|
||||||
<div class="result_item">
|
<div class="result_item">
|
||||||
<a id="link" href="{{.URL}}">{{.URL}}</a>
|
<a id="link" href="{{.URL}}">{{.URL}}</a>
|
||||||
<a href="{{.URL}}"><h3>{{.Header}}</h3></a>
|
<a href="{{.URL}}"><h3>{{.Header}}</h3></a>
|
||||||
<p>{{.Description}}</p>
|
<p>{{.Description}}</p>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="no-results">No results found for '{{ .Query }}'. Try different keywords.</div>
|
<div class="no-results">No results found for '{{ .Query }}'. Try different keywords.</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="prev-next prev-img">
|
<div class="prev-next prev-img">
|
||||||
<form action="/search" method="get">
|
<form action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<input type="hidden" name="t" value="text">
|
<input type="hidden" name="t" value="text">
|
||||||
{{ if .HasPrevPage }}
|
{{ if .HasPrevPage }}
|
||||||
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if .HasNextPage }}
|
{{ if .HasNextPage }}
|
||||||
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
338
templates/images.html
Normal file → Executable file
338
templates/images.html
Normal file → Executable file
|
@ -1,169 +1,169 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{.Query}} - Ocásek</title>
|
<title>{{.Query}} - Ocásek</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
||||||
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
||||||
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="image">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="image">search</button>
|
||||||
<input type="submit" class="hide" name="t" value="image" />
|
<input type="submit" class="hide" name="t" value="image" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
|
||||||
<button name="t" value="text" class="clickable">Web</button>
|
<button name="t" value="text" class="clickable">Web</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="image">image</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="image">image</button>
|
||||||
<button name="t" value="image" class="clickable search-active">Images</button>
|
<button name="t" value="image" class="clickable search-active">Images</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
||||||
<button name="t" value="video" class="clickable">Videos</button>
|
<button name="t" value="video" class="clickable">Videos</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
||||||
<button name="t" value="forum" class="clickable">Forums</button>
|
<button name="t" value="forum" class="clickable">Forums</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="content" class="js-enabled">
|
<div id="content" class="js-enabled">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
||||||
<button name="t" value="map" class="clickable">Maps</button>
|
<button name="t" value="map" class="clickable">Maps</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
||||||
<button name="t" value="file" class="clickable">Torrents</button>
|
<button name="t" value="file" class="clickable">Torrents</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form class="results_settings" action="/search" method="get">
|
<form class="results_settings" action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<select class="results-settings" name="safe" id="safeSearchSelect">
|
<select class="results-settings" name="safe" id="safeSearchSelect">
|
||||||
<option value="">Safe Search Off</option>
|
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>Safe Search Off</option>
|
||||||
<option value="active">Safe Search On</option>
|
<option value="active" {{if eq .Safe "active"}}selected{{end}}>Safe Search On</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="results-settings" name="lang" id="languageSelect">
|
<select class="results-settings" name="lang" id="languageSelect">
|
||||||
{{range .LanguageOptions}}
|
{{range .LanguageOptions}}
|
||||||
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
<button class="results-save" name="t" value="image">Apply settings</button>
|
<button class="results-save" name="t" value="image">Apply settings</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="search-results" id="results">
|
<div class="search-results" id="results">
|
||||||
<!-- Results go here -->
|
<!-- Results go here -->
|
||||||
{{ if .Results }}
|
{{ if .Results }}
|
||||||
<div class="images images_viewer_hidden">
|
<div class="images images_viewer_hidden">
|
||||||
<!-- Images Grid -->
|
<!-- Images Grid -->
|
||||||
{{ range .Results }}
|
{{ range .Results }}
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<a class="clickable" href="{{ .ThumbProxy }}" target="_blank">
|
<a class="clickable" href="{{ .ThumbProxy }}" target="_blank">
|
||||||
<img src="{{ .ThumbProxy }}" alt="{{ .Title }}" data-media="{{ .Media }}">
|
<img src="{{ .ThumbProxy }}" alt="{{ .Title }}" data-media="{{ .Media }}">
|
||||||
<div class="resolution">{{ .Width }} × {{ .Height }}</div>
|
<div class="resolution">{{ .Width }} × {{ .Height }}</div>
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<div class="img_title">{{ .Title }}</div>
|
<div class="img_title">{{ .Title }}</div>
|
||||||
<div class="img_source"><a href="{{ .Source }}" target="_blank">Source</a></div>
|
<div class="img_source"><a href="{{ .Source }}" target="_blank">Source</a></div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<noscript>
|
<noscript>
|
||||||
<div class="prev-next prev-img">
|
<div class="prev-next prev-img">
|
||||||
<form action="/search" method="get">
|
<form action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<input type="hidden" name="t" value="image">
|
<input type="hidden" name="t" value="image">
|
||||||
{{ if .HasPrevPage }}
|
{{ if .HasPrevPage }}
|
||||||
<!-- Subtract 1 from the current page for the Previous button -->
|
<!-- Subtract 1 from the current page for the Previous button -->
|
||||||
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if .HasNextPage }}
|
{{ if .HasNextPage }}
|
||||||
<!-- Add 1 to the current page for the Next button -->
|
<!-- Add 1 to the current page for the Next button -->
|
||||||
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
{{ else if .NoResults }}
|
{{ else if .NoResults }}
|
||||||
<div class="no-results">No results found for '{{ .Query }}'. Try different keywords.</div>
|
<div class="no-results">No results found for '{{ .Query }}'. Try different keywords.</div>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<div class="no-more-results">Looks like this is the end of results.</div>
|
<div class="no-more-results">Looks like this is the end of results.</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<div class="message-bottom-left" id="message-bottom-left">
|
<div class="message-bottom-left" id="message-bottom-left">
|
||||||
<span>Searching for new results...</span>
|
<span>Searching for new results...</span>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
let page = {{ .Page }};
|
let page = {{ .Page }};
|
||||||
const query = "{{ .Query }}";
|
const query = "{{ .Query }}";
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let hasMoreResults = true;
|
let hasMoreResults = true;
|
||||||
const loadingIndicator = document.getElementById('message-bottom-left');
|
const loadingIndicator = document.getElementById('message-bottom-left');
|
||||||
let loadingTimeout;
|
let loadingTimeout;
|
||||||
|
|
||||||
function loadResults(newPage) {
|
function loadResults(newPage) {
|
||||||
if (loading || !hasMoreResults) return;
|
if (loading || !hasMoreResults) return;
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
// Show loading indicator if taking more than 100ms
|
// Show loading indicator if taking more than 100ms
|
||||||
loadingTimeout = setTimeout(() => {
|
loadingTimeout = setTimeout(() => {
|
||||||
loadingIndicator.style.display = 'flex';
|
loadingIndicator.style.display = 'flex';
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
fetch(`/search?q=${encodeURIComponent(query)}&t=image&p=${newPage}`)
|
fetch(`/search?q=${encodeURIComponent(query)}&t=image&p=${newPage}`)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Network response was not ok');
|
throw new Error('Network response was not ok');
|
||||||
}
|
}
|
||||||
return response.text();
|
return response.text();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
clearTimeout(loadingTimeout);
|
clearTimeout(loadingTimeout);
|
||||||
loadingIndicator.style.display = 'none';
|
loadingIndicator.style.display = 'none';
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const doc = parser.parseFromString(data, 'text/html');
|
const doc = parser.parseFromString(data, 'text/html');
|
||||||
const newResults = doc.getElementById('results').innerHTML;
|
const newResults = doc.getElementById('results').innerHTML;
|
||||||
const noResultsMessage = "No results found for '{{ .Query }}'. Try different keywords.";
|
const noResultsMessage = "No results found for '{{ .Query }}'. Try different keywords.";
|
||||||
const endOfResultsMessage = "Looks like this is the end of results.";
|
const endOfResultsMessage = "Looks like this is the end of results.";
|
||||||
const serverError = "Internal Server Error";
|
const serverError = "Internal Server Error";
|
||||||
|
|
||||||
if (newResults.includes(noResultsMessage) || newResults.includes(endOfResultsMessage) || newResults.includes(serverError)) {
|
if (newResults.includes(noResultsMessage) || newResults.includes(endOfResultsMessage) || newResults.includes(serverError)) {
|
||||||
document.getElementById('results').innerHTML += newResults;
|
document.getElementById('results').innerHTML += newResults;
|
||||||
hasMoreResults = false;
|
hasMoreResults = false;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('results').innerHTML += newResults;
|
document.getElementById('results').innerHTML += newResults;
|
||||||
page = newPage;
|
page = newPage;
|
||||||
}
|
}
|
||||||
loading = false;
|
loading = false;
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
clearTimeout(loadingTimeout);
|
clearTimeout(loadingTimeout);
|
||||||
loadingIndicator.style.display = 'none';
|
loadingIndicator.style.display = 'none';
|
||||||
console.error('Error loading results:', error);
|
console.error('Error loading results:', error);
|
||||||
hasMoreResults = false; // Stop further attempts
|
hasMoreResults = false; // Stop further attempts
|
||||||
loading = false;
|
loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('scroll', () => {
|
window.addEventListener('scroll', () => {
|
||||||
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
||||||
loadResults(page + 1);
|
loadResults(page + 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
168
templates/search.html
Normal file → Executable file
168
templates/search.html
Normal file → Executable file
|
@ -1,73 +1,95 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Search with Ocásek</title>
|
<title>Search with Ocásek</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
||||||
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const settingsIcon = document.querySelector('.settings-icon-link-search');
|
// Define the updateSettings function first
|
||||||
const searchMenu = document.querySelector('.search-menu');
|
function updateSettings(settingKey, settingValue) {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
settingsIcon.addEventListener('click', function () {
|
xhr.open('POST', '/updateSettings', true);
|
||||||
searchMenu.classList.toggle('settings-menu-hidden');
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
searchMenu.classList.toggle('settings-menu-visible');
|
xhr.onload = function () {
|
||||||
});
|
if (this.status >= 200 && this.status < 300) {
|
||||||
|
console.log('Settings updated successfully!');
|
||||||
// Theme change event listeners
|
} else {
|
||||||
document.getElementById('dark_theme').addEventListener('click', function () {
|
console.log('Failed to update settings.');
|
||||||
window.location.href = '/search?theme=dark';
|
}
|
||||||
});
|
};
|
||||||
document.getElementById('light_theme').addEventListener('click', function () {
|
xhr.send(encodeURI(settingKey + '=' + settingValue));
|
||||||
window.location.href = '/search?theme=light';
|
}
|
||||||
});
|
|
||||||
});
|
const settingsIcon = document.querySelector('.settings-icon-link-search');
|
||||||
</script>
|
const searchMenu = document.querySelector('.search-menu');
|
||||||
<div class="settings-search-div settings-search-div-search">
|
|
||||||
<button class="material-icons-round clickable settings-icon-link settings-icon-link-search">menu</button>
|
settingsIcon.addEventListener('click', function () {
|
||||||
</div>
|
searchMenu.classList.toggle('settings-menu-hidden');
|
||||||
<div class="search-menu settings-menu-hidden">
|
searchMenu.classList.toggle('settings-menu-visible');
|
||||||
<h2>Settings</h2>
|
});
|
||||||
<div class="settings-content">
|
|
||||||
<button id="settingsButton" onclick="window.location.href='/settings'">All settings</button> <!-- Well its unessesary to use js here but this menu will not work without js anyway -->
|
// Theme change event listeners
|
||||||
<div class="theme-settings">
|
document.getElementById('dark_theme').addEventListener('click', function () {
|
||||||
<p><span class="highlight">Theme: </span> <span id="theme_name">Default Theme</span></p>
|
window.location.href = '/search?theme=dark';
|
||||||
<div class="themes-settings-menu">
|
});
|
||||||
<div><img class="view-image-search clickable" id="dark_theme" alt="Dark Theme" src="/static/images/dark.webp"></div>
|
document.getElementById('light_theme').addEventListener('click', function () {
|
||||||
<div><img class="view-image-search clickable" id="light_theme" alt="Light Theme" src="/static/images/light.webp"></div>
|
window.location.href = '/search?theme=light';
|
||||||
</div>
|
});
|
||||||
</div>
|
|
||||||
<select class="lang" name="lang">
|
// Event listener for Safe Search Selection
|
||||||
<option value="en" selected>English</option>
|
document.getElementById('safeSearchSelect').addEventListener('change', function () {
|
||||||
<option value="fr">Français</option>
|
updateSettings('safe', this.value);
|
||||||
<option value="es">Español</option>
|
});
|
||||||
<!-- Add other languages as needed -->
|
|
||||||
</select>
|
// Event listener for Language Selection
|
||||||
<select class="domain" name="safe">
|
document.getElementById('languageSelect').addEventListener('change', function () {
|
||||||
<option value="active" selected>Safe search on</option>
|
updateSettings('lang', this.value);
|
||||||
<option value="">Safe search off</option>
|
});
|
||||||
<!-- Add other domains as needed -->
|
});
|
||||||
</select>
|
</script>
|
||||||
|
<div class="settings-search-div settings-search-div-search">
|
||||||
</div>
|
<button class="material-icons-round clickable settings-icon-link settings-icon-link-search">menu</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="/search" class="search-container" method="post" autocomplete="off">
|
<div class="search-menu settings-menu-hidden">
|
||||||
<h1>Ocásek</h1>
|
<h2>Settings</h2>
|
||||||
<div class="wrapper">
|
<div class="settings-content">
|
||||||
<input type="text" name="q" autofocus id="search-input" placeholder="Type to search..." />
|
<!-- <button id="settingsButton" onclick="window.location.href='/settings'">All settings</button> Well its unessesary to use js here but this menu will not work without js anyway -->
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text" type="submit">search</button>
|
<div class="theme-settings">
|
||||||
<!-- <a id="clearSearch" class="material-icons-round">close</a> -->
|
<p><span class="highlight">Current theme: </span> <span id="theme_name">{{.Theme}}</span></p>
|
||||||
</div>
|
<div class="themes-settings-menu">
|
||||||
<div class="search-button-wrapper">
|
<div><img class="view-image-search clickable" id="dark_theme" alt="Dark Theme" src="/static/images/dark.webp"></div>
|
||||||
<input type="hidden" name="p" value="1">
|
<div><img class="view-image-search clickable" id="light_theme" alt="Light Theme" src="/static/images/light.webp"></div>
|
||||||
<button name="t" value="text" type="submit">Search Text</button>
|
</div>
|
||||||
<button name="t" value="image" type="submit">Search Images</button>
|
</div>
|
||||||
</div>
|
<select class="lang" name="safe" id="safeSearchSelect">
|
||||||
</form>
|
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>Safe Search Off</option>
|
||||||
</body>
|
<option value="active" {{if eq .Safe "active"}}selected{{end}}>Safe Search On</option>
|
||||||
</html>
|
</select>
|
||||||
|
<select class="lang" name="lang" id="languageSelect">
|
||||||
|
{{range .LanguageOptions}}
|
||||||
|
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form action="/search" class="search-container" method="post" autocomplete="off">
|
||||||
|
<h1>Ocásek</h1>
|
||||||
|
<div class="wrapper">
|
||||||
|
<input type="text" name="q" autofocus id="search-input" placeholder="Type to search..." />
|
||||||
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text" type="submit">search</button>
|
||||||
|
<!-- <a id="clearSearch" class="material-icons-round">close</a> -->
|
||||||
|
</div>
|
||||||
|
<div class="search-button-wrapper">
|
||||||
|
<input type="hidden" name="p" value="1">
|
||||||
|
<button name="t" value="text" type="submit">Search Text</button>
|
||||||
|
<button name="t" value="image" type="submit">Search Images</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
306
templates/text.html
Normal file → Executable file
306
templates/text.html
Normal file → Executable file
|
@ -1,153 +1,153 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{.Query}} - Ocásek</title>
|
<title>{{.Query}} - Ocásek</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
||||||
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
|
||||||
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
|
||||||
<div class="wrapper-results">
|
<div class="wrapper-results">
|
||||||
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
<input type="text" name="q" value="{{ .Query }}" id="search-input" placeholder="Type to search..." />
|
||||||
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text">search</button>
|
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text">search</button>
|
||||||
<input type="submit" class="hide" name="t" value="text" />
|
<input type="submit" class="hide" name="t" value="text" />
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-search-button-wrapper">
|
<div class="sub-search-button-wrapper">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="text">search</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable search-active" name="t" value="text">search</button>
|
||||||
<button name="t" value="text" class="clickable search-active">Web</button>
|
<button name="t" value="text" class="clickable search-active">Web</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
|
||||||
<button name="t" value="image" class="clickable">Images</button>
|
<button name="t" value="image" class="clickable">Images</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
|
||||||
<button name="t" value="video" class="clickable">Videos</button>
|
<button name="t" value="video" class="clickable">Videos</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
|
||||||
<button name="t" value="forum" class="clickable">Forums</button>
|
<button name="t" value="forum" class="clickable">Forums</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="content" class="js-enabled">
|
<div id="content" class="js-enabled">
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
|
||||||
<button name="t" value="map" class="clickable">Maps</button>
|
<button name="t" value="map" class="clickable">Maps</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-container-results-btn">
|
<div class="search-container-results-btn">
|
||||||
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="file">share</button>
|
||||||
<button name="t" value="file" class="clickable">Torrents</button>
|
<button name="t" value="file" class="clickable">Torrents</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form class="results_settings" action="/search" method="get">
|
<form class="results_settings" action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<select class="results-settings" name="safe" id="safeSearchSelect">
|
<select class="results-settings" name="safe" id="safeSearchSelect">
|
||||||
<option value="">Safe Search Off</option>
|
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>Safe Search Off</option>
|
||||||
<option value="active">Safe Search On</option>
|
<option value="active" {{if eq .Safe "active"}}selected{{end}}>Safe Search On</option>
|
||||||
</select>
|
</select>
|
||||||
<select class="results-settings" name="lang" id="languageSelect">
|
<select class="results-settings" name="lang" id="languageSelect">
|
||||||
{{range .LanguageOptions}}
|
{{range .LanguageOptions}}
|
||||||
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
<button class="results-save" name="t" value="text">Apply settings</button>
|
<button class="results-save" name="t" value="text">Apply settings</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="results" id="results">
|
<div class="results" id="results">
|
||||||
{{if .Results}}
|
{{if .Results}}
|
||||||
{{range .Results}}
|
{{range .Results}}
|
||||||
<div class="result_item">
|
<div class="result_item">
|
||||||
<a id="link" href="{{.URL}}">{{.URL}}</a>
|
<a id="link" href="{{.URL}}">{{.URL}}</a>
|
||||||
<a href="{{.URL}}"><h3>{{.Header}}</h3></a>
|
<a href="{{.URL}}"><h3>{{.Header}}</h3></a>
|
||||||
<p>{{.Description}}</p>
|
<p>{{.Description}}</p>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if .NoResults}}
|
{{else if .NoResults}}
|
||||||
<div class="no-results">No results found for '{{ .Query }}'. Try different keywords.</div>
|
<div class="no-results">No results found for '{{ .Query }}'. Try different keywords.</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="no-more-results">Looks like this is the end of results.</div>
|
<div class="no-more-results">Looks like this is the end of results.</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="message-bottom-left" id="message-bottom-left">
|
<div class="message-bottom-left" id="message-bottom-left">
|
||||||
<span>Searching for new results...</span>
|
<span>Searching for new results...</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="prev-next prev-img" id="prev-next">
|
<div class="prev-next prev-img" id="prev-next">
|
||||||
<form action="/search" method="get">
|
<form action="/search" method="get">
|
||||||
<input type="hidden" name="q" value="{{ .Query }}">
|
<input type="hidden" name="q" value="{{ .Query }}">
|
||||||
<input type="hidden" name="t" value="text">
|
<input type="hidden" name="t" value="text">
|
||||||
{{ if .HasPrevPage }}
|
{{ if .HasPrevPage }}
|
||||||
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
<button type="submit" name="p" value="{{ sub .Page 1 }}">Previous</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if .HasNextPage }}
|
{{ if .HasNextPage }}
|
||||||
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
<button type="submit" name="p" value="{{ add .Page 1 }}">Next</button>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// Check if JavaScript is enabled and modify the DOM accordingly
|
// Check if JavaScript is enabled and modify the DOM accordingly
|
||||||
document.getElementById('content').classList.remove('js-enabled');
|
document.getElementById('content').classList.remove('js-enabled');
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
if (document.getElementById('prev-next')) {
|
if (document.getElementById('prev-next')) {
|
||||||
document.getElementById('prev-next').style.display = 'none';
|
document.getElementById('prev-next').style.display = 'none';
|
||||||
|
|
||||||
let page = {{ .Page }};
|
let page = {{ .Page }};
|
||||||
const query = "{{ .Query }}";
|
const query = "{{ .Query }}";
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let hasMoreResults = true;
|
let hasMoreResults = true;
|
||||||
const loadingIndicator = document.getElementById('message-bottom-left');
|
const loadingIndicator = document.getElementById('message-bottom-left');
|
||||||
let loadingTimeout;
|
let loadingTimeout;
|
||||||
|
|
||||||
function loadResults(newPage) {
|
function loadResults(newPage) {
|
||||||
if (loading || !hasMoreResults) return;
|
if (loading || !hasMoreResults) return;
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
// Show loading indicator if taking more than 100ms
|
// Show loading indicator if taking more than 100ms
|
||||||
loadingTimeout = setTimeout(() => {
|
loadingTimeout = setTimeout(() => {
|
||||||
loadingIndicator.style.display = 'flex';
|
loadingIndicator.style.display = 'flex';
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
fetch(`/search?q=${encodeURIComponent(query)}&t=text&p=${newPage}`)
|
fetch(`/search?q=${encodeURIComponent(query)}&t=text&p=${newPage}`)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
clearTimeout(loadingTimeout);
|
clearTimeout(loadingTimeout);
|
||||||
loadingIndicator.style.display = 'none';
|
loadingIndicator.style.display = 'none';
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const doc = parser.parseFromString(data, 'text/html');
|
const doc = parser.parseFromString(data, 'text/html');
|
||||||
const newResults = doc.getElementById('results').innerHTML;
|
const newResults = doc.getElementById('results').innerHTML;
|
||||||
const noResultsMessage = "No results found for '{{ .Query }}'. Try different keywords.";
|
const noResultsMessage = "No results found for '{{ .Query }}'. Try different keywords.";
|
||||||
|
|
||||||
if (newResults.includes(noResultsMessage)) {
|
if (newResults.includes(noResultsMessage)) {
|
||||||
document.getElementById('results').innerHTML += "<div class='no-more-results'>Looks like this is the end of results.</div>";
|
document.getElementById('results').innerHTML += "<div class='no-more-results'>Looks like this is the end of results.</div>";
|
||||||
hasMoreResults = false;
|
hasMoreResults = false;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('results').innerHTML += newResults;
|
document.getElementById('results').innerHTML += newResults;
|
||||||
page = newPage;
|
page = newPage;
|
||||||
}
|
}
|
||||||
loading = false;
|
loading = false;
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
clearTimeout(loadingTimeout);
|
clearTimeout(loadingTimeout);
|
||||||
loadingIndicator.style.display = 'none';
|
loadingIndicator.style.display = 'none';
|
||||||
console.error('Error loading results:', error);
|
console.error('Error loading results:', error);
|
||||||
loading = false;
|
loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('scroll', () => {
|
window.addEventListener('scroll', () => {
|
||||||
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
|
||||||
loadResults(page + 1);
|
loadResults(page + 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
10
text.go
10
text.go
|
@ -48,23 +48,25 @@ func HandleTextSearch(w http.ResponseWriter, settings UserSettings, query string
|
||||||
Query string
|
Query string
|
||||||
Page int
|
Page int
|
||||||
Fetched string
|
Fetched string
|
||||||
LanguageOptions []LanguageOption
|
|
||||||
CurrentLang string
|
|
||||||
HasPrevPage bool
|
HasPrevPage bool
|
||||||
HasNextPage bool
|
HasNextPage bool
|
||||||
NoResults bool
|
NoResults bool
|
||||||
|
LanguageOptions []LanguageOption
|
||||||
|
CurrentLang string
|
||||||
Theme string
|
Theme string
|
||||||
|
Safe string
|
||||||
}{
|
}{
|
||||||
Results: combinedResults,
|
Results: combinedResults,
|
||||||
Query: query,
|
Query: query,
|
||||||
Page: page,
|
Page: page,
|
||||||
Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()),
|
Fetched: fmt.Sprintf("%.2f seconds", elapsedTime.Seconds()),
|
||||||
LanguageOptions: languageOptions,
|
|
||||||
CurrentLang: settings.Language,
|
|
||||||
HasPrevPage: page > 1,
|
HasPrevPage: page > 1,
|
||||||
HasNextPage: len(combinedResults) >= 50,
|
HasNextPage: len(combinedResults) >= 50,
|
||||||
NoResults: len(combinedResults) == 0,
|
NoResults: len(combinedResults) == 0,
|
||||||
|
LanguageOptions: languageOptions,
|
||||||
|
CurrentLang: settings.Language,
|
||||||
Theme: settings.Theme,
|
Theme: settings.Theme,
|
||||||
|
Safe: settings.SafeSearch,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tmpl.Execute(w, data)
|
err = tmpl.Execute(w, data)
|
||||||
|
|
114
user-settings.go
Normal file → Executable file
114
user-settings.go
Normal file → Executable file
|
@ -1,54 +1,60 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
type UserSettings struct {
|
type UserSettings struct {
|
||||||
Theme string
|
Theme string
|
||||||
Language string
|
Language string
|
||||||
SafeSearch string
|
SafeSearch string
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadUserSettings(r *http.Request) UserSettings {
|
func loadUserSettings(r *http.Request) UserSettings {
|
||||||
var settings UserSettings
|
var settings UserSettings
|
||||||
|
|
||||||
// Load theme
|
// Load theme
|
||||||
if cookie, err := r.Cookie("theme"); err == nil {
|
if cookie, err := r.Cookie("theme"); err == nil {
|
||||||
settings.Theme = cookie.Value
|
settings.Theme = cookie.Value
|
||||||
} else {
|
} else {
|
||||||
settings.Theme = "dark" // Default theme
|
settings.Theme = "dark" // Default theme
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load language
|
// Load language
|
||||||
if cookie, err := r.Cookie("language"); err == nil {
|
if cookie, err := r.Cookie("language"); err == nil {
|
||||||
settings.Language = cookie.Value
|
settings.Language = cookie.Value
|
||||||
} else {
|
} else {
|
||||||
settings.Language = "en" // Default language
|
settings.Language = "en" // Default language
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load safe search
|
// Load safe search
|
||||||
if cookie, err := r.Cookie("safe"); err == nil {
|
if cookie, err := r.Cookie("safe"); err == nil {
|
||||||
settings.SafeSearch = cookie.Value
|
settings.SafeSearch = cookie.Value
|
||||||
} else {
|
} else {
|
||||||
settings.SafeSearch = "" // Default safe search off
|
settings.SafeSearch = "" // Default safe search off
|
||||||
}
|
}
|
||||||
|
|
||||||
return settings
|
return settings
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveUserSettings(w http.ResponseWriter, settings UserSettings) {
|
func saveUserSettings(w http.ResponseWriter, settings UserSettings) {
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
Name: "theme",
|
Name: "theme",
|
||||||
Value: settings.Theme,
|
Value: settings.Theme,
|
||||||
Path: "/",
|
Path: "/",
|
||||||
})
|
Secure: true, // Ensure cookie is sent over HTTPS only
|
||||||
http.SetCookie(w, &http.Cookie{
|
SameSite: http.SameSiteNoneMode, // Set SameSite to None
|
||||||
Name: "language",
|
})
|
||||||
Value: settings.Language,
|
http.SetCookie(w, &http.Cookie{
|
||||||
Path: "/",
|
Name: "language",
|
||||||
})
|
Value: settings.Language,
|
||||||
http.SetCookie(w, &http.Cookie{
|
Path: "/",
|
||||||
Name: "safe",
|
Secure: true, // Ensure cookie is sent over HTTPS only
|
||||||
Value: settings.SafeSearch,
|
SameSite: http.SameSiteNoneMode, // Set SameSite to None
|
||||||
Path: "/",
|
})
|
||||||
})
|
http.SetCookie(w, &http.Cookie{
|
||||||
}
|
Name: "safe",
|
||||||
|
Value: settings.SafeSearch,
|
||||||
|
Path: "/",
|
||||||
|
Secure: true, // Ensure cookie is sent over HTTPS only
|
||||||
|
SameSite: http.SameSiteNoneMode, // Set SameSite to None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
17
video.go
17
video.go
|
@ -166,13 +166,16 @@ func handleVideoSearch(w http.ResponseWriter, settings UserSettings, query strin
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tmpl.Execute(w, map[string]interface{}{
|
err = tmpl.Execute(w, map[string]interface{}{
|
||||||
"Results": results,
|
"Results": results,
|
||||||
"Query": query,
|
"Query": query,
|
||||||
"Fetched": fmt.Sprintf("%.2f seconds", elapsed.Seconds()),
|
"Fetched": fmt.Sprintf("%.2f seconds", elapsed.Seconds()),
|
||||||
"Page": page,
|
"Page": page,
|
||||||
"HasPrevPage": page > 1,
|
"HasPrevPage": page > 1,
|
||||||
"HasNextPage": len(results) > 0, // no
|
"HasNextPage": len(results) > 0,
|
||||||
"Theme": settings.Theme,
|
"LanguageOptions": languageOptions,
|
||||||
|
"CurrentLang": settings.Language,
|
||||||
|
"Theme": settings.Theme,
|
||||||
|
"Safe": settings.SafeSearch,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printErr("Error executing template: %v", err)
|
printErr("Error executing template: %v", err)
|
||||||
|
|
Loading…
Add table
Reference in a new issue