mirror of
https://github.com/LalleSX/4chan-XZ.git
synced 2026-01-30 09:48:12 +01:00
More types!
This commit is contained in:
parent
12483e97c5
commit
fbc329add3
@ -1,16 +1,20 @@
|
||||
import { Conf, g } from '../globals/globals'
|
||||
import $ from '../platform/$'
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
var Get = {
|
||||
import type Thread from '../classes/Thread'
|
||||
import type Post from '../classes/Post'
|
||||
interface Get {
|
||||
url(type: any, IDs: { siteID: string }, ...args: any[]): string | undefined
|
||||
threadExcerpt(thread: Thread): string
|
||||
threadFromRoot(root: HTMLElement): Thread | null
|
||||
threadFromNode(node: HTMLElement): Thread | null
|
||||
postFromRoot(root: HTMLElement): Post | null
|
||||
postFromNode(root: HTMLElement): Post | null
|
||||
allQuotelinksLinkingTo(post: Post): HTMLAnchorElement[]
|
||||
postDataFromLink(link: HTMLAnchorElement): { boardID: string; postID: number }
|
||||
}
|
||||
var Get: Get = {
|
||||
url(type, IDs, ...args) {
|
||||
let f, site
|
||||
let f: ((IDs: { siteID: string }, ...args: any[]) => string) | undefined, site: typeof g.sites[0]
|
||||
if ((site = g.sites[IDs.siteID]) && (f = $.getOwn(site.urls, type))) {
|
||||
return f(IDs, ...Array.from(args))
|
||||
} else {
|
||||
@ -43,7 +47,7 @@ var Get = {
|
||||
},
|
||||
threadFromNode(node) {
|
||||
return Get.threadFromRoot(
|
||||
$.x(`ancestor-or-self::${g.SITE.xpath.thread}`, node),
|
||||
$.x(`ancestor-or-self::${g.SITE.xpath.threadContainer}[1]`, node)[0],
|
||||
)
|
||||
},
|
||||
postFromRoot(root) {
|
||||
@ -60,20 +64,23 @@ var Get = {
|
||||
},
|
||||
postFromNode(root) {
|
||||
return Get.postFromRoot(
|
||||
$.x(`ancestor-or-self::${g.SITE.xpath.postContainer}[1]`, root),
|
||||
$.x(`ancestor-or-self::${g.SITE.xpath.postContainer}`, root)[0],
|
||||
)
|
||||
},
|
||||
postDataFromLink(link) {
|
||||
let boardID, postID, threadID
|
||||
if (link.dataset.postID) {
|
||||
postDataFromLink(link: any) {
|
||||
let boardID: any, postID: any, threadID: any
|
||||
if (link.dataset?.postID) {
|
||||
// resurrected quote
|
||||
;({ boardID, threadID, postID } = link.dataset)
|
||||
({ boardID, threadID, postID } = link.dataset)
|
||||
if (!threadID) {
|
||||
threadID = 0
|
||||
threadID = '0'
|
||||
}
|
||||
} else {
|
||||
const match = link.href.match(g.SITE.regexp.quotelink)
|
||||
;[boardID, threadID, postID] = Array.from(match.slice(1))
|
||||
const match = link.href.match(g?.SITE?.regexp?.quotelink)
|
||||
if (!match) {
|
||||
throw new Error('Invalid link')
|
||||
}
|
||||
[boardID, threadID, postID] = match.slice(1)
|
||||
if (!postID) {
|
||||
postID = threadID
|
||||
}
|
||||
@ -83,7 +90,7 @@ var Get = {
|
||||
threadID: +threadID,
|
||||
postID: +postID,
|
||||
}
|
||||
},
|
||||
},
|
||||
allQuotelinksLinkingTo(post) {
|
||||
// Get quotelinks & backlinks linking to the given post.
|
||||
const quotelinks = []
|
||||
@ -1,37 +0,0 @@
|
||||
import BoardConfig from '../General/BoardConfig'
|
||||
import { d, g } from '../globals/globals'
|
||||
import SimpleDict from './SimpleDict'
|
||||
|
||||
export default class Board {
|
||||
toString() {
|
||||
return this.ID
|
||||
}
|
||||
|
||||
constructor(ID) {
|
||||
this.ID = ID
|
||||
this.boardID = this.ID
|
||||
this.siteID = g.SITE.ID
|
||||
this.threads = new SimpleDict()
|
||||
this.posts = new SimpleDict()
|
||||
this.config = BoardConfig.boards?.[this.ID] || {}
|
||||
|
||||
g.boards[this.ID] = this
|
||||
}
|
||||
|
||||
cooldowns() {
|
||||
const c2 = (this.config || {}).cooldowns || {}
|
||||
const c = {
|
||||
thread: c2.threads || 0,
|
||||
reply: c2.replies || 0,
|
||||
image: c2.images || 0,
|
||||
thread_global: 300, // inter-board thread cooldown
|
||||
}
|
||||
// Pass users have reduced cooldowns.
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
for (var key of ['reply', 'image']) {
|
||||
c[key] = Math.ceil(c[key] / 2)
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
}
|
||||
46
src/classes/Board.ts
Normal file
46
src/classes/Board.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import BoardConfig from '../General/BoardConfig';
|
||||
import { d, g } from '../globals/globals';
|
||||
import Post from './Post';
|
||||
import Thread from './Thread';
|
||||
import SimpleDict from './SimpleDict';
|
||||
|
||||
export default class Board {
|
||||
ID: string;
|
||||
boardID: string;
|
||||
siteID: string;
|
||||
threads: SimpleDict<Thread>;
|
||||
posts: SimpleDict<Post>;
|
||||
config: any;
|
||||
|
||||
constructor(ID: string) {
|
||||
this.ID = ID;
|
||||
this.boardID = this.ID;
|
||||
this.siteID = g.SITE.ID;
|
||||
this.threads = new SimpleDict();
|
||||
this.posts = new SimpleDict();
|
||||
this.config = BoardConfig.domain(this.ID)
|
||||
|
||||
g.boards[this.ID] = this;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.ID;
|
||||
}
|
||||
|
||||
cooldowns() {
|
||||
const c2 = (this.config || {}).cooldowns || {};
|
||||
const c = {
|
||||
thread: c2.threads || 0,
|
||||
reply: c2.replies || 0,
|
||||
image: c2.images || 0,
|
||||
thread_global: 300, // inter-board thread cooldown
|
||||
};
|
||||
// Pass users have reduced cooldowns.
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
for (let key of ['reply', 'image']) {
|
||||
c[key] = Math.ceil(c[key] / 2);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
import Main from '../main/Main'
|
||||
|
||||
export default class Callbacks {
|
||||
static initClass() {
|
||||
this.Post = new Callbacks('Post')
|
||||
this.Thread = new Callbacks('Thread')
|
||||
this.CatalogThread = new Callbacks('Catalog Thread')
|
||||
this.CatalogThreadNative = new Callbacks('Catalog Thread')
|
||||
}
|
||||
|
||||
constructor(type) {
|
||||
this.type = type
|
||||
this.keys = []
|
||||
}
|
||||
|
||||
push({ name, cb }) {
|
||||
if (!this[name]) {
|
||||
this.keys.push(name)
|
||||
}
|
||||
return (this[name] = cb)
|
||||
}
|
||||
|
||||
execute(node, keys = this.keys, force = false) {
|
||||
let errors
|
||||
if (node.callbacksExecuted && !force) {
|
||||
return
|
||||
}
|
||||
node.callbacksExecuted = true
|
||||
for (var name of keys) {
|
||||
try {
|
||||
this[name]?.call(node)
|
||||
} catch (err) {
|
||||
if (!errors) {
|
||||
errors = []
|
||||
}
|
||||
errors.push({
|
||||
message: [
|
||||
'"',
|
||||
name,
|
||||
'" crashed on node ',
|
||||
this.type,
|
||||
' No.',
|
||||
node.ID,
|
||||
' (',
|
||||
node.board,
|
||||
').',
|
||||
].join(''),
|
||||
error: err,
|
||||
html: node.nodes?.root?.outerHTML,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (errors) {
|
||||
return Main.handleErrors(errors)
|
||||
}
|
||||
}
|
||||
}
|
||||
Callbacks.initClass()
|
||||
68
src/classes/Callbacks.ts
Normal file
68
src/classes/Callbacks.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import Main from '../main/Main';
|
||||
|
||||
export default class Callbacks {
|
||||
private type: string;
|
||||
private keys: string[];
|
||||
|
||||
static Post: Callbacks;
|
||||
static Thread: Callbacks;
|
||||
static CatalogThread: Callbacks;
|
||||
static CatalogThreadNative: Callbacks;
|
||||
|
||||
static initClass() {
|
||||
this.Post = new Callbacks('Post');
|
||||
this.Thread = new Callbacks('Thread');
|
||||
this.CatalogThread = new Callbacks('Catalog Thread');
|
||||
this.CatalogThreadNative = new Callbacks('Catalog Thread');
|
||||
}
|
||||
|
||||
constructor(type: string) {
|
||||
this.type = type;
|
||||
this.keys = [];
|
||||
}
|
||||
|
||||
push({ name, cb }: { name: string; cb: () => void }) {
|
||||
if (!this[name]) {
|
||||
this.keys.push(name);
|
||||
}
|
||||
return (this[name] = cb);
|
||||
}
|
||||
|
||||
execute(node: any, keys = this.keys, force = false) {
|
||||
let errors: any[];
|
||||
if (node.callbacksExecuted && !force) {
|
||||
return;
|
||||
}
|
||||
node.callbacksExecuted = true;
|
||||
for (let name of keys) {
|
||||
try {
|
||||
this[name]?.call(node);
|
||||
} catch (err: any) {
|
||||
if (!errors) {
|
||||
errors = [];
|
||||
}
|
||||
errors.push({
|
||||
message: [
|
||||
'"',
|
||||
name,
|
||||
'" crashed on node ',
|
||||
this.type,
|
||||
' No.',
|
||||
node.ID,
|
||||
' (',
|
||||
node.board,
|
||||
').',
|
||||
].join(''),
|
||||
error: err,
|
||||
html: node.nodes?.root?.outerHTML,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (errors) {
|
||||
return Main.handleErrors(errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Callbacks.initClass();
|
||||
@ -1,6 +1,7 @@
|
||||
import SimpleDict from './SimpleDict'
|
||||
import $ from '../platform/$'
|
||||
import { g } from '../globals/globals'
|
||||
import Post from './Post'
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
@ -8,15 +9,35 @@ import { g } from '../globals/globals'
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
export default class Thread {
|
||||
board: string
|
||||
ID: number
|
||||
threadID: number
|
||||
boardID: string
|
||||
siteID: string
|
||||
fullID: string
|
||||
posts: SimpleDict<Post>
|
||||
isDead: boolean
|
||||
isHidden: boolean
|
||||
isSticky: boolean
|
||||
isClosed: boolean
|
||||
isArchived: boolean
|
||||
postLimit: boolean
|
||||
fileLimit: boolean
|
||||
lastPost: number
|
||||
ipCount: undefined
|
||||
json: null | any
|
||||
OP: null | Post
|
||||
catalogView: null | any
|
||||
nodes: { root: null | HTMLElement }
|
||||
toString() {
|
||||
return this.ID
|
||||
}
|
||||
|
||||
constructor(ID, board) {
|
||||
constructor(ID: string, board: string) {
|
||||
this.board = board
|
||||
this.ID = +ID
|
||||
this.threadID = this.ID
|
||||
this.boardID = this.board.ID
|
||||
this.boardID = g.BOARD.ID
|
||||
this.siteID = g.SITE.ID
|
||||
this.fullID = `${this.board}.${this.ID}`
|
||||
this.posts = new SimpleDict()
|
||||
@ -40,8 +61,8 @@ export default class Thread {
|
||||
g.threads.push(this.fullID, this)
|
||||
}
|
||||
|
||||
setPage(pageNum) {
|
||||
let icon
|
||||
setPage(pageNum: number): void {
|
||||
let icon: HTMLElement | null
|
||||
const { info, reply } = this.OP.nodes
|
||||
if (!(icon = $('.page-num', info))) {
|
||||
icon = $.el('span', { className: 'page-num' })
|
||||
@ -54,7 +75,7 @@ export default class Thread {
|
||||
}
|
||||
}
|
||||
|
||||
setCount(type, count, reachedLimit) {
|
||||
setCount(type: string, count: number, reachedLimit: boolean): void {
|
||||
if (!this.catalogView) {
|
||||
return
|
||||
}
|
||||
@ -63,7 +84,7 @@ export default class Thread {
|
||||
return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning')
|
||||
}
|
||||
|
||||
setStatus(type, status) {
|
||||
setStatus(type: string, status: boolean): void {
|
||||
const name = `is${type}`
|
||||
if (this[name] === status) {
|
||||
return
|
||||
@ -77,7 +98,7 @@ export default class Thread {
|
||||
return this.setIcon('Archived', this.isArchived)
|
||||
}
|
||||
|
||||
setIcon(type, status) {
|
||||
setIcon(type: string, status: boolean): void {
|
||||
const typeLC = type.toLowerCase()
|
||||
let icon = $(`.${typeLC}Icon`, this.OP.nodes.info)
|
||||
if (!!icon === status) {
|
||||
@ -117,11 +138,11 @@ export default class Thread {
|
||||
)
|
||||
}
|
||||
|
||||
kill() {
|
||||
kill(): boolean {
|
||||
return (this.isDead = true)
|
||||
}
|
||||
|
||||
collect() {
|
||||
collect(): boolean {
|
||||
let n = 0
|
||||
this.posts.forEach(function (post) {
|
||||
if (post.clones.length) {
|
||||
@ -132,7 +153,7 @@ export default class Thread {
|
||||
})
|
||||
if (!n) {
|
||||
g.threads.rm(this.fullID)
|
||||
return this.board.threads.rm(this)
|
||||
return this.board.threads.rm(this.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user