From 153230580ee5002d931626c250a04abedc3905a7 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 22 Aug 2018 12:54:06 -0400 Subject: [PATCH] Cleanup javascript into fewer files, add show/description link to search pages --- public/css/app.min.css | 2 +- public/css/base.css | 4 ++ public/js/scripts-authed.min.js | 13 ++-- public/js/scripts-authed.min.js.map | 2 +- public/js/scripts.min.js.map | 2 +- public/js/src/{anime_edit.js => anime.js} | 51 ++++++++++---- public/js/src/anime_collection.js | 30 -------- public/js/src/anime_search_results.js | 27 ------- public/js/src/base/AnimeClient.js | 2 +- public/js/src/base/sort_tables.js | 4 +- public/js/src/index-authed.js | 7 +- public/js/src/manga.js | 86 +++++++++++++++++++++++ public/js/src/manga_collection.js | 24 ------- public/js/src/manga_edit.js | 64 ----------------- public/js/src/manga_search_results.js | 27 ------- public/js/src/template-helpers.js | 69 ++++++++++++++++++ public/js/tables.min.js.map | 2 +- 17 files changed, 212 insertions(+), 204 deletions(-) rename public/js/src/{anime_edit.js => anime.js} (51%) delete mode 100644 public/js/src/anime_collection.js delete mode 100644 public/js/src/anime_search_results.js create mode 100644 public/js/src/manga.js delete mode 100644 public/js/src/manga_collection.js delete mode 100644 public/js/src/manga_edit.js delete mode 100644 public/js/src/manga_search_results.js create mode 100644 public/js/src/template-helpers.js diff --git a/public/css/app.min.css b/public/css/app.min.css index c9cbdcaf..d7ccb0d1 100644 --- a/public/css/app.min.css +++ b/public/css/app.min.css @@ -1 +1 @@ -:root{-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;line-height:1.4;overflow-y:scroll;scroll-behavior:smooth;text-size-adjust:100%}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-size:1.4em;font-size:14px;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all;word-wrap:break-word}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{-webkit-box-sizing:inherit;border-style:solid;border-width:0;box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{-webkit-transition:.25s ease;color:#1271db;text-decoration:none;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}button,input,select,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:36px;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:30px;font-size:3rem}h3{font-size:2.4em;font-size:24px;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:18px;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:16px;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:14px;font-size:1.4rem}code{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;word-break:break-all;word-wrap:break-word}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:1px thin solid #444;outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],select[disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],select[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select{background-color:#fff;border:.1rem solid #ccc}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-moz-user-select:none;-ms-user-select:none;-webkit-transition:.25s ease;-webkit-user-drag:none;-webkit-user-select:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;transition:.25s ease;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{-webkit-transition:.25s ease;border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:8px;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:hsla(0,0%,100%,.65);margin:0}table{margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{width:4em}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db}.bracketed{color:#12db18}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12}.grow-1{-ms-flex-positive:1;-webkit-box-flex:1;flex-grow:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-align-end{-ms-flex-align:end;-webkit-box-align:end;align-items:flex-end}.flex-align-space-around{-ms-flex-line-pack:distribute;align-content:space-around}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.small-font{font-size:16px;font-size:1.6rem}.justify{text-align:justify}.align_center{text-align:center!important}.align_left{text-align:left!important}.align_right{text-align:right!important}.valign_top{vertical-align:top}.no_border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.danger{background-color:#ff4136;border-color:#924949;color:#fff}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#fff}.user-btn{border-color:#12db18;color:#12db18;padding:0 .5rem;text-shadow:1px 1px 1px #000}.user-btn:active,.user-btn:hover{background-color:#db7d12;border-color:#db7d12}.full_width{width:100%}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:3.6em;font-size:36px;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.cssload-loader{-webkit-perspective:780px;border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{-webkit-box-sizing:border-box;border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}.sorting,.sorting_asc,.sorting_desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting_asc:before{content:" ↑\00a0"}.sorting_desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small_character{display:inline-block;height:311px;margin:.25em .125em;position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{color:#fff;padding:.25em .125em;text-align:right;text-shadow:2px 2px 2px #000;z-index:2}.age_rating,.media_type{text-align:left}.media>.media_metadata{bottom:0;position:absolute;right:0}.media>.medium_metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{-webkit-transition:none;transition:none}.media .name a:before{content:"";display:block;height:311px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.media:hover{-webkit-transition:.25s ease;transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small_character>.name a,.small_character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000}.anime .name,.manga .name{background:#000;background:rgba(0,0,0,.45);padding:.5em .25em;text-align:center;width:100%}.anime .age_rating,.anime .airing_status,.anime .completion,.anime .delete,.anime .edit,.anime .media_type,.anime .user_rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{-ms-flex-line-pack:distribute;-ms-flex-pack:distribute;align-content:space-around;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around;padding:0 inherit;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{-ms-flex-item-align:center;align-self:center;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus_one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px);z-index:50}.anime .media>button.plus_one:hover{background:#888;color:hsla(0,0%,100%,.65)}.anime .media>button.plus_one:active{background:#444}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 22.4px);z-index:40}.manga .media>.edit_buttons button{border-color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons:hover button{background:#888;color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons button:active{background:#444}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.big-check{display:none}.big-check:checked+label{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:150px;font-size:15rem;height:100%;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series_list article.media{position:relative}#series_list .name,#series_list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series_list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.description{max-width:800px;max-width:80rem}.fixed{max-width:930px;max-width:93rem}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>div{margin:1rem}.details .media_details{max-width:300px}.details .media_details td{padding:0 1.5rem}.details p{text-align:justify}.details .media_details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media_details td:nth-child(2n){text-align:left}.character,.small_character{height:350px;vertical-align:middle;white-space:nowrap;width:225px}.character:hover .name,.small_character:hover .name{background:rgba(0,0,0,.8)}.small_character a{display:inline-block;height:100%;width:100%}.character .name,.small_character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.small_character img{-webkit-transform:translateY(-50%);position:relative;top:50%;transform:translateY(-50%);width:100%;z-index:5}.min-table{margin-left:0;min-width:0}.small_character{height:250px;width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}.media{margin:2px 0}main{padding:0 .5rem .5rem}}.streaming-logo{height:50px;vertical-align:middle;width:50px}.cover_streaming_link{display:none}.media:hover .cover_streaming_link{display:block}.cover_streaming_link .streaming-logo{-webkit-filter:drop-shadow(0 -1px 4px #fff);filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{-ms-flex-align:center;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{-ms-flex-wrap:wrap;-webkit-box-shadow:0 48px 80px -32px rgba(0,0,0,.3);background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:-webkit-box;display:-ms-flexbox;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs label{-webkit-transition:background .1s,color .1s;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs label:hover{background:#d8d8d8}.tabs label:active{background:#ccc}.tabs [type=radio]:focus+label{-webkit-box-shadow:inset 0 0 0 3px #2aa1c0;box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs [type=radio]{opacity:0;position:absolute}.tabs [type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs [type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;display:block;padding:20px 30px 30px;width:100%}.tabs .content{display:none}@media (min-width:600px){.tabs label{width:auto}.tabs .content{-ms-flex-order:99;-webkit-box-ordinal-group:100;order:99}} \ No newline at end of file +:root{-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;line-height:1.4;overflow-y:scroll;scroll-behavior:smooth;text-size-adjust:100%}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-size:1.4em;font-size:14px;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all;word-wrap:break-word}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{-webkit-box-sizing:inherit;border-style:solid;border-width:0;box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{-webkit-transition:.25s ease;color:#1271db;text-decoration:none;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}button,input,select,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:36px;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:30px;font-size:3rem}h3{font-size:2.4em;font-size:24px;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:18px;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:16px;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:14px;font-size:1.4rem}code{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;word-break:break-all;word-wrap:break-word}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:1px thin solid #444;outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],select[disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],select[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select{background-color:#fff;border:.1rem solid #ccc}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-moz-user-select:none;-ms-user-select:none;-webkit-transition:.25s ease;-webkit-user-drag:none;-webkit-user-select:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;transition:.25s ease;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{-webkit-transition:.25s ease;border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:8px;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:hsla(0,0%,100%,.65);margin:0}table{margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{width:4em}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db}.bracketed{color:#12db18}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12}.grow-1{-ms-flex-positive:1;-webkit-box-flex:1;flex-grow:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-align-end{-ms-flex-align:end;-webkit-box-align:end;align-items:flex-end}.flex-align-space-around{-ms-flex-line-pack:distribute;align-content:space-around}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.small-font{font-size:16px;font-size:1.6rem}.justify{text-align:justify}.align_center{text-align:center!important}.align_left{text-align:left!important}.align_right{text-align:right!important}.valign_top{vertical-align:top}.no_border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.danger{background-color:#ff4136;border-color:#924949;color:#fff}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#fff}.user-btn{border-color:#12db18;color:#12db18;padding:0 .5rem;text-shadow:1px 1px 1px #000}.user-btn:active,.user-btn:hover{background-color:#db7d12;border-color:#db7d12}.full_width{width:100%}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:3.6em;font-size:36px;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.cssload-loader{-webkit-perspective:780px;border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{-webkit-box-sizing:border-box;border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}.sorting,.sorting_asc,.sorting_desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting_asc:before{content:" ↑\00a0"}.sorting_desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small_character{display:inline-block;height:311px;margin:.25em .125em;position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{color:#fff;padding:.25em .125em;text-align:right;text-shadow:2px 2px 2px #000;z-index:2}.age_rating,.media_type{text-align:left}.media>.media_metadata{bottom:0;position:absolute;right:0}.media>.medium_metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{-webkit-transition:none;transition:none}.media .name a:before{content:"";display:block;height:311px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.media:hover{-webkit-transition:.25s ease;transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small_character>.name a,.small_character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000}.anime .name,.manga .name{background:#000;background:rgba(0,0,0,.45);padding:.5em .25em;text-align:center;width:100%}.anime .age_rating,.anime .airing_status,.anime .completion,.anime .delete,.anime .edit,.anime .media_type,.anime .user_rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{-ms-flex-line-pack:distribute;-ms-flex-pack:distribute;align-content:space-around;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around;padding:0 inherit;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{-ms-flex-item-align:center;align-self:center;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus_one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px);z-index:50}.anime .media>button.plus_one:hover{background:#888;color:hsla(0,0%,100%,.65)}.anime .media>button.plus_one:active{background:#444}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 22.4px);z-index:40}.manga .media>.edit_buttons button{border-color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons:hover button{background:#888;color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons button:active{background:#444}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search>.row{z-index:6}.big-check{display:none}.big-check:checked+label{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:150px;font-size:15rem;height:100%;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series_list article.media{position:relative}#series_list .name,#series_list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series_list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.description{max-width:800px;max-width:80rem}.fixed{max-width:930px;max-width:93rem}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>div{margin:1rem}.details .media_details{max-width:300px}.details .media_details td{padding:0 1.5rem}.details p{text-align:justify}.details .media_details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media_details td:nth-child(2n){text-align:left}.character,.small_character{height:350px;vertical-align:middle;white-space:nowrap;width:225px}.character:hover .name,.small_character:hover .name{background:rgba(0,0,0,.8)}.small_character a{display:inline-block;height:100%;width:100%}.character .name,.small_character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.small_character img{-webkit-transform:translateY(-50%);position:relative;top:50%;transform:translateY(-50%);width:100%;z-index:5}.min-table{margin-left:0;min-width:0}.small_character{height:250px;width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}.media{margin:2px 0}main{padding:0 .5rem .5rem}}.streaming-logo{height:50px;vertical-align:middle;width:50px}.cover_streaming_link{display:none}.media:hover .cover_streaming_link{display:block}.cover_streaming_link .streaming-logo{-webkit-filter:drop-shadow(0 -1px 4px #fff);filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{-ms-flex-align:center;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{-ms-flex-wrap:wrap;-webkit-box-shadow:0 48px 80px -32px rgba(0,0,0,.3);background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:-webkit-box;display:-ms-flexbox;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs label{-webkit-transition:background .1s,color .1s;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs label:hover{background:#d8d8d8}.tabs label:active{background:#ccc}.tabs [type=radio]:focus+label{-webkit-box-shadow:inset 0 0 0 3px #2aa1c0;box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs [type=radio]{opacity:0;position:absolute}.tabs [type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs [type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;display:block;padding:20px 30px 30px;width:100%}.tabs .content{display:none}@media (min-width:600px){.tabs label{width:auto}.tabs .content{-ms-flex-order:99;-webkit-box-ordinal-group:100;order:99}} \ No newline at end of file diff --git a/public/css/base.css b/public/css/base.css index 0a37b731..d4f7be51 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -605,6 +605,10 @@ a:hover, a:active { background-repeat: no-repeat; } +.media.search > .row { + z-index: 6; +} + .big-check { display: none; } diff --git a/public/js/scripts-authed.min.js b/public/js/scripts-authed.min.js index 56f6e886..042679e7 100644 --- a/public/js/scripts-authed.min.js +++ b/public/js/scripts-authed.min.js @@ -5,17 +5,18 @@ e.iteratorFromArray=function(c,f){e.initSymbolIterator();c instanceof String&&(c e.polyfill=function(c,f){if(f){var k=e.global;c=c.split(".");for(var g=0;g {\n\tlet matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),\n\t\ti = matches.length;\n\twhile (--i >= 0 && matches.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement(selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop() {\n\t\twindow.scroll(0,0);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide(sel) {\n\t\tsel.setAttribute('hidden', 'hidden');\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow(sel) {\n\t\tsel.removeAttribute('hidden');\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage(type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent(current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl(path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle(interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = function (sel, event, target, listener) {\n\tif (arguments.length === 3) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {void}\n */\nAnimeClient.ajax = function(url, config) {\n\t// Set some sane defaults\n\tconfig = config || {};\n\tconfig.data = config.data || {};\n\tconfig.type = config.type || 'GET';\n\tconfig.dataType = config.dataType || '';\n\tconfig.success = config.success || AnimeClient.noop;\n\tconfig.mimeType = config.mimeType || 'application/x-www-form-urlencoded';\n\tconfig.error = config.error || AnimeClient.noop;\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tswitch (method) {\n\t\tcase 'GET':\n\t\t\trequest.send(null);\n\t\tbreak;\n\n\t\tdefault:\n\t\t\trequest.send(config.data);\n\t\tbreak;\n\t}\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n */\nAnimeClient.get = function(url, data, callback = null) {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;"],"names":[],"mappings":"IAuBG,EAAU,CAAV;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/public/js/scripts.min.js.map b/public/js/scripts.min.js.map index dbc4bb95..043f0d43 100644 --- a/public/js/scripts.min.js.map +++ b/public/js/scripts.min.js.map @@ -1 +1 @@ -{"version":3,"file":"scripts.min.js.map","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"scripts.min.js.map","sources":["src/base/AnimeClient.js"],"sourcesContent":["// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),\n\t\ti = matches.length;\n\twhile (--i >= 0 && matches.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nexport const AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {object} [context]\n\t * @return {[HTMLElement]} - array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement(selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop() {\n\t\twindow.scroll(0,0);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide(sel) {\n\t\tsel.setAttribute('hidden', 'hidden');\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow(sel) {\n\t\tsel.removeAttribute('hidden');\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage(type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {HTMLElement} current - the current HTMLElement\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {HTMLElement|null} - the parent element\n\t */\n\tclosestParent(current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl(path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle(interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|HTMLElement} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|HTMLElement|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = function (sel, event, target, listener) {\n\tif (arguments.length === 3) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {void}\n */\nAnimeClient.ajax = function(url, config) {\n\t// Set some sane defaults\n\tconfig = config || {};\n\tconfig.data = config.data || {};\n\tconfig.type = config.type || 'GET';\n\tconfig.dataType = config.dataType || '';\n\tconfig.success = config.success || AnimeClient.noop;\n\tconfig.mimeType = config.mimeType || 'application/x-www-form-urlencoded';\n\tconfig.error = config.error || AnimeClient.noop;\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tswitch (method) {\n\t\tcase 'GET':\n\t\t\trequest.send(null);\n\t\tbreak;\n\n\t\tdefault:\n\t\t\trequest.send(config.data);\n\t\tbreak;\n\t}\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n */\nAnimeClient.get = function(url, data, callback = null) {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;"],"names":[],"mappings":"IAuBG,EAAU,CAAV;;;;;;;;;;;;"} \ No newline at end of file diff --git a/public/js/src/anime_edit.js b/public/js/src/anime.js similarity index 51% rename from public/js/src/anime_edit.js rename to public/js/src/anime.js index 47fec000..f15ff1cc 100644 --- a/public/js/src/anime_edit.js +++ b/public/js/src/anime.js @@ -1,14 +1,39 @@ -/** - * Javascript for editing anime, if logged in - */ -import _ from './base/AnimeClient'; +import _ from './base/AnimeClient' +import { renderAnimeSearchResults } from './template-helpers' + +const search = (query) => { + // Show the loader + _.$('.cssload-loader')[ 0 ].removeAttribute('hidden'); + + // Do the api search + _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => { + searchResults = JSON.parse(searchResults); + + // Hide the loader + _.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden'); + + // Show the results + _.$('#series_list')[ 0 ].innerHTML = renderAnimeSearchResults(searchResults.data); + }); +}; + +if (_.hasElement('.anime #search')) { + _.on('#search', 'keyup', _.throttle(250, function () { + const query = encodeURIComponent(this.value); + if (query === '') { + return; + } + + search(query); + })); +} // Action to increment episode count _.on('body.anime.list', 'click', '.plus_one', (e) => { let parentSel = _.closestParent(e.target, 'article'); - let watchedCount = parseInt(_.$('.completed_number', parentSel)[0].textContent, 10) || 0; - let totalCount = parseInt(_.$('.total_number', parentSel)[0].textContent, 10); - let title = _.$('.name a', parentSel)[0].textContent; + let watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0; + let totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10); + let title = _.$('.name a', parentSel)[ 0 ].textContent; // Setup the update data let data = { @@ -26,11 +51,11 @@ _.on('body.anime.list', 'click', '.plus_one', (e) => { } // If you increment at the last episode, mark as completed - if (( ! isNaN(watchedCount)) && (watchedCount + 1) === totalCount) { + if ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) { data.data.status = 'completed'; } - _.show(_.$('#loading-shadow')[0]); + _.show(_.$('#loading-shadow')[ 0 ]); // okay, lets actually make some changes! _.ajax(_.url('/anime/update'), { @@ -51,16 +76,16 @@ _.on('body.anime.list', 'click', '.plus_one', (e) => { _.hide(parentSel); } - _.hide(_.$('#loading-shadow')[0]); + _.hide(_.$('#loading-shadow')[ 0 ]); _.showMessage('success', `Successfully updated ${title}`); - _.$('.completed_number', parentSel)[0].textContent = ++watchedCount; + _.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount; _.scrollToTop(); }, error: (xhr, errorType, error) => { - _.hide(_.$('#loading-shadow')[0]); + _.hide(_.$('#loading-shadow')[ 0 ]); _.showMessage('error', `Failed to update ${title}. `); _.scrollToTop(); } }); -}); +}); \ No newline at end of file diff --git a/public/js/src/anime_collection.js b/public/js/src/anime_collection.js deleted file mode 100644 index e3e79ed2..00000000 --- a/public/js/src/anime_collection.js +++ /dev/null @@ -1,30 +0,0 @@ -import _ from './base/AnimeClient'; -import { render_anime_search_results } from './anime_search_results'; - -const search = (query) => { - // Show the loader - _.$('.cssload-loader')[ 0 ].removeAttribute('hidden'); - - // Do the api search - _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => { - searchResults = JSON.parse(searchResults); - - // Hide the loader - _.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden'); - - // Show the results - _.$('#series_list')[ 0 ].innerHTML = render_anime_search_results(searchResults.data); - }); -}; - - -if (_.hasElement('.anime #search')) { - _.on('#search', 'keyup', _.throttle(250, function () { - const query = encodeURIComponent(this.value); - if (query === '') { - return; - } - - search(query); - })); -} diff --git a/public/js/src/anime_search_results.js b/public/js/src/anime_search_results.js deleted file mode 100644 index d0614117..00000000 --- a/public/js/src/anime_search_results.js +++ /dev/null @@ -1,27 +0,0 @@ -export function render_anime_search_results (data) { - const results = []; - - data.forEach(x => { - const item = x.attributes; - const titles = item.titles.reduce((prev, current) => { - return prev + `${current}
`; - }, []); - - results.push(` - - `); - }); - - return results.join(''); -} \ No newline at end of file diff --git a/public/js/src/base/AnimeClient.js b/public/js/src/base/AnimeClient.js index 89e75735..07da0a5b 100644 --- a/public/js/src/base/AnimeClient.js +++ b/public/js/src/base/AnimeClient.js @@ -5,7 +5,7 @@ const matches = (elm, selector) => { let matches = (elm.document || elm.ownerDocument).querySelectorAll(selector), i = matches.length; - while (--i >= 0 && matches.item(i) !== elm); + while (--i >= 0 && matches.item(i) !== elm) {}; return i > -1; } diff --git a/public/js/src/base/sort_tables.js b/public/js/src/base/sort_tables.js index ebe20047..dc48809a 100644 --- a/public/js/src/base/sort_tables.js +++ b/public/js/src/base/sort_tables.js @@ -2,9 +2,7 @@ const LightTableSorter = (() => { let th = null; let cellIndex = null; let order = ''; - const text = (row) => { - return row.cells.item(cellIndex).textContent.toLowerCase(); - }; + const text = (row) => row.cells.item(cellIndex).textContent.toLowerCase(); const sort = (a, b) => { let textA = text(a); let textB = text(b); diff --git a/public/js/src/index-authed.js b/public/js/src/index-authed.js index b114713d..4235adfe 100644 --- a/public/js/src/index-authed.js +++ b/public/js/src/index-authed.js @@ -1,7 +1,4 @@ import './index'; -import './anime_collection'; -import './anime_edit'; - -import './manga_collection'; -import './manga_edit'; +import './anime'; +import './manga'; diff --git a/public/js/src/manga.js b/public/js/src/manga.js new file mode 100644 index 00000000..c69ce5d6 --- /dev/null +++ b/public/js/src/manga.js @@ -0,0 +1,86 @@ +import _ from './base/AnimeClient' +import { renderMangaSearchResults } from './template-helpers' + +const search = (query) => { + _.$('.cssload-loader')[ 0 ].removeAttribute('hidden'); + _.get(_.url('/manga/search'), { query }, (searchResults, status) => { + searchResults = JSON.parse(searchResults); + _.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden'); + _.$('#series_list')[ 0 ].innerHTML = renderMangaSearchResults(searchResults.data); + }); +}; + +if (_.hasElement('.manga #search')) { + _.on('#search', 'keyup', _.throttle(250, function (e) { + let query = encodeURIComponent(this.value); + if (query === '') { + return; + } + + search(query); + })); +} + +/** + * Javascript for editing manga, if logged in + */ +_.on('.manga.list', 'click', '.edit_buttons button', (e) => { + let thisSel = e.target; + let parentSel = _.closestParent(e.target, 'article'); + let type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume'; + let completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0; + let total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10); + let mangaName = _.$('.name', parentSel)[ 0 ].textContent; + + if (isNaN(completed)) { + completed = 0; + } + + // Setup the update data + let data = { + id: parentSel.dataset.kitsuId, + mal_id: parentSel.dataset.malId, + data: { + progress: completed + } + }; + + // If the episode count is 0, and incremented, + // change status to currently reading + if (isNaN(completed) || completed === 0) { + data.data.status = 'current'; + } + + // If you increment at the last chapter, mark as completed + if ((!isNaN(completed)) && (completed + 1) === total) { + data.data.status = 'completed'; + } + + // Update the total count + data.data.progress = ++completed; + + _.show(_.$('#loading-shadow')[ 0 ]); + + _.ajax(_.url('/manga/update'), { + data, + dataType: 'json', + type: 'POST', + mimeType: 'application/json', + success: () => { + if (data.data.status === 'completed') { + _.hide(parentSel); + } + + _.hide(_.$('#loading-shadow')[ 0 ]); + + _.$(`.${type}s_read`, parentSel)[ 0 ].textContent = completed; + _.showMessage('success', `Successfully updated ${mangaName}`); + _.scrollToTop(); + }, + error: () => { + _.hide(_.$('#loading-shadow')[ 0 ]); + _.showMessage('error', `Failed to update ${mangaName}`); + _.scrollToTop(); + } + }); +}); \ No newline at end of file diff --git a/public/js/src/manga_collection.js b/public/js/src/manga_collection.js deleted file mode 100644 index a736795f..00000000 --- a/public/js/src/manga_collection.js +++ /dev/null @@ -1,24 +0,0 @@ -import _ from './base/AnimeClient'; -import { render_manga_search_results } from './manga_search_results' - -const search = (query) => { - _.$('.cssload-loader')[0].removeAttribute('hidden'); - _.get(_.url('/manga/search'), {query}, (searchResults, status) => { - searchResults = JSON.parse(searchResults); - _.$('.cssload-loader')[0].setAttribute('hidden', 'hidden'); - _.$('#series_list')[0].innerHTML = render_manga_search_results(searchResults.data); - }); -}; - -if (_.hasElement('.manga #search')) { - _.on('#search', 'keyup', _.throttle(250, function (e) { - let query = encodeURIComponent(this.value); - if (query === '') { - return; - } - - search(query); - })); -} - - diff --git a/public/js/src/manga_edit.js b/public/js/src/manga_edit.js deleted file mode 100644 index 80f7bd55..00000000 --- a/public/js/src/manga_edit.js +++ /dev/null @@ -1,64 +0,0 @@ -import _ from './base/AnimeClient'; -/** - * Javascript for editing manga, if logged in - */ -_.on('.manga.list', 'click', '.edit_buttons button', (e) => { - let thisSel = e.target; - let parentSel = _.closestParent(e.target, 'article'); - let type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume'; - let completed = parseInt(_.$(`.${type}s_read`, parentSel)[0].textContent, 10) || 0; - let total = parseInt(_.$(`.${type}_count`, parentSel)[0].textContent, 10); - let mangaName = _.$('.name', parentSel)[0].textContent; - - if (isNaN(completed)) { - completed = 0; - } - - // Setup the update data - let data = { - id: parentSel.dataset.kitsuId, - mal_id: parentSel.dataset.malId, - data: { - progress: completed - } - }; - - // If the episode count is 0, and incremented, - // change status to currently reading - if (isNaN(completed) || completed === 0) { - data.data.status = 'current'; - } - - // If you increment at the last chapter, mark as completed - if (( ! isNaN(completed)) && (completed + 1) === total) { - data.data.status = 'completed'; - } - - // Update the total count - data.data.progress = ++completed; - - _.show(_.$('#loading-shadow')[0]); - - _.ajax(_.url('/manga/update'), { - data, - dataType: 'json', - type: 'POST', - mimeType: 'application/json', - success: () => { - if (data.data.status === 'completed') { - _.hide(parentSel); - } - - _.hide(_.$('#loading-shadow')[0]); - - _.$(`.${type}s_read`, parentSel)[0].textContent = completed; - _.showMessage('success', `Sucessfully updated ${mangaName}`); - _.scrollToTop(); - }, - error: () => { - _.hide(_.$('#loading-shadow')[0]); - _.showMessage('error', `Failed to update ${mangaName}`); - _.scrollToTop(); - } - }); -}); diff --git a/public/js/src/manga_search_results.js b/public/js/src/manga_search_results.js deleted file mode 100644 index 80f56fb3..00000000 --- a/public/js/src/manga_search_results.js +++ /dev/null @@ -1,27 +0,0 @@ -export function render_manga_search_results (data) { - const results = []; - - data.forEach(x => { - const item = x.attributes; - const titles = item.titles.reduce((prev, current) => { - return prev + `${current}
`; - }, []); - - results.push(` - - `); - }); - - return results.join(''); -} diff --git a/public/js/src/template-helpers.js b/public/js/src/template-helpers.js new file mode 100644 index 00000000..5f0cabb7 --- /dev/null +++ b/public/js/src/template-helpers.js @@ -0,0 +1,69 @@ +export function renderAnimeSearchResults (data) { + const results = []; + + data.forEach(x => { + const item = x.attributes; + const titles = item.titles.reduce((prev, current) => { + return prev + `${current}
`; + }, []); + + results.push(` + + `); + }); + + return results.join(''); +} + +export function renderMangaSearchResults (data) { + const results = []; + + data.forEach(x => { + const item = x.attributes; + const titles = item.titles.reduce((prev, current) => { + return prev + `${current}
`; + }, []); + + results.push(` + + `); + }); + + return results.join(''); +} \ No newline at end of file diff --git a/public/js/tables.min.js.map b/public/js/tables.min.js.map index 5018bd1c..bc650aee 100644 --- a/public/js/tables.min.js.map +++ b/public/js/tables.min.js.map @@ -1 +1 @@ -{"version":3,"file":"tables.min.js.map","sources":["src/base/sort_tables.js"],"sourcesContent":["const LightTableSorter = (() => {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => {\n\t\treturn row.cells.item(cellIndex).textContent.toLowerCase();\n\t};\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconst n = parseInt(textA, 10);\n\t\tif (n) {\n\t\t\ttextA = n;\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting_asc' ? 'sorting_asc' : 'sorting_desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting_asc', 'sorting_desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting_asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"IAsBG,GAAA;;;;;;"} \ No newline at end of file +{"version":3,"file":"tables.min.js.map","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"} \ No newline at end of file