mirror of
https://github.com/venera-app/venera-configs.git
synced 2025-09-27 00:27:23 +00:00
update template & add picacg
This commit is contained in:
626
_template_.js
Normal file
626
_template_.js
Normal file
@@ -0,0 +1,626 @@
|
||||
class NewComicSource extends ComicSource {
|
||||
// Note: The fields which are marked as [Optional] should be removed if not used
|
||||
|
||||
// name of the source
|
||||
name = ""
|
||||
|
||||
// unique id of the source
|
||||
key = ""
|
||||
|
||||
version = "1.0.0"
|
||||
|
||||
minAppVersion = "1.0.0"
|
||||
|
||||
// update url
|
||||
url = ""
|
||||
|
||||
/**
|
||||
* [Optional] init function
|
||||
*/
|
||||
init() {
|
||||
|
||||
}
|
||||
|
||||
// [Optional] account related
|
||||
account = {
|
||||
/**
|
||||
* login, return any value to indicate success
|
||||
* @param account {string}
|
||||
* @param pwd {string}
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
login: async (account, pwd) => {
|
||||
/*
|
||||
Use Network to send request
|
||||
Use this.saveData to save data
|
||||
`account` and `pwd` will be saved to local storage automatically if login success
|
||||
```
|
||||
let res = await Network.post('https://example.com/login', {
|
||||
'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
|
||||
}, `account=${account}&password=${pwd}`)
|
||||
|
||||
if(res.status == 200) {
|
||||
let json = JSON.parse(res.body)
|
||||
this.saveData('token', json.token)
|
||||
return 'ok'
|
||||
}
|
||||
|
||||
throw 'Failed to login'
|
||||
```
|
||||
*/
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* logout function, clear account related data
|
||||
*/
|
||||
logout: () => {
|
||||
/*
|
||||
```
|
||||
this.deleteData('token')
|
||||
Network.deleteCookies('https://example.com')
|
||||
```
|
||||
*/
|
||||
},
|
||||
|
||||
// {string?} - register url
|
||||
registerWebsite: null
|
||||
}
|
||||
|
||||
// explore page list
|
||||
explore = [
|
||||
{
|
||||
// title of the page.
|
||||
// title is used to identify the page, it should be unique
|
||||
title: "",
|
||||
|
||||
/// singlePageWithMultiPart or multiPageComicList
|
||||
type: "singlePageWithMultiPart",
|
||||
|
||||
/**
|
||||
* load function
|
||||
* @param page {number | null} - page number, null for `singlePageWithMultiPart` type
|
||||
* @returns {{}} - for `singlePageWithMultiPart` type, return {[string]: Comic[]}; for `multiPageComicList` type, return {comics: Comic[], maxPage: number}
|
||||
*/
|
||||
load: async (page) => {
|
||||
/*
|
||||
```
|
||||
let res = await Network.get("https://example.com")
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw `Invalid status code: ${res.status}`
|
||||
}
|
||||
|
||||
let data = JSON.parse(res.body)
|
||||
|
||||
function parseComic(comic) {
|
||||
// ...
|
||||
|
||||
return new Comic({
|
||||
id: id,
|
||||
title: title,
|
||||
subTitle: author,
|
||||
cover: cover,
|
||||
tags: tags,
|
||||
description: description
|
||||
})
|
||||
}
|
||||
|
||||
let comics = {}
|
||||
comics["hot"] = data["results"]["recComics"].map(parseComic)
|
||||
comics["latest"] = data["results"]["newComics"].map(parseComic)
|
||||
|
||||
return comics
|
||||
```
|
||||
*/
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// categories
|
||||
category = {
|
||||
/// title of the category page, used to identify the page, it should be unique
|
||||
title: "",
|
||||
parts: [
|
||||
{
|
||||
// title of the part
|
||||
name: "Theme",
|
||||
|
||||
// fixed or random
|
||||
// if random, need to provide `randomNumber` field, which indicates the number of comics to display at the same time
|
||||
type: "fixed",
|
||||
|
||||
// number of comics to display at the same time
|
||||
// randomNumber: 5,
|
||||
|
||||
categories: ["All", "Adventure", "School"],
|
||||
|
||||
// category or search
|
||||
// if `category`, use categoryComics.load to load comics
|
||||
// if `search`, use search.load to load comics
|
||||
itemType: "category",
|
||||
|
||||
// [Optional] must have same length as categories, used to provide loading param for each category
|
||||
categoryParams: ["all", "adventure", "school"]
|
||||
}
|
||||
],
|
||||
// enable ranking page
|
||||
enableRankingPage: false,
|
||||
}
|
||||
|
||||
/// category comic loading related
|
||||
categoryComics = {
|
||||
/**
|
||||
* load comics of a category
|
||||
* @param category {string} - category name
|
||||
* @param param {string?} - category param
|
||||
* @param options {string[]} - options from optionList
|
||||
* @param page {number} - page number
|
||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||
*/
|
||||
load: async (category, param, options, page) => {
|
||||
/*
|
||||
```
|
||||
let data = JSON.parse((await Network.get('...')).body)
|
||||
let maxPage = data.maxPage
|
||||
|
||||
function parseComic(comic) {
|
||||
// ...
|
||||
|
||||
return new Comic({
|
||||
id: id,
|
||||
title: title,
|
||||
subTitle: author,
|
||||
cover: cover,
|
||||
tags: tags,
|
||||
description: description
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
comics: data.list.map(parseComic),
|
||||
maxPage: maxPage
|
||||
}
|
||||
```
|
||||
*/
|
||||
},
|
||||
// provide options for category comic loading
|
||||
optionList: [
|
||||
{
|
||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||
options: [
|
||||
"newToOld-New to Old",
|
||||
"oldToNew-Old to New"
|
||||
],
|
||||
// [Optional] {string[]} - show this option only when the value not in the list
|
||||
notShowWhen: null,
|
||||
// [Optional] {string[]} - show this option only when the value in the list
|
||||
showWhen: null
|
||||
}
|
||||
],
|
||||
ranking: {
|
||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||
options: [
|
||||
"day-Day",
|
||||
"week-Week"
|
||||
],
|
||||
/**
|
||||
* load ranking comics
|
||||
* @param option {string} - option from optionList
|
||||
* @param page {number} - page number
|
||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||
*/
|
||||
load: async (option, page) => {
|
||||
/*
|
||||
```
|
||||
let data = JSON.parse((await Network.get('...')).body)
|
||||
let maxPage = data.maxPage
|
||||
|
||||
function parseComic(comic) {
|
||||
// ...
|
||||
|
||||
return new Comic({
|
||||
id: id,
|
||||
title: title,
|
||||
subTitle: author,
|
||||
cover: cover,
|
||||
tags: tags,
|
||||
description: description
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
comics: data.list.map(parseComic),
|
||||
maxPage: maxPage
|
||||
}
|
||||
```
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// search related
|
||||
search = {
|
||||
/**
|
||||
* load search result
|
||||
* @param keyword {string}
|
||||
* @param options {string[]} - options from optionList
|
||||
* @param page {number}
|
||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||
*/
|
||||
load: async (keyword, options, page) => {
|
||||
/*
|
||||
```
|
||||
let data = JSON.parse((await Network.get('...')).body)
|
||||
let maxPage = data.maxPage
|
||||
|
||||
function parseComic(comic) {
|
||||
// ...
|
||||
|
||||
return new Comic({
|
||||
id: id,
|
||||
title: title,
|
||||
subTitle: author,
|
||||
cover: cover,
|
||||
tags: tags,
|
||||
description: description
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
comics: data.list.map(parseComic),
|
||||
maxPage: maxPage
|
||||
}
|
||||
```
|
||||
*/
|
||||
},
|
||||
|
||||
// provide options for search
|
||||
optionList: [
|
||||
{
|
||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||
options: [
|
||||
"0-time",
|
||||
"1-popular"
|
||||
],
|
||||
// option label
|
||||
label: "sort"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// favorite related
|
||||
favorites = {
|
||||
// whether support multi folders
|
||||
multiFolder: false,
|
||||
/**
|
||||
* add or delete favorite.
|
||||
* throw `Login expired` to indicate login expired, App will automatically re-login and re-add/delete favorite
|
||||
* @param comicId {string}
|
||||
* @param folderId {string}
|
||||
* @param isAdding {boolean} - true for add, false for delete
|
||||
* @returns {Promise<any>} - return any value to indicate success
|
||||
*/
|
||||
addOrDelFavorite: async (comicId, folderId, isAdding) => {
|
||||
/*
|
||||
```
|
||||
let res = await Network.post('...')
|
||||
if (res.status === 401) {
|
||||
throw `Login expired`;
|
||||
}
|
||||
return 'ok'
|
||||
```
|
||||
*/
|
||||
},
|
||||
/**
|
||||
* load favorite folders.
|
||||
* throw `Login expired` to indicate login expired, App will automatically re-login retry.
|
||||
* if comicId is not null, return favorite folders which contains the comic.
|
||||
* @param comicId {string?}
|
||||
* @returns {Promise<{folders: {[p: string]: string}, favorited: string[]}>} - `folders` is a map of folder id to folder name, `favorited` is a list of folder id which contains the comic
|
||||
*/
|
||||
loadFolders: async (comicId) => {
|
||||
/*
|
||||
```
|
||||
let data = JSON.parse((await Network.get('...')).body)
|
||||
|
||||
let folders = {}
|
||||
|
||||
data.folders.forEach((f) => {
|
||||
folders[f.id] = f.name
|
||||
})
|
||||
|
||||
return {
|
||||
folders: folders,
|
||||
favorited: data.favorited
|
||||
}
|
||||
```
|
||||
*/
|
||||
},
|
||||
/**
|
||||
* load comics in a folder
|
||||
* throw `Login expired` to indicate login expired, App will automatically re-login retry.
|
||||
* @param page {number}
|
||||
* @param folder {string?} - folder id, null for non-multi-folder
|
||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||
*/
|
||||
loadComics: async (page, folder) => {
|
||||
/*
|
||||
```
|
||||
let data = JSON.parse((await Network.get('...')).body)
|
||||
let maxPage = data.maxPage
|
||||
|
||||
function parseComic(comic) {
|
||||
// ...
|
||||
|
||||
return new Comic{
|
||||
id: id,
|
||||
title: title,
|
||||
subTitle: author,
|
||||
cover: cover,
|
||||
tags: tags,
|
||||
description: description
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
comics: data.list.map(parseComic),
|
||||
maxPage: maxPage
|
||||
}
|
||||
```
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/// single comic related
|
||||
comic = {
|
||||
/**
|
||||
* load comic info
|
||||
* @param id {string}
|
||||
* @returns {Promise<ComicDetails>}
|
||||
*/
|
||||
loadInfo: async (id) => {
|
||||
|
||||
},
|
||||
/**
|
||||
* [Optional] load thumbnails of a comic
|
||||
* @param id {string}
|
||||
* @param next {string?} - next page token, null for first page
|
||||
* @returns {Promise<{thumbnails: string[], next: string?}>} - `next` is next page token, null for no more
|
||||
*/
|
||||
loadThumbnails: async (id, next) => {
|
||||
/*
|
||||
```
|
||||
let data = JSON.parse((await Network.get('...')).body)
|
||||
|
||||
return {
|
||||
thumbnails: data.list,
|
||||
next: next,
|
||||
}
|
||||
```
|
||||
*/
|
||||
},
|
||||
/**
|
||||
* load images of a chapter
|
||||
* @param comicId {string}
|
||||
* @param epId {string?}
|
||||
* @returns {Promise<{images: string[]}>}
|
||||
*/
|
||||
loadEp: async (comicId, epId) => {
|
||||
/*
|
||||
```
|
||||
return {
|
||||
// string[]
|
||||
images: images
|
||||
}
|
||||
```
|
||||
*/
|
||||
},
|
||||
/**
|
||||
* [Optional] provide configs for an image loading
|
||||
* @param url
|
||||
* @param comicId
|
||||
* @param epId
|
||||
* @returns {{}}
|
||||
*/
|
||||
onImageLoad: (url, comicId, epId) => {
|
||||
/*
|
||||
```
|
||||
return {
|
||||
url: `${url}?id=comicId`,
|
||||
// http method
|
||||
method: 'GET',
|
||||
// any
|
||||
data: null,
|
||||
headers: {
|
||||
'user-agent': 'pica_comic/v3.1.0',
|
||||
},
|
||||
// * modify response data
|
||||
// * @param data {ArrayBuffer}
|
||||
// * @returns {ArrayBuffer}
|
||||
onResponse: (data) => {
|
||||
return data
|
||||
}
|
||||
}
|
||||
```
|
||||
*/
|
||||
|
||||
return {}
|
||||
},
|
||||
/**
|
||||
* [Optional] provide configs for a thumbnail loading
|
||||
* @param url {string}
|
||||
* @returns {{}}
|
||||
*/
|
||||
onThumbnailLoad: (url) => {
|
||||
/*
|
||||
```
|
||||
return {
|
||||
url: `${url}?id=comicId`,
|
||||
// http method
|
||||
method: 'GET',
|
||||
// {any}
|
||||
data: null,
|
||||
headers: {
|
||||
'user-agent': 'pica_comic/v3.1.0',
|
||||
},
|
||||
// modify response data
|
||||
onResponse: (data) => {
|
||||
return data
|
||||
}
|
||||
}
|
||||
```
|
||||
*/
|
||||
return {}
|
||||
},
|
||||
/**
|
||||
* [Optional] like or unlike a comic
|
||||
* @param id {string}
|
||||
* @param isLike {boolean} - true for like, false for unlike
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
likeComic: async (id, isLike) => {
|
||||
|
||||
},
|
||||
/**
|
||||
* [Optional] load comments
|
||||
* @param comicId {string}
|
||||
* @param subId {string?} - ComicDetails.subId
|
||||
* @param page {number}
|
||||
* @param replyTo {string?} - commentId to reply, not null when reply to a comment
|
||||
* @returns {Promise<{comments: Comment[], maxPage: number?}>}
|
||||
*/
|
||||
loadComments: async (comicId, subId, page, replyTo) => {
|
||||
/*
|
||||
```
|
||||
// ...
|
||||
|
||||
return {
|
||||
comments: data.results.list.map(e => {
|
||||
return new Comment({
|
||||
// string
|
||||
userName: e.user_name,
|
||||
// string
|
||||
avatar: e.user_avatar,
|
||||
// string
|
||||
content: e.comment,
|
||||
// string?
|
||||
time: e.create_at,
|
||||
// number?
|
||||
replyCount: e.count,
|
||||
// string
|
||||
id: e.id,
|
||||
})
|
||||
}),
|
||||
// number
|
||||
maxPage: data.results.maxPage,
|
||||
}
|
||||
```
|
||||
*/
|
||||
},
|
||||
/**
|
||||
* [Optional] send a comment, return any value to indicate success
|
||||
* @param comicId {string}
|
||||
* @param subId {string?} - ComicDetails.subId
|
||||
* @param content {string}
|
||||
* @param replyTo {string?} - commentId to reply, not null when reply to a comment
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
sendComment: async (comicId, subId, content, replyTo) => {
|
||||
|
||||
},
|
||||
/**
|
||||
* [Optional] like or unlike a comment
|
||||
* @param comicId {string}
|
||||
* @param subId {string?} - ComicDetails.subId
|
||||
* @param commentId {string}
|
||||
* @param isLike {boolean} - true for like, false for unlike
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
likeComment: async (comicId, subId, commentId, isLike) => {
|
||||
|
||||
},
|
||||
/**
|
||||
* [Optional] vote a comment
|
||||
* @param id {string} - comicId
|
||||
* @param subId {string?} - ComicDetails.subId
|
||||
* @param commentId {string} - commentId
|
||||
* @param isUp {boolean} - true for up, false for down
|
||||
* @param isCancel {boolean} - true for cancel, false for vote
|
||||
* @returns {Promise<number>} - new score
|
||||
*/
|
||||
voteComment: async (id, subId, commentId, isUp, isCancel) => {
|
||||
|
||||
},
|
||||
// {string?} - regex string, used to identify comic id from user input
|
||||
idMatch: null,
|
||||
/**
|
||||
* [Optional] Handle tag click event
|
||||
* @param namespace {string}
|
||||
* @param tag {string}
|
||||
* @returns {{action: string, keyword: string, param: string?}}
|
||||
*/
|
||||
onClickTag: (namespace, tag) => {
|
||||
/*
|
||||
```
|
||||
return {
|
||||
// 'search' or 'category'
|
||||
action: 'search',
|
||||
keyword: tag,
|
||||
// {string?} only for category action
|
||||
param: null,
|
||||
}
|
||||
*/
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[Optional] settings related
|
||||
Use this.loadSetting to load setting
|
||||
```
|
||||
let setting1Value = this.loadSetting('setting1')
|
||||
console.log(setting1Value)
|
||||
```
|
||||
*/
|
||||
settings = {
|
||||
setting1: {
|
||||
// title
|
||||
title: "Setting1",
|
||||
// type: input, select, switch
|
||||
type: "select",
|
||||
// options
|
||||
options: [
|
||||
{
|
||||
// value
|
||||
value: 'o1',
|
||||
// [Optional] text, if not set, use value as text
|
||||
text: 'Option 1',
|
||||
},
|
||||
],
|
||||
default: 'o1',
|
||||
},
|
||||
setting2: {
|
||||
title: "Setting2",
|
||||
type: "switch",
|
||||
default: true,
|
||||
},
|
||||
setting3: {
|
||||
title: "Setting3",
|
||||
type: "input",
|
||||
validator: null, // string | null, regex string
|
||||
default: '',
|
||||
}
|
||||
}
|
||||
|
||||
// [Optional] translations for the strings in this config
|
||||
translation = {
|
||||
'zh_CN': {
|
||||
'Setting1': '设置1',
|
||||
'Setting2': '设置2',
|
||||
'Setting3': '设置3',
|
||||
},
|
||||
'zh_TW': {},
|
||||
'en': {}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user