Forgot to commit for a while, shit commit <3

This commit is contained in:
Crow Crowcrow 2017-04-10 21:14:40 +02:00
parent 9a4c281db3
commit c26e955a08
18 changed files with 442 additions and 535 deletions

4
.gitignore vendored
View File

@ -1,5 +1,7 @@
node_modules node_modules
gulpfile.js gulpfile.js
.sftp-config.json sftp-config.json
build build
meikan meikan
compile.bat
meikan.sublime-workspace

72
api/api.go Normal file
View 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
View File

@ -0,0 +1,5 @@
{{ define "footer" }}
<script src="/static/js/menu.js"></script>
</body>
</html>
{{ end }}

View File

@ -1,586 +1,260 @@
<!DOCTYPE html> {{ define "header" }}
<html> <!DOCTYPE html>
<head> <html>
<title>Meikan - Home</title> <head>
<link rel="stylesheet" type="text/css" href="/static/css/base.css"> <title>Meikan - Home</title>
</head> <link rel="stylesheet" type="text/css" href="/static/css/base.css">
<body> </head>
<body>
<div class="menu"> <div class="menu">
<div class="container"> <div class="container">
<a class="logo" href="/">
<a class="logo" href="/home.html">
<i class="material-icons">local_library</i><span>Meikan</span> <i class="material-icons">local_library</i><span>Meikan</span>
</a> </a>
<a data-group="anime" href="/anime"> <a data-group="anime" href="/anime">
anime anime
</a> </a>
<a data-group="manga" href="/manga"> <a data-group="manga" href="/manga">
manga manga
</a> </a>
<a data-group="vn" href="/vn"> <a data-group="vn" href="/vn">
vn vn
</a> </a>
</div> </div>
</div> </div>
<div id="subMenu" class="submenu"> <div id="subMenu" class="submenu">
<div class="container"> <div class="container">
<div data-group="anime" class="group"> <div data-group="anime" class="group">
<div class="column"> <div class="column">
<div class="groupTitle">Top Anime</div> <div class="groupTitle">Top Anime</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="column"> <div class="column">
<div class="groupTitle">Top Genre</div> <div class="groupTitle">Top Genre</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="column"> <div class="column">
<div class="groupTitle">Random</div> <div class="groupTitle">Random</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div data-group="manga" class="group"> <div data-group="manga" class="group">
<div class="column"> <div class="column">
<div class="groupTitle">Top Manga</div> <div class="groupTitle">Top Manga</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="column"> <div class="column">
<div class="groupTitle">Top Genre</div> <div class="groupTitle">Top Genre</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="column"> <div class="column">
<div class="groupTitle">Random</div> <div class="groupTitle">Random</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div data-group="vn" class="group"> <div data-group="vn" class="group">
<div class="column"> <div class="column">
<div class="groupTitle">Top VN</div> <div class="groupTitle">Top VN</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="column"> <div class="column">
<div class="groupTitle">Top Genre</div> <div class="groupTitle">Top Genre</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="column"> <div class="column">
<div class="groupTitle">Random</div> <div class="groupTitle">Random</div>
<ul> <ul>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
<li> <li>
<div class="title">Something</div> <div class="title">Something</div>
<div class="info">TV | 10 eps | Finished</div> <div class="info">TV | 10 eps | Finished</div>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{{ end }}
<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>

79
main.go Normal file
View 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))
}
}

View File

@ -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)
}
}

View File

@ -2,9 +2,8 @@
"devDependencies": { "devDependencies": {
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-sass": "^3.1.0", "gulp-sass": "^3.1.0",
"gulp-scp2": "^0.2.0",
"gulp-sftp": "^0.1.5",
"gulp-sftp-with-callbacks": "^0.1.8", "gulp-sftp-with-callbacks": "^0.1.8",
"request": "^2.81.0",
"scp2": "^0.5.0" "scp2": "^0.5.0"
} }
} }

74
sass/animeList.scss Normal file
View 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;
}
}
}
}
}
}

View File

