* Add docs v0.0.1 * Add icon size warning * Fix sourcenover caution * Fix semver descriptions * Filters fix * Quickfix quickstart * Add icon warning v2 * Fix typos * Add NovelItem * Update plugins host * Update plugins host * Remove unnecesarry .js and .dist * Update plugins host * Add host.ps1 * Fix readme.txt * Fix READNE.txt, again * Remove .js and .dist * readme update with ost * Add linux/windows hosting functions * Fix workflows
16 KiB
Documentation for LNReader plugins
Most of the Plugin/Novel type definitions accessed using the Plugin namespace imported via
import { Plugin } from "@typings/plugin";
PluginBase
PluginBase is a base class for all plugins.
class ExamplePlugin implements Plugin.PluginBase {}
| Field | Required | Description |
|---|---|---|
| id | yes | Plugin ID |
| name | yes | Plugin Name |
| icon | yes | Plugin Icon |
| site | yes | Plugin site link |
| version | yes | Plugin version |
| filters | no | Filter definition object |
| popularNovels(page, options) | yes | Novel list getter |
| parseNovelAndChapters(url) | yes | Novel info and chapter list getter |
| parseChapter(url) | yes | Chapter text getter |
| searchNovels(searchTerm, page) | yes | Novel searching getter |
| fetchImage(url) | yes | Customizable function for fetching images |
PluginBase::id
Unique ID of your plugin
class ExamplePlugin implements Plugin.PluginBase {
...
id = "templateID";
...
}
PluginBase::name
The name of your plugin that is shown in-app
class ExamplePlugin implements Plugin.PluginBase {
...
name = "template Plugin";
...
}
PluginBase::icon
The path to your plugin's icon inside of icon folder
class ExamplePlugin implements Plugin.PluginBase {
...
icon = "src/eng/templateplugin/icon.png";
...
}
Warning
Icons should be 96x96px
PluginBase::site
The url to the plugin's site
Example
class ExamplePlugin implements Plugin.PluginBase {
...
site = "https://example.com";
...
}
PluginBase::version
Version of your plugin formatted according to semver2.0 spec i.e. <major>.<minor>.<patch>
Where
patchincrements on small fixes that fix the plugin (like site changed a selector, filter had a typo etc.)minorincrements on fixes that improve the plugin (like adding/removing filters, adding search options etc.)majorincrements on fixes that fix the major issues with the plugin (like changing site link)
Example
class ExamplePlugin implements Plugin.PluginBase {
...
version = "1.0.0";
...
}
PluginBase::filters
A Filter definition object that holds filters used in popularNovels function
Example
class ExamplePlugin implements Plugin.PluginBase {
...
filters = {
order: {
label:"Order",
options: [
{ label: "Popular", value: "" },
{ label: "Newest", value: "newest" }
],
type: FilterTypes.Picker,
value: ""
},
status: {
label: "Status",
options: [
{ label: "All", value: "" },
{ label: "Ongoing", value: "ongoing" },
{ label: "Hiatus", value: "hiatus" },
{ label: "Completed", value: "completed" },
],
type: FilterTypes.Picker,
value: "",
}
}
...
}
PluginBase::popularNovels
Function that is used to get the (filtered) list of novels from the front page of the site
async popularNovels(
page: number,
options: Plugin.PopularNovelsOptions<typeof this.filters>
): Promise<Plugin.NovelItem[]>
See Using cheerio for more information on how to parse HTML documents
Parameters
pagecurrent page to fetchoptionsPopularNovelsOptions
Returns
NovelItem[] An array of filtered main-page NovelItems
Example:
class ExamplePlugin implements Plugin.PluginBase {
...
async popularNovels(
page: number,
options: Plugin.PopularNovelsOptions<typeof this.filters>
): Promise<Plugin.NovelItem[]> {
const novels: Plugin.NovelItem[] = [];
if(options.filters.example.value === "test"){
novels.push({
name: "Novel1",
url: "https://example.com/novel1",
cover:defaultCover
})
}
return novels;
}
}
PluginBase::PopularNovelsOptions
This type is used for getting the options of the popularNovels function
-
showLatestNovels: booleanflag set when opened withLatestbutton -
filters: FilterValues<typeof filters>object containing all selected filter values. More about Filters
PluginBase::parseNovelAndChapters
Function that is used to get the information about particular novel and the list of it's chapters
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel>
See Using cheerio for more information on how to parse HTML documents
Parameters
novelUrlvalue from NovelItem::url
Returns
SourceNovel Novel information and chapter list as SourceNovel object
[!CAUTION] > SourceNovel::url should be the same value as NovelItem::url provided as parameter!
Example:
class ExamplePlugin implements Plugin.PluginBase {
...
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
const novel: Plugin.SourceNovel = {
url: novelUrl,
name: "test",
artist: "none",
author: "none",
cover: defaultCover,
genres: "Isekai, Neverland",
status: NovelStatus.Completed,
summary: ""
};
let chapters: Plugin.ChapterItem[] = [];
const chapter: Plugin.ChapterItem = {
name: "",
url: "",
releaseTime: "",
chapterNumber: 0,
};
chapters.push(chapter);
novel.chapters = chapters;
return novel;
}
...
}
PluginBase::parseChapter
Function that is used to get the information about particular novel and the list of it's chapters
async parseChapter(chapterUrl: string): Promise<string>
See Using cheerio for more information on how to parse HTML documents
Parameters
chapterUrlvalue from ChapterItem::url
Returns
string HTML content of the chapter
Example:
class ExamplePlugin implements Plugin.PluginBase {
...
async parseChapter(chapterUrl: string): Promise<string>{
return "<h1>No chapter here</h1>";
}
...
}
PluginBase::searchNovels
Function that is used to find Novels in the source
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]>
See Using cheerio for more information on how to parse HTML documents
Parameters
searchTermthe search termpagesearch page number
Returns
NovelItem[] An array of found NovelItems
Example
class ExamplePlugin implements Plugin.PluginBase {
...
async searchNovels(
searchTerm: string,
pageNo: number
): Promise<Plugin.NovelItem[]> {
let novels: Plugin.NovelItem[] = [];
return novels;
}
...
}
PluginBase::fetchImage
Function used if images failed to load due to site's protection
async fetchImage(url: string): Promise<string | undefined>
See Fetch functions for detailed list of fetch functions provided by us to help with fetching data
Parameter
urlImage's url to fetch
Returns
stringbase64 representation of the image
or
undefinedon error
Example
class ExamplePlugin implements Plugin.PluginBase {
...
async fetchImage(url: string): Promise<string | undefined> {
const headers = {
Referer: "https://ln.hako.vn",
};
return await fetchFile(url, { headers: headers });
}
...
}
NovelItem
It is an object representing information how to store/access the novel
| Field | type | Required | Description |
|---|---|---|---|
url |
string |
yes | The url to the site |
name |
string |
yes | The name of the novel shown in the library |
cover |
string |
no | URL to novel's cover |
Default cover
You can use the default Cover not available cover by importing
import { defaultCover } from "@libs/defaultCover";
SourceNovel
| Field | Type | Required | Desciption |
|---|---|---|---|
| url | string | yes | |
| name | string | no | string |
| cover | string |
no | |
| genres | string |
no | |
| summary | string |
no | |
| author | string |
no | |
| artist | string |
no | |
| status | [NovelStatus] or string |
no | |
| chapters?: ChapterItem[]; |
ChapterItem
Filters
Filters and FilterTypes are not in the Plugin namespace and are from @libs/filterInputs file:
import { FilterTypes, Filters } from "@libs/filterInputs";
There are 2 main objects when using filters:
- Filter definition object
- FilterValues object
Filter definition object
This is the user-defined object that defines strictly what filters are available in the "filter" menu in app. Every property of this object is a different filter. The key of the object is the name that will be used to reference this filter's value in the FilterValues object
filters = {
order: {<FilterProperties>}
} satisfies Filters;
// accessible in popularNovels as
options.filters.order
Caution
Do not forget to add
satisfies Filtersafter the Filter definition object!
FilterProperties
| Name | Type | Required | Desciption |
|---|---|---|---|
| label | string |
yes | in-app label |
| type | FilterTypes |
yes | type of the filter |
| value | check types | yes | Default value for this filter and the starting filter state in-app |
| options | check types | in some types | The options available in the given type |
Example
filters = {
genre: {
type: FilterTypes.CheckboxGroup,
label: "Genres",
value: [],
options: [
{ label: "Isekai", value: "isekai" },
{ label: "Romance", value: "romans" },
],
},
} satisfies Filters;
Filter types
Types of filters supported
| FilterType | Description | value |
options |
|---|---|---|---|
Picker |
A spinner for choosing one of the choices provided in options |
string the picked value |
Picker options |
TextInput |
A filter allowing a free text input | string written value |
N/A |
Switch |
A boolean switch | boolean state of the switch |
N/A |
CheckboxGroup |
A grouping of checkboxes | string[] array containing selected values |
CheckboxGroup options |
ExcludableCheckboxGroup |
A filter allowing to pick one of the choices provided in options |
ExcludableCheckboxGroupValues object | CheckboxGroup options |
Picker options
options: [
{
label: "default", // in-app label
value: "", // in-code value
},
{
label: "Value ABC",
value: "abc",
},
];
CheckboxGroup options
options: [
{
label: "Value ABC", // in-app label
value: "abc", // in-code value
},
{
label: "Value DEF",
value: "def",
},
];
FilterValues object
It is an object used inisde of popularNovels that contains selected values for all filters defined in the Filter definition object.
The keys of the filter values correspond to Filter definition keys
// Filter definition object
filters = { abc: {} } satisfies Filters;
// then
options.filters; // FilterValues
options.filters.abc; // FilterValue for abc filter
FilterValue
Properties of FilterValue:
type: FilterTypetype of the filtervaluevalue dependent on FilterTypes
options.filters.abc.value; // value of the filter
options.filters.abc.type; // type of the filter
ExcludableCheckboxGroupValue object
{
included: string[], // options with selected selected
excluded: string[] // options with excluded selected
}