├── src ├── skin.js ├── scss │ ├── skin.scss │ └── tamplate.scss ├── cache.js ├── template.js ├── modules │ ├── boot.js │ ├── detail.js │ ├── auth.js │ ├── album.js │ ├── log.js │ ├── hook-detail.js │ ├── head.js │ ├── clean.js │ ├── download.js │ ├── thank.js │ ├── cache.js │ ├── pass-data.js │ ├── button.js │ ├── direct-source.js │ ├── download-finish.js │ └── cover.js ├── status-bar.js ├── warning.js ├── direct-source.js ├── category.js ├── cover-next.js └── setting.js ├── dist ├── 4692b9ec53fd5972caa2.ttf ├── 5be1347c682810f199c7.eot ├── 82b1212e45a2bc35dd73.woff ├── be810be3a3e14c682a25.woff2 ├── cover-next.js.LICENSE.txt └── 060b2710bdbbe3dfe48b.svg ├── .gitignore ├── postcss.config.js ├── tailwind.config.js ├── .babelrc ├── README.md ├── package.json ├── webpack.config.js └── cover-next.user.js /src/skin.js: -------------------------------------------------------------------------------- 1 | import './scss/skin.scss'; 2 | -------------------------------------------------------------------------------- /dist/4692b9ec53fd5972caa2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kon3ko/cover-next/HEAD/dist/4692b9ec53fd5972caa2.ttf -------------------------------------------------------------------------------- /dist/5be1347c682810f199c7.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kon3ko/cover-next/HEAD/dist/5be1347c682810f199c7.eot -------------------------------------------------------------------------------- /dist/82b1212e45a2bc35dd73.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kon3ko/cover-next/HEAD/dist/82b1212e45a2bc35dd73.woff -------------------------------------------------------------------------------- /dist/be810be3a3e14c682a25.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kon3ko/cover-next/HEAD/dist/be810be3a3e14c682a25.woff2 -------------------------------------------------------------------------------- /src/scss/skin.scss: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/cache.js: -------------------------------------------------------------------------------- 1 | import BaseCache from "./modules/cache"; 2 | //cache 3 | const Cache = new BaseCache(); 4 | 5 | export default Cache; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/* 2 | .idea/* 3 | 4 | src/modules/cover-hook.js 5 | src/modules/server-cache.js 6 | src/modules/serial.js 7 | /src/modules/letter.js 8 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const tailwindcss = require('tailwindcss'); 2 | 3 | module.exports = { 4 | plugins: [ 5 | 'postcss-preset-env', 6 | tailwindcss, 7 | require('autoprefixer'), 8 | ], 9 | }; 10 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | corePlugins: { 9 | preflight: false, 10 | } 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@babel/syntax-dynamic-import", 4 | "@babel/plugin-transform-runtime" 5 | ], 6 | "presets": [ 7 | [ 8 | "@babel/preset-env", 9 | { 10 | "modules": false 11 | } 12 | ] 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/template.js: -------------------------------------------------------------------------------- 1 | import './scss/tamplate.scss'; 2 | import "@fancyapps/ui/dist/fancybox.css"; 3 | import Setting from "./setting"; 4 | 5 | //preview cover 6 | let previewCover = 'img.preview{max-height:' + Setting.previewMaxHeight + 'px;max-width:' + Setting.previewMaxWidth + 'px;}'; 7 | 8 | GM_addStyle(previewCover); -------------------------------------------------------------------------------- /src/modules/boot.js: -------------------------------------------------------------------------------- 1 | import Setting from "../setting"; 2 | import Log from "./log"; 3 | import Auth from "./auth"; 4 | 5 | class Boot { 6 | constructor() { 7 | Log('Boot loading...'); 8 | 9 | this.font(); 10 | 11 | Log('Boot Done'); 12 | } 13 | 14 | font() { 15 | Log('Font Change...'); 16 | 17 | if(Number.isInteger(parseInt(Setting.fontSize))){ 18 | Log('Font Size:', Setting.fontSize); 19 | 20 | $('body').css('font-size', Setting.fontSize + 'pt'); 21 | $('td').css('font-size', Setting.fontSize + 'pt'); 22 | } 23 | 24 | Log('Font Change Done'); 25 | } 26 | } 27 | 28 | export default Boot; 29 | -------------------------------------------------------------------------------- /src/modules/detail.js: -------------------------------------------------------------------------------- 1 | class Detail { 2 | id; 3 | html; 4 | table; 5 | 6 | constructor( { html, location } ) { 7 | this.html = html; 8 | this.table = $('table[width="80%"]', html); 9 | this.id = this.findId(location); 10 | } 11 | 12 | findId( location ) { 13 | let search; 14 | if (typeof location === "object") { 15 | search = location.search; 16 | } else { 17 | search = location.split("?")[ 1 ]; 18 | } 19 | 20 | const params = new URLSearchParams(search); 21 | let id = 0; 22 | for (const param of params) { 23 | if (param[ 0 ] === 'id') { 24 | id = param[ 1 ]; 25 | } 26 | } 27 | 28 | return id; 29 | } 30 | } 31 | 32 | export default Detail; -------------------------------------------------------------------------------- /src/modules/auth.js: -------------------------------------------------------------------------------- 1 | import Log from "./log"; 2 | 3 | class Auth { 4 | id; 5 | username; 6 | isPremium; 7 | 8 | constructor() { 9 | Log('Auth...'); 10 | 11 | this.detail(); 12 | this.isPremium = this.premium(); 13 | 14 | Log('username: ' + this.username); 15 | Log('id: ' + this.id); 16 | 17 | Log('Auth Done'); 18 | } 19 | 20 | detail() { 21 | const a = $('table.mainouter tr:nth-child(2):first td a[href^=\'userdetails.php\']'); 22 | this.username = a.text(); 23 | this.id = a.attr('href').replace('userdetails.php?id=', ''); 24 | } 25 | 26 | premium() { 27 | const a = $('table.mainouter tr:nth-child(2):first td'); 28 | 29 | return !!a.text().includes('Premium EXP.'); 30 | } 31 | } 32 | 33 | export default Auth; 34 | -------------------------------------------------------------------------------- /src/modules/album.js: -------------------------------------------------------------------------------- 1 | import {Fancybox} from "@fancyapps/ui"; 2 | import Setting from "../setting"; 3 | import Cache from "../cache"; 4 | 5 | class Album { 6 | rows; 7 | 8 | constructor( { rows } ) { 9 | this.rows = rows.filter(( { data } ) => !data.except); 10 | 11 | this.rows.map(( { data, cover }, index ) => { 12 | cover.preview.click(() => { 13 | new Fancybox(this.rows.map(( { data, button, cover : coverItem } ) => ({ 14 | src : coverItem.source ?? Setting.previewFail, 15 | type : 'image', 16 | caption : this.caption(data), 17 | })), { 18 | startIndex : index, 19 | click : null, 20 | infinite : false 21 | }); 22 | }); 23 | }); 24 | } 25 | 26 | caption( data ) { 27 | return ` 28 | ${data.title} 29 |
30 | 31 | ขนาด: ${data.size} | เสร็จ: ${data.downloaded} | ปล่อย: ${data.seed} | ดูด: ${data.peer} 32 | `; 33 | } 34 | 35 | } 36 | 37 | export default Album; -------------------------------------------------------------------------------- /src/modules/log.js: -------------------------------------------------------------------------------- 1 | import Setting from "../setting"; 2 | 3 | function getConsistentColorFrom3Chars(text) { 4 | // รับเฉพาะ 3 ตัวอักษรแรก 5 | text = text.slice(0, 4).padEnd(4, "0"); // ถ้าน้อยกว่า 3 ตัวให้เติม "0" 6 | 7 | // ใช้ hash function เพื่อให้สีที่ได้คงที่ 8 | let hash = 0; 9 | for (let i = 0; i < text.length; i++) { 10 | hash = text.charCodeAt(i) + ((hash << 5) - hash); // ฟังก์ชันแฮช 11 | } 12 | 13 | // แปลง hash เป็นค่า RGB โดยให้ค่ามีความหลากหลาย 14 | let r = (hash >> 16) & 0xff; // ค่าแดง 15 | let g = (hash >> 8) & 0xff; // ค่าสีเขียว 16 | let b = hash & 0xff; // ค่าสีน้ำเงิน 17 | 18 | // เพิ่มการสุ่มเพื่อให้มีความหลากหลายมากขึ้น แต่ยังคงให้สีเดิมถ้าใช้ข้อความเดิม 19 | r = (r + Math.floor(Math.random() * 50)) % 256; 20 | g = (g + Math.floor(Math.random() * 50)) % 256; 21 | b = (b + Math.floor(Math.random() * 50)) % 256; 22 | 23 | // แปลงเป็น HEX 24 | const color = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`; 25 | 26 | return color; 27 | } 28 | 29 | function Log( index, message ) { 30 | if(Setting.debug || process.env.NODE_ENV === 'development'){ 31 | 32 | const color = getConsistentColorFrom3Chars(index); 33 | if (message === undefined) { 34 | if (index.charAt(0) === index.charAt(0).toUpperCase()) 35 | index = `#### ${index} ####`; 36 | console.log(`%c${index}`, `color:${color};`); 37 | } else { 38 | console.log(`%c#${index} ${message}`, `color:${color};`); 39 | } 40 | } 41 | } 42 | 43 | export default Log; 44 | -------------------------------------------------------------------------------- /src/modules/hook-detail.js: -------------------------------------------------------------------------------- 1 | import Log from "./log"; 2 | 3 | class HookDetail { 4 | data; 5 | hook = []; 6 | 7 | constructor( { data, hook } ) { 8 | this.data = data; 9 | this.hook = hook; 10 | 11 | Log('Register hook'); 12 | } 13 | 14 | async detail() { 15 | Log('Hook detail'); 16 | 17 | let handler = await this.frame(); 18 | 19 | //hook 20 | const promises = this.hook.map(async ( { callback, self } ) => { 21 | return await callback({ 22 | handler : handler, 23 | html : handler.target.contentDocument, 24 | self : self, 25 | }); 26 | }); 27 | await Promise.all(promises); 28 | 29 | return handler.target.contentDocument; 30 | } 31 | 32 | async frame( callback ) { 33 | return await new Promise(resolve => { 34 | Log('Frame creating...'); 35 | 36 | //create frame 37 | let frame = $('