Add multiple village support
This commit is contained in:
parent
bf7f4c1b7d
commit
3a673ac334
@ -1,9 +1,10 @@
|
|||||||
import * as URLParse from 'url-parse';
|
import * as URLParse from 'url-parse';
|
||||||
import { elClassId, markPage, waitForLoad } from '../utils';
|
import { markPage, waitForLoad } from '../utils';
|
||||||
import { Scheduler } from '../Scheduler';
|
import { Scheduler } from '../Scheduler';
|
||||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
|
||||||
import { TaskQueueRenderer } from '../TaskQueueRenderer';
|
import { TaskQueueRenderer } from '../TaskQueueRenderer';
|
||||||
import { BuildPage } from './BuildPage';
|
import { BuildPage } from '../Page/BuildPage';
|
||||||
|
import { grabActiveVillageId, showBuildingSlotIds, showFieldsSlotIds } from '../Page/EveryPage';
|
||||||
|
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
||||||
|
|
||||||
export class Dashboard {
|
export class Dashboard {
|
||||||
private readonly version: string;
|
private readonly version: string;
|
||||||
@ -24,12 +25,19 @@ export class Dashboard {
|
|||||||
this.renderTaskQueue();
|
this.renderTaskQueue();
|
||||||
setInterval(() => this.renderTaskQueue(), 5000);
|
setInterval(() => this.renderTaskQueue(), 5000);
|
||||||
|
|
||||||
|
const villageId = grabActiveVillageId();
|
||||||
|
|
||||||
|
const tasks = this.scheduler.getTaskItems();
|
||||||
|
const buildingsInQueue = tasks
|
||||||
|
.filter(t => t.name === UpgradeBuildingTask.name && t.args.villageId === villageId)
|
||||||
|
.map(t => t.args.buildId);
|
||||||
|
|
||||||
if (p.pathname === '/dorf1.php') {
|
if (p.pathname === '/dorf1.php') {
|
||||||
this.showSlotIds('buildingSlot');
|
showFieldsSlotIds(buildingsInQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.pathname === '/dorf2.php') {
|
if (p.pathname === '/dorf2.php') {
|
||||||
this.showSlotIds('aid');
|
showBuildingSlotIds(buildingsInQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.pathname === '/build.php') {
|
if (p.pathname === '/build.php') {
|
||||||
@ -42,27 +50,6 @@ export class Dashboard {
|
|||||||
new TaskQueueRenderer().render(this.scheduler.getTaskItems());
|
new TaskQueueRenderer().render(this.scheduler.getTaskItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
private showSlotIds(prefix: string) {
|
|
||||||
const tasks = this.scheduler.getTaskItems();
|
|
||||||
jQuery('.level.colorLayer').each((idx, el) => {
|
|
||||||
const buildId = elClassId(jQuery(el).attr('class') || '', prefix);
|
|
||||||
const oldLabel = jQuery(el)
|
|
||||||
.find('.labelLayer')
|
|
||||||
.text();
|
|
||||||
jQuery(el)
|
|
||||||
.find('.labelLayer')
|
|
||||||
.text(buildId + ':' + oldLabel);
|
|
||||||
const inQueue = tasks.find(
|
|
||||||
t => t.cmd.name === UpgradeBuildingTask.name && Number(t.cmd.args.id) === Number(buildId)
|
|
||||||
);
|
|
||||||
if (inQueue !== undefined) {
|
|
||||||
jQuery(el).css({
|
|
||||||
'background-image': 'linear-gradient(to top, #f00, #f00 100%)',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private log(...args) {
|
private log(...args) {
|
||||||
console.log('SCHEDULER:', ...args);
|
console.log('SCHEDULER:', ...args);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { elClassId, split, uniqId } from '../utils';
|
import { elClassId, split, uniqId } from '../utils';
|
||||||
import { Command } from '../Common';
|
|
||||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
||||||
import { Scheduler } from '../Scheduler';
|
import { Scheduler } from '../Scheduler';
|
||||||
import { TrainTroopTask } from '../Task/TrainTroopTask';
|
import { TrainTroopTask } from '../Task/TrainTroopTask';
|
||||||
|
import { grabActiveVillageId } from './EveryPage';
|
||||||
|
|
||||||
const QUARTERS_ID = 19;
|
const QUARTERS_ID = 19;
|
||||||
|
|
||||||
@ -34,12 +34,10 @@ export class BuildPage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onScheduleBuilding(id: number) {
|
private onScheduleBuilding(buildId: number) {
|
||||||
const queueItem = new Command(UpgradeBuildingTask.name, {
|
const villageId = grabActiveVillageId();
|
||||||
id,
|
this.scheduler.scheduleTask(UpgradeBuildingTask.name, { villageId, buildId });
|
||||||
});
|
const n = new Notification(`Building ${buildId} scheduled`);
|
||||||
this.scheduler.scheduleTask(queueItem);
|
|
||||||
const n = new Notification(`Building ${id} scheduled`);
|
|
||||||
setTimeout(() => n && n.close(), 4000);
|
setTimeout(() => n && n.close(), 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,18 +61,18 @@ export class BuildPage {
|
|||||||
|
|
||||||
private onTrainTroopClick(buildId: Number, troopId: Number, el: HTMLElement) {
|
private onTrainTroopClick(buildId: Number, troopId: Number, el: HTMLElement) {
|
||||||
console.log('TRAIN TROOPERS', 'TROOP ID', troopId, 'BUILDING ID', buildId);
|
console.log('TRAIN TROOPERS', 'TROOP ID', troopId, 'BUILDING ID', buildId);
|
||||||
|
const villageId = grabActiveVillageId();
|
||||||
const input = jQuery(el).find(`input[name="t${troopId}"]`);
|
const input = jQuery(el).find(`input[name="t${troopId}"]`);
|
||||||
const count = Number(input.val());
|
const count = Number(input.val());
|
||||||
if (!isNaN(count) && count > 0) {
|
if (!isNaN(count) && count > 0) {
|
||||||
console.log('PREPARE TO TRAIN', count, 'TROOPERS');
|
console.log('PREPARE TO TRAIN', count, 'TROOPERS');
|
||||||
for (let n of split(count)) {
|
for (let n of split(count)) {
|
||||||
this.scheduler.scheduleTask(
|
this.scheduler.scheduleTask(TrainTroopTask.name, {
|
||||||
new Command(TrainTroopTask.name, {
|
villageId,
|
||||||
buildId,
|
buildId,
|
||||||
troopId,
|
troopId,
|
||||||
trainCount: n,
|
trainCount: n,
|
||||||
})
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
35
src/Page/EveryPage.ts
Normal file
35
src/Page/EveryPage.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import * as URLParse from 'url-parse';
|
||||||
|
import { elClassId, getNumber } from '../utils';
|
||||||
|
|
||||||
|
export function grabActiveVillageId(): number {
|
||||||
|
const href = jQuery('#sidebarBoxVillagelist a.active').attr('href');
|
||||||
|
const p = new URLParse(href || '', true);
|
||||||
|
console.log('VILLAGE REF', href, p);
|
||||||
|
return getNumber(p.query.newdid);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSlotIds(prefix: string, buildingIds: number[]): void {
|
||||||
|
jQuery('.level.colorLayer').each((idx, el) => {
|
||||||
|
const buildId = getNumber(elClassId(jQuery(el).attr('class') || '', prefix));
|
||||||
|
const oldLabel = jQuery(el)
|
||||||
|
.find('.labelLayer')
|
||||||
|
.text();
|
||||||
|
jQuery(el)
|
||||||
|
.find('.labelLayer')
|
||||||
|
.text(buildId + ':' + oldLabel);
|
||||||
|
const inQueue = buildingIds.includes(buildId);
|
||||||
|
if (inQueue) {
|
||||||
|
jQuery(el).css({
|
||||||
|
'background-image': 'linear-gradient(to top, #f00, #f00 100%)',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showFieldsSlotIds(buildingIds: number[]) {
|
||||||
|
showSlotIds('buildingSlot', buildingIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showBuildingSlotIds(buildingIds: number[]) {
|
||||||
|
showSlotIds('aid', buildingIds);
|
||||||
|
}
|
@ -47,7 +47,7 @@ export class Scheduler {
|
|||||||
private scheduleUniqTask(seconds: number, name: string, args: Args = {}) {
|
private scheduleUniqTask(seconds: number, name: string, args: Args = {}) {
|
||||||
const taskScheduler = () => {
|
const taskScheduler = () => {
|
||||||
if (!this.taskQueue.hasNamed(name)) {
|
if (!this.taskQueue.hasNamed(name)) {
|
||||||
this.taskQueue.push(new Command(name, args), timestamp() + 10 * 60);
|
this.taskQueue.push(name, args, timestamp() + 10 * 60);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
taskScheduler();
|
taskScheduler();
|
||||||
@ -95,12 +95,12 @@ export class Scheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async processTaskCommand(task: Task) {
|
private async processTaskCommand(task: Task) {
|
||||||
const taskController = createTask(task.cmd.name, this);
|
const taskController = createTask(task.name, this);
|
||||||
this.log('PROCESS TASK', task.cmd.name, task, taskController);
|
this.log('PROCESS TASK', task.name, task, taskController);
|
||||||
if (taskController) {
|
if (taskController) {
|
||||||
await taskController.run(task);
|
await taskController.run(task);
|
||||||
} else {
|
} else {
|
||||||
this.logWarn('TASK NOT FOUND', task.cmd.name);
|
this.logWarn('TASK NOT FOUND', task.name);
|
||||||
this.taskQueue.complete(task.id);
|
this.taskQueue.complete(task.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ export class Scheduler {
|
|||||||
if (err instanceof BuildingQueueFullError) {
|
if (err instanceof BuildingQueueFullError) {
|
||||||
this.logWarn('BUILDING QUEUE FULL, TRY ALL AFTER', err.seconds);
|
this.logWarn('BUILDING QUEUE FULL, TRY ALL AFTER', err.seconds);
|
||||||
this.taskQueue.modify(
|
this.taskQueue.modify(
|
||||||
t => t.cmd.name === UpgradeBuildingTask.name,
|
t => t.name === UpgradeBuildingTask.name,
|
||||||
t => t.withTime(timestamp() + err.seconds)
|
t => t.withTime(timestamp() + err.seconds)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -146,9 +146,9 @@ export class Scheduler {
|
|||||||
this.taskQueue.complete(id);
|
this.taskQueue.complete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleTask(task: Command): void {
|
scheduleTask(name: string, args: Args): void {
|
||||||
this.log('PUSH TASK', task);
|
this.log('PUSH TASK', name, args);
|
||||||
this.taskQueue.push(task, timestamp());
|
this.taskQueue.push(name, args, timestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleActions(actions: Array<Command>): void {
|
scheduleActions(actions: Array<Command>): void {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Command } from '../Common';
|
import { Args } from '../Common';
|
||||||
import { uniqId } from '../utils';
|
import { uniqId } from '../utils';
|
||||||
|
|
||||||
const QUEUE_NAME = 'task_queue:v3';
|
const QUEUE_NAME = 'task_queue:v4';
|
||||||
|
|
||||||
export type TaskId = string;
|
export type TaskId = string;
|
||||||
|
|
||||||
@ -12,25 +12,27 @@ function uniqTaskId(): TaskId {
|
|||||||
export class Task {
|
export class Task {
|
||||||
readonly id: TaskId;
|
readonly id: TaskId;
|
||||||
readonly ts: number;
|
readonly ts: number;
|
||||||
readonly cmd: Command;
|
readonly name: string;
|
||||||
constructor(id: TaskId, ts: number, cmd: Command) {
|
readonly args: Args;
|
||||||
|
constructor(id: TaskId, ts: number, name: string, args: Args) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.ts = ts;
|
this.ts = ts;
|
||||||
this.cmd = cmd;
|
this.name = name;
|
||||||
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
withTime(ts: number): Task {
|
withTime(ts: number): Task {
|
||||||
return new Task(this.id, ts, this.cmd);
|
return new Task(this.id, ts, this.name, this.args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TaskList = Array<Task>;
|
export type TaskList = Array<Task>;
|
||||||
|
|
||||||
export class TaskQueue {
|
export class TaskQueue {
|
||||||
push(cmd: Command, ts: number): Task {
|
push(name: string, args: Args, ts: number): Task {
|
||||||
const id = uniqTaskId();
|
const id = uniqTaskId();
|
||||||
const task = new Task(id, ts, cmd);
|
const task = new Task(id, ts, name, args);
|
||||||
this.log('PUSH TASK', id, ts, cmd);
|
this.log('PUSH TASK', id, ts, name, args);
|
||||||
let items = this.getItems();
|
let items = this.getItems();
|
||||||
items.push(task);
|
items.push(task);
|
||||||
this.flushItems(items);
|
this.flushItems(items);
|
||||||
@ -51,7 +53,7 @@ export class TaskQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasNamed(name: string): boolean {
|
hasNamed(name: string): boolean {
|
||||||
return this.has(t => t.cmd.name === name);
|
return this.has(t => t.name === name);
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(predicate: (t: Task) => boolean, modifier: (t: Task) => Task) {
|
modify(predicate: (t: Task) => boolean, modifier: (t: Task) => Task) {
|
||||||
@ -101,7 +103,7 @@ export class TaskQueue {
|
|||||||
const storedItems = serialized !== null ? (JSON.parse(serialized) as Array<{ [key: string]: any }>) : [];
|
const storedItems = serialized !== null ? (JSON.parse(serialized) as Array<{ [key: string]: any }>) : [];
|
||||||
const items: TaskList = [];
|
const items: TaskList = [];
|
||||||
storedItems.forEach(obj => {
|
storedItems.forEach(obj => {
|
||||||
items.push(new Task(obj.id || uniqId(), +obj.ts, obj.cmd));
|
items.push(new Task(obj.id || uniqId(), +obj.ts, obj.name, obj.args));
|
||||||
});
|
});
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
@ -3,18 +3,24 @@ import { Task } from '../Storage/TaskQueue';
|
|||||||
import { TaskController, registerTask } from './TaskController';
|
import { TaskController, registerTask } from './TaskController';
|
||||||
import { GoToPageAction } from '../Action/GoToPageAction';
|
import { GoToPageAction } from '../Action/GoToPageAction';
|
||||||
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
||||||
import { TrainTrooperAction } from '../Action/TrainTrooperAction';
|
|
||||||
import { GrabVillageResourcesAction } from '../Action/GrabVillageResourcesAction';
|
import { GrabVillageResourcesAction } from '../Action/GrabVillageResourcesAction';
|
||||||
import { BalanceHeroResourcesAction } from '../Action/BalanceHeroResourcesAction';
|
import { BalanceHeroResourcesAction } from '../Action/BalanceHeroResourcesAction';
|
||||||
|
import { path } from '../utils';
|
||||||
|
|
||||||
@registerTask
|
@registerTask
|
||||||
export class BalanceHeroResourcesTask extends TaskController {
|
export class BalanceHeroResourcesTask extends TaskController {
|
||||||
async run(task: Task) {
|
async run(task: Task) {
|
||||||
const args: Args = { ...task.cmd.args, taskId: task.id };
|
const args: Args = { ...task.args, taskId: task.id };
|
||||||
this.scheduler.scheduleActions([
|
this.scheduler.scheduleActions([
|
||||||
new Command(GoToPageAction.name, { ...args, path: '/dorf1.php' }),
|
new Command(GoToPageAction.name, {
|
||||||
|
...args,
|
||||||
|
path: path('/dorf1.php'),
|
||||||
|
}),
|
||||||
new Command(GrabVillageResourcesAction.name, args),
|
new Command(GrabVillageResourcesAction.name, args),
|
||||||
new Command(GoToPageAction.name, { ...args, path: 'hero.php' }),
|
new Command(GoToPageAction.name, {
|
||||||
|
...args,
|
||||||
|
path: path('/hero.php'),
|
||||||
|
}),
|
||||||
new Command(BalanceHeroResourcesAction.name, args),
|
new Command(BalanceHeroResourcesAction.name, args),
|
||||||
new Command(CompleteTaskAction.name, args),
|
new Command(CompleteTaskAction.name, args),
|
||||||
]);
|
]);
|
||||||
|
@ -6,17 +6,21 @@ import { GrabHeroAttributesAction } from '../Action/GrabHeroAttributesAction';
|
|||||||
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
||||||
import { SendOnAdventureAction } from '../Action/SendOnAdventureAction';
|
import { SendOnAdventureAction } from '../Action/SendOnAdventureAction';
|
||||||
import { ClickButtonAction } from '../Action/ClickButtonAction';
|
import { ClickButtonAction } from '../Action/ClickButtonAction';
|
||||||
|
import { path } from '../utils';
|
||||||
|
|
||||||
@registerTask
|
@registerTask
|
||||||
export class SendOnAdventureTask extends TaskController {
|
export class SendOnAdventureTask extends TaskController {
|
||||||
async run(task: Task) {
|
async run(task: Task) {
|
||||||
const args: Args = { ...task.cmd.args, taskId: task.id };
|
const args: Args = { ...task.args, taskId: task.id };
|
||||||
this.scheduler.scheduleActions([
|
this.scheduler.scheduleActions([
|
||||||
new Command(GoToPageAction.name, { ...args, path: 'hero.php' }),
|
new Command(GoToPageAction.name, {
|
||||||
|
...args,
|
||||||
|
path: path('/hero.php'),
|
||||||
|
}),
|
||||||
new Command(GrabHeroAttributesAction.name, args),
|
new Command(GrabHeroAttributesAction.name, args),
|
||||||
new Command(GoToPageAction.name, {
|
new Command(GoToPageAction.name, {
|
||||||
...args,
|
...args,
|
||||||
path: '/hero.php?t=3',
|
path: path('/hero.php', { t: 3 }),
|
||||||
}),
|
}),
|
||||||
new Command(SendOnAdventureAction.name, args),
|
new Command(SendOnAdventureAction.name, args),
|
||||||
new Command(ClickButtonAction.name, {
|
new Command(ClickButtonAction.name, {
|
||||||
|
@ -4,13 +4,17 @@ import { TaskController, registerTask } from './TaskController';
|
|||||||
import { GoToPageAction } from '../Action/GoToPageAction';
|
import { GoToPageAction } from '../Action/GoToPageAction';
|
||||||
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
||||||
import { TrainTrooperAction } from '../Action/TrainTrooperAction';
|
import { TrainTrooperAction } from '../Action/TrainTrooperAction';
|
||||||
|
import { path } from '../utils';
|
||||||
|
|
||||||
@registerTask
|
@registerTask
|
||||||
export class TrainTroopTask extends TaskController {
|
export class TrainTroopTask extends TaskController {
|
||||||
async run(task: Task) {
|
async run(task: Task) {
|
||||||
const args: Args = { ...task.cmd.args, taskId: task.id };
|
const args: Args = { ...task.args, taskId: task.id };
|
||||||
this.scheduler.scheduleActions([
|
this.scheduler.scheduleActions([
|
||||||
new Command(GoToPageAction.name, { ...args, path: '/build.php?id=' + args.buildId }),
|
new Command(GoToPageAction.name, {
|
||||||
|
...args,
|
||||||
|
path: path('/build.php', { newdid: args.villageId, id: args.buildId }),
|
||||||
|
}),
|
||||||
new Command(TrainTrooperAction.name, args),
|
new Command(TrainTrooperAction.name, args),
|
||||||
new Command(CompleteTaskAction.name, args),
|
new Command(CompleteTaskAction.name, args),
|
||||||
]);
|
]);
|
||||||
|
@ -5,17 +5,21 @@ import { TaskController, registerTask } from './TaskController';
|
|||||||
import { GoToPageAction } from '../Action/GoToPageAction';
|
import { GoToPageAction } from '../Action/GoToPageAction';
|
||||||
import { CheckBuildingRemainingTimeAction } from '../Action/CheckBuildingRemainingTimeAction';
|
import { CheckBuildingRemainingTimeAction } from '../Action/CheckBuildingRemainingTimeAction';
|
||||||
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
||||||
|
import { path } from '../utils';
|
||||||
|
|
||||||
@registerTask
|
@registerTask
|
||||||
export class UpgradeBuildingTask extends TaskController {
|
export class UpgradeBuildingTask extends TaskController {
|
||||||
async run(task: Task) {
|
async run(task: Task) {
|
||||||
const args: Args = { ...task.cmd.args, taskId: task.id };
|
const args: Args = { ...task.args, taskId: task.id };
|
||||||
this.scheduler.scheduleActions([
|
this.scheduler.scheduleActions([
|
||||||
new Command(GoToPageAction.name, { ...args, path: '/dorf1.php' }),
|
new Command(GoToPageAction.name, {
|
||||||
|
...args,
|
||||||
|
path: path('/dorf1.php', { newdid: args.villageId }),
|
||||||
|
}),
|
||||||
new Command(CheckBuildingRemainingTimeAction.name, args),
|
new Command(CheckBuildingRemainingTimeAction.name, args),
|
||||||
new Command(GoToPageAction.name, {
|
new Command(GoToPageAction.name, {
|
||||||
...args,
|
...args,
|
||||||
path: '/build.php?id=' + args.id,
|
path: path('/build.php', { newdid: args.villageId, id: args.buildId }),
|
||||||
}),
|
}),
|
||||||
new Command(UpgradeBuildingAction.name, args),
|
new Command(UpgradeBuildingAction.name, args),
|
||||||
new Command(CompleteTaskAction.name, args),
|
new Command(CompleteTaskAction.name, args),
|
||||||
|
@ -25,7 +25,7 @@ export class TaskQueueRenderer {
|
|||||||
tasks.forEach(task => {
|
tasks.forEach(task => {
|
||||||
ul.append(
|
ul.append(
|
||||||
jQuery('<li></li>').text(
|
jQuery('<li></li>').text(
|
||||||
formatDate(task.ts) + ' ' + task.cmd.name + ' ' + JSON.stringify(task.cmd.args) + ' ' + task.id
|
formatDate(task.ts) + ' ' + task.name + ' ' + JSON.stringify(task.args) + ' ' + task.id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -71,6 +71,14 @@ export function getNumber(value: any, def: number = 0): number {
|
|||||||
return converted === undefined ? def : converted;
|
return converted === undefined ? def : converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function path(p: string, query: { [key: string]: string | number } = {}) {
|
||||||
|
let parts: string[] = [];
|
||||||
|
for (let k in query) {
|
||||||
|
parts.push(`${k}=${query[k]}`);
|
||||||
|
}
|
||||||
|
return p + (parts.length ? '?' + parts.join('&') : '');
|
||||||
|
}
|
||||||
|
|
||||||
export function markPage(text: string, version: string) {
|
export function markPage(text: string, version: string) {
|
||||||
jQuery('body').append(
|
jQuery('body').append(
|
||||||
'<div style="' +
|
'<div style="' +
|
||||||
|
Loading…
Reference in New Issue
Block a user