@ -1,5 +1,4 @@
@font-face @font-face {
{
font-family: 'Roboto'; font-family: 'Roboto';
font-weight: 400; font-weight: 400;
font-style: normal; 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; 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-family: 'Material Icons';
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
@ -19,30 +17,28 @@
@import 'variables'; @import 'variables';
* * {
{
box-sizing: border-box; box-sizing: border-box;
} }
html, html,
body body {
{
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
height: 100%; height: 100%;
margin: 0; margin: 0;
} }
body body {
{ &:after {
&:after position: fixed;
{ top: 0;
position: absolute;
top: 65px;
left: 0; left: 0;
z-index: -1;
width: 100%; width: 100%;
height: calc(100% - 65px); height: 100%;
content: ''; content: '';
@ -50,8 +46,7 @@ body
background: url('/static/img/bg.svg'); background: url('/static/img/bg.svg');
background-size: cover; background-size: cover;
} }
.material-icons .material-icons {
{
font-family: 'Material Icons'; font-family: 'Material Icons';
font-size: 24px; font-size: 24px;
font-weight: normal; font-weight: normal;
@ -69,164 +64,150 @@ body
-webkit-font-feature-settings: 'liga'; -webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
} }
.container .container {
{
position: relative; position: relative;
width: 1240px; width: 1240px;
margin: 0 auto; margin: 0 auto;
} }
.menu .menu {
{ font-size: 0;
font-size: 0;
position: relative; position: relative;
z-index: 2; z-index: 2;
height: 65px; height: 65px;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: #fff; background: #fff;
box-shadow: 0 3px 6px rgba(0,0,0,.23), 0 3px 6px rgba(0,0,0,.16); box-shadow: 0 3px 6px rgba(0,0,0,.23), 0 3px 6px rgba(0,0,0,.16);
a a {
{ font-size: 22px;
font-size: 22px; font-variant: small-caps;
font-variant: small-caps; line-height: 65px;
line-height: 65px;
display: inline-block; display: inline-block;
height: 100%;
padding: 0 30px;
transition: background .1s, color .1s;
vertical-align: middle;
text-decoration: none;
color: rgba(0,0,0,.52);
&:first-child
{
font-size: 30px;
font-variant: normal;
padding-left: 0;
color: #ff4081;
> i {
height: inherit;
line-height: inherit;
vertical-align: top;
font-size: 30px;
}
> span
{
margin-left: 10px;
}
}
&:not(:first-child):hover,
&: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,.23);
will-change: height;
&.open
{
height: 350px;
}
.container
{
height: 350px;
.group
{
position: absolute;
top: 0;
left: 0;
display: flex;
width: 100%;
height: 100%; height: 100%;
padding: 0 30px;
pointer-events: none; transition: background .1s, color .1s;
vertical-align: middle;
text-decoration: none;
opacity: 0; color: rgba(0,0,0,.52);
&.open &:first-child {
{ font-size: 30px;
opacity: 1; font-variant: normal;
padding-left: 0;
color: $pink;
> i {
font-size: 30px;
line-height: inherit;
height: inherit;
vertical-align: top;
}
> span {
margin-left: 10px;
}
} }
.column &:not(:first-child):hover,
{ &:not(:first-child).open {
display: flex;
flex-direction: column;
margin: 20px 10px;
color: #fff; color: #fff;
background: $pink;
}
}
}
.submenu {
position: absolute;
z-index: 1;
top: 65px;
flex: 1; overflow: hidden;
.groupTitle
{
line-height: 20px;
max-height: 20px; width: 100%;
height: 0;
transition: height .5s;
background: #212121;
box-shadow: inset 0 3px 6px rgba(0,0,0,.23);
will-change: height;
&.open {
height: 350px;
}
.container {
height: 350px;
.group {
position: absolute;
top: 0;
left: 0;
display: flex;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0;
&.open {
opacity: 1;
} }
> * .column {
{
display: flex;
height: 100%;
}
ul
{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 20px 0 0 10px; margin: 20px 10px;
padding: 10px 20px;
list-style: none; color: #fff;
border-left: 2px rgba(255,255,255,.1) solid; flex: 1;
li .groupTitle {
{ line-height: 20px;
position: relative;
flex: 1; max-height: 20px;
.title }
{ > * {
font-size: 16px; display: flex;
display: block; height: 100%;
}
ul {
display: flex;
flex-direction: column;
margin-bottom: 3px; margin: 20px 0 0 10px;
padding: 10px 20px;
color: #ff80ab; list-style: none;
}
.info
{
font-size: .8em;
font-weight: light;
color: #aaa; border-left: 2px rgba(255,255,255,.1) solid;
li {
position: relative;
flex: 1;
.title {
font-size: 16px;
display: block;
margin-bottom: 3px;
color: #ff80ab;
}
.info {
font-size: .8em;
font-weight: light;
color: #aaa;
}
} }
} }
} }
@ -234,4 +215,3 @@ body
} }
} }
} }
}

View File

@ -56,7 +56,8 @@
} }
.submenu .submenu
{ {
position: relative; position: absolute;
top: 65px;
z-index: 1; z-index: 1;
overflow: hidden; overflow: hidden;

View File

@ -0,0 +1 @@
$pink: #ff4081;

1
static/css/animeList.css Normal file
View 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}

View File

@ -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}

View File

@ -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
View 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
View 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
View File

@ -0,0 +1,2 @@
{{ template "header" .}}
{{ template "footer" }}