Forgot to commit for a while, shit commit <3
This commit is contained in:
parent
9a4c281db3
commit
c26e955a08
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
node_modules
|
||||
gulpfile.js
|
||||
.sftp-config.json
|
||||
sftp-config.json
|
||||
build
|
||||
meikan
|
||||
compile.bat
|
||||
meikan.sublime-workspace
|
72
api/api.go
Normal file
72
api/api.go
Normal file
@ -0,0 +1,72 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"path"
|
||||
)
|
||||
|
||||
type Genre struct {
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
}
|
||||
|
||||
type Anime struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Type string `json:"type"`
|
||||
Episodes int `json:"episodes"`
|
||||
State string `json:"state"`
|
||||
Rating string `json:"rating"`
|
||||
StartDate string `json:"start_date"`
|
||||
EndDate string `json:"end_date"`
|
||||
Genres []Genre `json:"genres"`
|
||||
AverageDuration int `json:"average_duration"`
|
||||
AnidbID int `json:"anidb_id"`
|
||||
MyanimelistID int `json:"myanimelist_id"`
|
||||
}
|
||||
|
||||
type AnimeSearch struct {
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
var baseURL = "https://api.meikan.moe/v1/"
|
||||
|
||||
func getJSON(url string, target interface{}) error {
|
||||
r, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
return json.NewDecoder(r.Body).Decode(&target)
|
||||
}
|
||||
|
||||
func postJSON(url string, form AnimeSearch, target interface{}) error {
|
||||
b := new(bytes.Buffer)
|
||||
json.NewEncoder(b).Encode(form)
|
||||
|
||||
r, err := http.Post(url, "application/json; charset=utf-8", b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Body.Close()
|
||||
return json.NewDecoder(r.Body).Decode(target)
|
||||
}
|
||||
|
||||
func AnimeByID(id string) (Anime, error) {
|
||||
anime := Anime{}
|
||||
url := baseURL + path.Join("anime", id)
|
||||
err := getJSON(url, &anime)
|
||||
return anime, err
|
||||
}
|
||||
|
||||
func SearchAnime(title string) ([]Anime, error) {
|
||||
anime := []Anime{}
|
||||
|
||||
form := AnimeSearch{Title: title}
|
||||
url := baseURL + "anime"
|
||||
err := postJSON(url, form, &anime)
|
||||
return anime, err
|
||||
}
|
5
components/footer.gohtml
Normal file
5
components/footer.gohtml
Normal file
@ -0,0 +1,5 @@
|
||||
{{ define "footer" }}
|
||||
<script src="/static/js/menu.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
@ -1,586 +1,260 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{{ define "header" }}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Meikan - Home</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="menu">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<a class="logo" href="/home.html">
|
||||
|
||||
<a class="logo" href="/">
|
||||
<i class="material-icons">local_library</i><span>Meikan</span>
|
||||
|
||||
</a>
|
||||
|
||||
<a data-group="anime" href="/anime">
|
||||
|
||||
anime
|
||||
|
||||
</a>
|
||||
|
||||
<a data-group="manga" href="/manga">
|
||||
|
||||
manga
|
||||
|
||||
</a>
|
||||
|
||||
<a data-group="vn" href="/vn">
|
||||
|
||||
vn
|
||||
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="subMenu" class="submenu">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div data-group="anime" class="group">
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Top Anime</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Top Genre</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Random</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div data-group="manga" class="group">
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Top Manga</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Top Genre</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Random</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div data-group="vn" class="group">
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Top VN</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Top Genre</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<div class="groupTitle">Random</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<div class="title">Something</div>
|
||||
|
||||
<div class="info">TV | 10 eps | Finished</div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
let menus = document.querySelectorAll('a[data-group]'),
|
||||
|
||||
subMenu = document.getElementById("subMenu"),
|
||||
|
||||
activeSubMenuGroup = [
|
||||
|
||||
document.querySelector(`div.group[data-group]`),
|
||||
|
||||
document.querySelector(`a[data-group]`)
|
||||
|
||||
];
|
||||
|
||||
subMenuGroups = [];
|
||||
|
||||
|
||||
|
||||
function openMenu(event){
|
||||
|
||||
activeSubMenuGroup[0].classList.remove("open");
|
||||
|
||||
activeSubMenuGroup[1].classList.remove("open");
|
||||
|
||||
activeSubMenuGroup[0] = subMenuGroups[this.dataset.group];
|
||||
|
||||
activeSubMenuGroup[1] = this;
|
||||
|
||||
|
||||
|
||||
this.classList.add("open");
|
||||
|
||||
subMenu.classList.add("open");
|
||||
|
||||
activeSubMenuGroup[0].classList.add("open");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function keepMenuOpen(event){
|
||||
|
||||
subMenu.classList.add("open");
|
||||
|
||||
activeSubMenuGroup[1].classList.add("open")
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function closeMenu(event){
|
||||
|
||||
subMenu.classList.remove("open");
|
||||
|
||||
activeSubMenuGroup[1].classList.remove("open");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
subMenu.addEventListener("mouseenter", keepMenuOpen);
|
||||
|
||||
subMenu.addEventListener("mouseleave", closeMenu);
|
||||
|
||||
for(let m of menus){
|
||||
|
||||
subMenuGroups[m.dataset.group] = document.querySelector(`div.group[data-group="${m.dataset.group}"]`);
|
||||
|
||||
m.addEventListener("mouseenter", openMenu);
|
||||
|
||||
m.addEventListener("mouseleave", closeMenu);
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
79
main.go
Normal file
79
main.go
Normal file
@ -0,0 +1,79 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"./api"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
const sockPath = "/srv/kumori.moe/sock/meikan.sock"
|
||||
|
||||
var tmpl = template.Must(template.ParseGlob("templates/*.gohtml"))
|
||||
|
||||
func init() {
|
||||
l, _ := ioutil.ReadDir("components")
|
||||
for _, v := range l {
|
||||
c, _ := ioutil.ReadFile(`components/` + v.Name())
|
||||
tmpl, _ = tmpl.Parse(string(c))
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
os.Remove(sockPath)
|
||||
sock, err := net.Listen("unix", sockPath)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
router := httprouter.New()
|
||||
|
||||
router.GET("/", getIndex)
|
||||
router.GET("/anime", getAnime)
|
||||
router.GET("/reload", reload)
|
||||
|
||||
router.ServeFiles("/static/*filepath", http.Dir("static/"))
|
||||
|
||||
err = os.Chmod(sockPath, 0770)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Fatal(http.Serve(sock, router))
|
||||
}
|
||||
|
||||
func getIndex(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
err := tmpl.ExecuteTemplate(w, "home.gohtml", nil)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func getAnime(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
animeList, err := api.SearchAnime("tsukaima")
|
||||
if err != nil {
|
||||
fmt.Fprint(w, err)
|
||||
return
|
||||
}
|
||||
err = tmpl.ExecuteTemplate(w, "anime.gohtml", &animeList)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func reload(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
tmpl = template.Must(template.ParseGlob("templates/*.gohtml"))
|
||||
l, _ := ioutil.ReadDir("components")
|
||||
for _, v := range l {
|
||||
c, _ := ioutil.ReadFile(`components/` + v.Name())
|
||||
tmpl, _ = tmpl.Parse(string(c))
|
||||
}
|
||||
}
|
44
meikan.go
44
meikan.go
@ -1,44 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
const sockPath = "/srv/kumori.moe/sock/meikan.sock"
|
||||
|
||||
var templates = template.Must(template.ParseGlob("templates/*.html"))
|
||||
|
||||
func main() {
|
||||
os.Remove(sockPath)
|
||||
sock, err := net.Listen("unix", sockPath)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
router := httprouter.New()
|
||||
|
||||
router.GET("/", index)
|
||||
router.ServeFiles("/static/*filepath", http.Dir("static/"))
|
||||
|
||||
if err := os.Chmod(sockPath, 0770); err != nil {
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Fatal(http.Serve(sock, router))
|
||||
}
|
||||
|
||||
func index(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
err := templates.ExecuteTemplate(w, "home.html", nil)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
}
|
@ -2,9 +2,8 @@
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-sass": "^3.1.0",
|
||||
"gulp-scp2": "^0.2.0",
|
||||
"gulp-sftp": "^0.1.5",
|
||||
"gulp-sftp-with-callbacks": "^0.1.8",
|
||||
"request": "^2.81.0",
|
||||
"scp2": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
74
sass/animeList.scss
Normal file
74
sass/animeList.scss
Normal file
@ -0,0 +1,74 @@
|
||||
@import 'variables';
|
||||
.search {
|
||||
display: flex;
|
||||
.filters {
|
||||
width: 300px;
|
||||
}
|
||||
.cardList {
|
||||
padding: 20px 0;
|
||||
|
||||
flex: 1;
|
||||
.card {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
border-radius: 2px;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.24);
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
img {
|
||||
height: 200px;
|
||||
}
|
||||
.body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
max-height: 200px;
|
||||
|
||||
flex: 1;
|
||||
.info {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex-direction: column;
|
||||
|
||||
padding: 16px 16px 0;
|
||||
|
||||
flex: 1;
|
||||
.title {
|
||||
font-size: 25px;
|
||||
|
||||
color: $pink;
|
||||
}
|
||||
.synopsis {
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
|
||||
padding: 16px 0 0 0;
|
||||
|
||||
color: rgba(0,0,0,.52);
|
||||
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
.action {
|
||||
padding: 16px;
|
||||
|
||||
border-top: 1px rgba(0,0,0,.12) solid;
|
||||
button {
|
||||
font-size: 16px;
|
||||
|
||||
color: #448aff;
|
||||
border: none;
|
||||
background: none;
|
||||
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
102
sass/base.scss
102
sass/base.scss
@ -1,5 +1,4 @@
|
||||
@font-face
|
||||
{
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
@ -8,8 +7,7 @@
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
||||
}
|
||||
|
||||
@font-face
|
||||
{
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
@ -19,30 +17,28 @@
|
||||
|
||||
@import 'variables';
|
||||
|
||||
*
|
||||
{
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body
|
||||
{
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
&:after
|
||||
{
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
body {
|
||||
&:after {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
z-index: -1;
|
||||
|
||||
width: 100%;
|
||||
height: calc(100% - 65px);
|
||||
height: 100%;
|
||||
|
||||
content: '';
|
||||
|
||||
@ -50,8 +46,7 @@ body
|
||||
background: url('/static/img/bg.svg');
|
||||
background-size: cover;
|
||||
}
|
||||
.material-icons
|
||||
{
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
@ -69,15 +64,13 @@ body
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
.container
|
||||
{
|
||||
.container {
|
||||
position: relative;
|
||||
|
||||
width: 1240px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.menu
|
||||
{
|
||||
.menu {
|
||||
font-size: 0;
|
||||
|
||||
position: relative;
|
||||
@ -89,8 +82,7 @@ body
|
||||
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 6px rgba(0,0,0,.23), 0 3px 6px rgba(0,0,0,.16);
|
||||
a
|
||||
{
|
||||
a {
|
||||
font-size: 22px;
|
||||
font-variant: small-caps;
|
||||
line-height: 65px;
|
||||
@ -105,37 +97,36 @@ body
|
||||
text-decoration: none;
|
||||
|
||||
color: rgba(0,0,0,.52);
|
||||
&:first-child
|
||||
{
|
||||
&:first-child {
|
||||
font-size: 30px;
|
||||
font-variant: normal;
|
||||
|
||||
padding-left: 0;
|
||||
|
||||
color: #ff4081;
|
||||
color: $pink;
|
||||
> i {
|
||||
height: inherit;
|
||||
line-height: inherit;
|
||||
vertical-align: top;
|
||||
font-size: 30px;
|
||||
line-height: inherit;
|
||||
|
||||
height: inherit;
|
||||
|
||||
vertical-align: top;
|
||||
}
|
||||
> span
|
||||
{
|
||||
> span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
&:not(:first-child):hover,
|
||||
&:not(:first-child).open
|
||||
{
|
||||
&:not(:first-child).open {
|
||||
color: #fff;
|
||||
background: #ff4081;
|
||||
background: $pink;
|
||||
}
|
||||
}
|
||||
}
|
||||
.submenu
|
||||
{
|
||||
position: relative;
|
||||
}
|
||||
.submenu {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 65px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
@ -148,15 +139,12 @@ body
|
||||
box-shadow: inset 0 3px 6px rgba(0,0,0,.23);
|
||||
|
||||
will-change: height;
|
||||
&.open
|
||||
{
|
||||
&.open {
|
||||
height: 350px;
|
||||
}
|
||||
.container
|
||||
{
|
||||
.container {
|
||||
height: 350px;
|
||||
.group
|
||||
{
|
||||
.group {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@ -169,12 +157,10 @@ body
|
||||
pointer-events: none;
|
||||
|
||||
opacity: 0;
|
||||
&.open
|
||||
{
|
||||
&.open {
|
||||
opacity: 1;
|
||||
}
|
||||
.column
|
||||
{
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -183,20 +169,17 @@ body
|
||||
color: #fff;
|
||||
|
||||
flex: 1;
|
||||
.groupTitle
|
||||
{
|
||||
.groupTitle {
|
||||
line-height: 20px;
|
||||
|
||||
max-height: 20px;
|
||||
}
|
||||
> *
|
||||
{
|
||||
> * {
|
||||
display: flex;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
ul
|
||||
{
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -206,13 +189,11 @@ body
|
||||
list-style: none;
|
||||
|
||||
border-left: 2px rgba(255,255,255,.1) solid;
|
||||
li
|
||||
{
|
||||
li {
|
||||
position: relative;
|
||||
|
||||
flex: 1;
|
||||
.title
|
||||
{
|
||||
.title {
|
||||
font-size: 16px;
|
||||
|
||||
display: block;
|
||||
@ -221,8 +202,7 @@ body
|
||||
|
||||
color: #ff80ab;
|
||||
}
|
||||
.info
|
||||
{
|
||||
.info {
|
||||
font-size: .8em;
|
||||
font-weight: light;
|
||||
|
||||
@ -233,5 +213,5 @@ body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,8 @@
|
||||
}
|
||||
.submenu
|
||||
{
|
||||
position: relative;
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
z-index: 1;
|
||||
|
||||
overflow: hidden;
|
||||
|
@ -0,0 +1 @@
|
||||
$pink: #ff4081;
|
1
static/css/animeList.css
Normal file
1
static/css/animeList.css
Normal file
@ -0,0 +1 @@
|
||||
.search{display:flex}.search .filters{width:300px}.search .cardList{padding:20px 0;flex:1}.search .cardList .card{display:flex;overflow:hidden;border-radius:2px;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24)}.search .cardList .card:not(:last-child){margin-bottom:20px}.search .cardList .card img{height:200px}.search .cardList .card .body{display:flex;flex-direction:column;max-height:200px;flex:1}.search .cardList .card .body .info{display:flex;overflow:hidden;flex-direction:column;padding:16px 16px 0;flex:1}.search .cardList .card .body .info .title{font-size:25px;color:#ff4081}.search .cardList .card .body .info .synopsis{overflow:hidden;display:-webkit-box;padding:16px 0 0 0;color:rgba(0,0,0,0.52);-webkit-line-clamp:3;-webkit-box-orient:vertical;margin-bottom:16px}.search .cardList .card .body .action{padding:16px;border-top:1px rgba(0,0,0,0.12) solid}.search .cardList .card .body .action button{font-size:16px;color:#448aff;border:none;background:none;outline:none}
|
@ -1 +1 @@
|
||||
@font-face{font-family:'Roboto';font-weight:400;font-style:normal;src:local("Roboto"),local("Roboto-Regular"),url(/static/fonts/roboto.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215}@font-face{font-family:'Material Icons';font-weight:400;font-style:normal;src:local("Material Icons"),local("MaterialIcons-Regular"),url(/static/fonts/material-icons.woff2) format("woff2")}*{box-sizing:border-box}html,body{font-family:'Roboto', sans-serif;height:100%;margin:0}body:after{position:absolute;top:65px;left:0;width:100%;height:calc(100% - 65px);content:'';opacity:.05;background:url("/static/img/bg.svg");background-size:cover}body .material-icons{font-family:'Material Icons';font-size:24px;font-weight:normal;font-style:normal;line-height:1;display:inline-block;white-space:nowrap;letter-spacing:normal;text-transform:none;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}body .container{position:relative;width:1240px;margin:0 auto}body .menu{font-size:0;position:relative;z-index:2;height:65px;margin:0;padding:0;background:#fff;box-shadow:0 3px 6px rgba(0,0,0,0.23),0 3px 6px rgba(0,0,0,0.16)}body .menu a{font-size:22px;font-variant:small-caps;line-height:65px;display:inline-block;height:100%;padding:0 30px;transition:background .1s, color .1s;vertical-align:middle;text-decoration:none;color:rgba(0,0,0,0.52)}body .menu a:first-child{font-size:30px;font-variant:normal;padding-left:0;color:#ff4081}body .menu a:first-child>i{height:inherit;line-height:inherit;vertical-align:top;font-size:30px}body .menu a:first-child>span{margin-left:10px}body .menu a:not(:first-child):hover,body .menu a:not(:first-child).open{color:#fff;background:#ff4081}body .submenu{position:relative;z-index:1;overflow:hidden;width:100%;height:0;transition:height .5s;background:#212121;box-shadow:inset 0 3px 6px rgba(0,0,0,0.23);will-change:height}body .submenu.open{height:350px}body .submenu .container{height:350px}body .submenu .container .group{position:absolute;top:0;left:0;display:flex;width:100%;height:100%;pointer-events:none;opacity:0}body .submenu .container .group.open{opacity:1}body .submenu .container .group .column{display:flex;flex-direction:column;margin:20px 10px;color:#fff;flex:1}body .submenu .container .group .column .groupTitle{line-height:20px;max-height:20px}body .submenu .container .group .column>*{display:flex;height:100%}body .submenu .container .group .column ul{display:flex;flex-direction:column;margin:20px 0 0 10px;padding:10px 20px;list-style:none;border-left:2px rgba(255,255,255,0.1) solid}body .submenu .container .group .column ul li{position:relative;flex:1}body .submenu .container .group .column ul li .title{font-size:16px;display:block;margin-bottom:3px;color:#ff80ab}body .submenu .container .group .column ul li .info{font-size:.8em;font-weight:light;color:#aaa}
|
||||
@font-face{font-family:'Roboto';font-weight:400;font-style:normal;src:local("Roboto"),local("Roboto-Regular"),url(/static/fonts/roboto.woff2) format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215}@font-face{font-family:'Material Icons';font-weight:400;font-style:normal;src:local("Material Icons"),local("MaterialIcons-Regular"),url(/static/fonts/material-icons.woff2) format("woff2")}*{box-sizing:border-box}html,body{font-family:'Roboto', sans-serif;height:100%;margin:0}body:after{position:fixed;top:0;left:0;z-index:-1;width:100%;height:100%;content:'';opacity:.05;background:url("/static/img/bg.svg");background-size:cover}body .material-icons{font-family:'Material Icons';font-size:24px;font-weight:normal;font-style:normal;line-height:1;display:inline-block;white-space:nowrap;letter-spacing:normal;text-transform:none;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:'liga';-webkit-font-smoothing:antialiased}body .container{position:relative;width:1240px;margin:0 auto}body .menu{font-size:0;position:relative;z-index:2;height:65px;margin:0;padding:0;background:#fff;box-shadow:0 3px 6px rgba(0,0,0,0.23),0 3px 6px rgba(0,0,0,0.16)}body .menu a{font-size:22px;font-variant:small-caps;line-height:65px;display:inline-block;height:100%;padding:0 30px;transition:background .1s, color .1s;vertical-align:middle;text-decoration:none;color:rgba(0,0,0,0.52)}body .menu a:first-child{font-size:30px;font-variant:normal;padding-left:0;color:#ff4081}body .menu a:first-child>i{font-size:30px;line-height:inherit;height:inherit;vertical-align:top}body .menu a:first-child>span{margin-left:10px}body .menu a:not(:first-child):hover,body .menu a:not(:first-child).open{color:#fff;background:#ff4081}body .submenu{position:absolute;z-index:1;top:65px;overflow:hidden;width:100%;height:0;transition:height .5s;background:#212121;box-shadow:inset 0 3px 6px rgba(0,0,0,0.23);will-change:height}body .submenu.open{height:350px}body .submenu .container{height:350px}body .submenu .container .group{position:absolute;top:0;left:0;display:flex;width:100%;height:100%;pointer-events:none;opacity:0}body .submenu .container .group.open{opacity:1}body .submenu .container .group .column{display:flex;flex-direction:column;margin:20px 10px;color:#fff;flex:1}body .submenu .container .group .column .groupTitle{line-height:20px;max-height:20px}body .submenu .container .group .column>*{display:flex;height:100%}body .submenu .container .group .column ul{display:flex;flex-direction:column;margin:20px 0 0 10px;padding:10px 20px;list-style:none;border-left:2px rgba(255,255,255,0.1) solid}body .submenu .container .group .column ul li{position:relative;flex:1}body .submenu .container .group .column ul li .title{font-size:16px;display:block;margin-bottom:3px;color:#ff80ab}body .submenu .container .group .column ul li .info{font-size:.8em;font-weight:light;color:#aaa}
|
||||
|
@ -1 +1 @@
|
||||
.menu{font-size:0;position:relative;z-index:2;height:65px;margin:0;padding:0;background:#fff;box-shadow:0 3px 6px rgba(0,0,0,0.23),0 3px 6px rgba(0,0,0,0.16)}.menu a{font-size:22px;font-variant:small-caps;line-height:65px;display:inline-block;height:100%;padding:0 30px;transition:background .1s, color .1s;vertical-align:middle;text-decoration:none;color:rgba(0,0,0,0.52)}.menu a:first-child{font-size:30px;font-variant:normal;padding-left:0;color:#ff4081}.menu a:first-child>i{height:inherit;line-height:inherit;vertical-align:top;font-size:30px}.menu a:first-child>span{margin-left:10px}.menu a:not(:first-child):hover,.menu a:not(:first-child).open{color:#fff;background:#ff4081}.submenu{position:relative;z-index:1;overflow:hidden;width:100%;height:0;transition:height .5s;background:#212121;box-shadow:inset 0 3px 6px rgba(0,0,0,0.23);will-change:height}.submenu.open{height:350px}.submenu .container{height:350px}.submenu .container .group{position:absolute;top:0;left:0;display:flex;width:100%;height:100%;pointer-events:none;opacity:0}.submenu .container .group.open{opacity:1}.submenu .container .group .column{display:flex;flex-direction:column;margin:20px 10px;color:#fff;flex:1}.submenu .container .group .column .groupTitle{line-height:20px;max-height:20px}.submenu .container .group .column>*{display:flex;height:100%}.submenu .container .group .column ul{display:flex;flex-direction:column;margin:20px 0 0 10px;padding:10px 20px;list-style:none;border-left:2px rgba(255,255,255,0.1) solid}.submenu .container .group .column ul li{position:relative;flex:1}.submenu .container .group .column ul li .title{font-size:16px;display:block;margin-bottom:3px;color:#ff80ab}.submenu .container .group .column ul li .info{font-size:.8em;font-weight:light;color:#aaa}
|
||||
.menu{font-size:0;position:relative;z-index:2;height:65px;margin:0;padding:0;background:#fff;box-shadow:0 3px 6px rgba(0,0,0,0.23),0 3px 6px rgba(0,0,0,0.16)}.menu a{font-size:22px;font-variant:small-caps;line-height:65px;display:inline-block;height:100%;padding:0 30px;transition:background .1s, color .1s;vertical-align:middle;text-decoration:none;color:rgba(0,0,0,0.52)}.menu a:first-child{font-size:30px;font-variant:normal;padding-left:0;color:#ff4081}.menu a:first-child>i{height:inherit;line-height:inherit;vertical-align:top;font-size:30px}.menu a:first-child>span{margin-left:10px}.menu a:not(:first-child):hover,.menu a:not(:first-child).open{color:#fff;background:#ff4081}.submenu{position:absolute;top:65px;z-index:1;overflow:hidden;width:100%;height:0;transition:height .5s;background:#212121;box-shadow:inset 0 3px 6px rgba(0,0,0,0.23);will-change:height}.submenu.open{height:350px}.submenu .container{height:350px}.submenu .container .group{position:absolute;top:0;left:0;display:flex;width:100%;height:100%;pointer-events:none;opacity:0}.submenu .container .group.open{opacity:1}.submenu .container .group .column{display:flex;flex-direction:column;margin:20px 10px;color:#fff;flex:1}.submenu .container .group .column .groupTitle{line-height:20px;max-height:20px}.submenu .container .group .column>*{display:flex;height:100%}.submenu .container .group .column ul{display:flex;flex-direction:column;margin:20px 0 0 10px;padding:10px 20px;list-style:none;border-left:2px rgba(255,255,255,0.1) solid}.submenu .container .group .column ul li{position:relative;flex:1}.submenu .container .group .column ul li .title{font-size:16px;display:block;margin-bottom:3px;color:#ff80ab}.submenu .container .group .column ul li .info{font-size:.8em;font-weight:light;color:#aaa}
|
||||
|
37
static/js/menu.js
Normal file
37
static/js/menu.js
Normal file
@ -0,0 +1,37 @@
|
||||
let menus = document.querySelectorAll('a[data-group]'),
|
||||
subMenu = document.getElementById("subMenu"),
|
||||
activeSubMenuGroup = [
|
||||
document.querySelector(`div.group[data-group]`),
|
||||
document.querySelector(`a[data-group]`)
|
||||
];
|
||||
subMenuGroups = [];
|
||||
|
||||
function openMenu(event){
|
||||
activeSubMenuGroup[0].classList.remove("open");
|
||||
activeSubMenuGroup[1].classList.remove("open");
|
||||
activeSubMenuGroup[0] = subMenuGroups[this.dataset.group];
|
||||
activeSubMenuGroup[1] = this;
|
||||
|
||||
this.classList.add("open");
|
||||
subMenu.classList.add("open");
|
||||
activeSubMenuGroup[0].classList.add("open");
|
||||
}
|
||||
|
||||
function keepMenuOpen(event){
|
||||
subMenu.classList.add("open");
|
||||
activeSubMenuGroup[1].classList.add("open")
|
||||
}
|
||||
|
||||
function closeMenu(event){
|
||||
subMenu.classList.remove("open");
|
||||
activeSubMenuGroup[1].classList.remove("open");
|
||||
}
|
||||
|
||||
subMenu.addEventListener("mouseenter", keepMenuOpen);
|
||||
subMenu.addEventListener("mouseleave", closeMenu);
|
||||
|
||||
for(let m of menus){
|
||||
subMenuGroups[m.dataset.group] = document.querySelector(`div.group[data-group="${m.dataset.group}"]`);
|
||||
m.addEventListener("mouseenter", openMenu);
|
||||
m.addEventListener("mouseleave", closeMenu);
|
||||
}
|
24
templates/anime.gohtml
Normal file
24
templates/anime.gohtml
Normal file
@ -0,0 +1,24 @@
|
||||
{{ template "header" }}
|
||||
<link rel="stylesheet" href="/static/css/animeList.css">
|
||||
<div class="container">
|
||||
<div class="search">
|
||||
<div class="filters"></div>
|
||||
<div class="cardList">
|
||||
{{ range . }}
|
||||
<div class="card">
|
||||
<img src="http://s1.narvii.com/image/d67vdzixlgx6jmy35vg2dgomjfhalqtf_hq.jpg">
|
||||
<div class="body">
|
||||
<div class="info">
|
||||
<div class="title">{{ .Title }}</div>
|
||||
<div class="synopsis">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore iure deleniti iste harum, nobis nesciunt aliquid temporibus aspernatur corrupti est. Non fugiat illum ullam rem harum tempore neque, magni architecto. Non natus est officia dolor, obcaecati autem odio molestias assumenda. Minus quae ducimus aut reprehenderit commodi, voluptatum quis nulla autem.</div>
|
||||
</div>
|
||||
<div class="action">
|
||||
<button>read more</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ template "footer" }}
|
2
templates/home.gohtml
Normal file
2
templates/home.gohtml
Normal file
@ -0,0 +1,2 @@
|
||||
{{ template "header" .}}
|
||||
{{ template "footer" }}
|
Loading…
Reference in New Issue
Block a user