This commit is contained in:
Alex 2024-06-28 09:19:28 +08:00
parent 5356f84c40
commit 2768e36ebd
6 changed files with 126 additions and 22 deletions

View file

@ -12,6 +12,15 @@ export default [
rules: {
"@typescript-eslint/no-explicit-any": "off",
"no-constant-condition": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
},
},
];

View file

@ -64,10 +64,7 @@ export default class SoloToolkitPlugin extends Plugin {
}
async saveSetting(setting: Partial<SoloToolkitSettings>) {
this.settings = {
...this.settings,
...setting,
};
Object.assign(this.settings, setting);
return this.saveSettings();
}

View file

@ -3,6 +3,15 @@ import SoloToolkitPlugin from "../main";
export type ViewType = "dice" | "deck" | "oracle" | "word";
type DeckClipboardMode = "" | "md" | "path" | "png";
type DiceClipboardMode =
| "plain"
| "parenthesis"
| "square"
| "curly"
| "code"
| "code+parenthesis"
| "code+square"
| "code+curly";
export interface SoloToolkitSettings {
defaultView: ViewType;
@ -13,6 +22,7 @@ export interface SoloToolkitSettings {
deckTarot: boolean; // obsolete
deckClipboard: boolean; // obsolete
deckClipboardMode: DeckClipboardMode;
diceClipboardMode: DiceClipboardMode;
inlineCounters: boolean;
oracleLanguage: string;
@ -31,6 +41,7 @@ export const DEFAULT_SETTINGS: SoloToolkitSettings = {
deckTarot: true,
deckClipboard: false,
deckClipboardMode: "md",
diceClipboardMode: "code",
inlineCounters: false,
oracleLanguage: "en",
@ -120,9 +131,29 @@ export class SoloToolkitSettingTab extends PluginSettingTab {
})
);
new Setting(containerEl)
.setName("Dice click behavior")
.setDesc("What will be copied when you click on a dice roll result")
.addDropdown((dropdown) => {
dropdown
.addOption("plain", "d6: 4")
.addOption("parenthesis", "(d6: 4)")
.addOption("square", "[d6: 4]")
.addOption("curly", "{d6: 4}")
.addOption("code", "`d6: 4`")
.addOption("code+parenthesis", "`(d6: 4)`")
.addOption("code+square", "`[d6: 4]`")
.addOption("code+curly", "`{d6: 4}`");
dropdown.setValue(this.plugin.settings.diceClipboardMode || "");
dropdown.onChange(async (value: DiceClipboardMode) => {
this.plugin.settings.diceClipboardMode = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName("Card click behavior")
.setDesc("Determines what happens when you click on a drawn card")
.setDesc("What will be copied when you click on a drawn card")
.addDropdown((dropdown) => {
dropdown
.addOption("", "Off")

View file

@ -29,6 +29,9 @@ export const trim = (value: string): string => value.trim();
export const identity = (value: string): string => value;
export const sum = (values: number[]): number =>
values.reduce((sum, value) => sum + (value || 0), 0);
export const shuffle = <T>(arr: T[]) => {
let index = arr.length;
let random = 0;
@ -40,6 +43,14 @@ export const shuffle = <T>(arr: T[]) => {
}
};
export function first<T>(arr: T[]): T {
return arr[0];
}
export function last<T>(arr: T[]): T {
return arr[arr.length - 1];
}
export const clickToCopy = (value: string) => (event: MouseEvent) => {
event.preventDefault();
navigator.clipboard.writeText(value);
@ -108,10 +119,16 @@ export const clickToCopyImage =
img.src = value;
};
export function first<T>(arr: T[]): T {
return arr[0];
}
export function last<T>(arr: T[]): T {
return arr[arr.length - 1];
export function bounce(timeout: number, once = false) {
let lastTime = 0;
return {
set: () => {
lastTime = Date.now();
},
check: () => {
const result = lastTime + timeout > Date.now();
if (once) lastTime = 0;
return result;
},
};
}

View file

@ -1,6 +1,6 @@
import { ExtraButtonComponent, setTooltip } from "obsidian";
import { SoloToolkitView as View } from "./index";
import { clickToCopy, roll, rollIntervals } from "../utils";
import { clickToCopy, roll, rollIntervals, bounce, sum, first } from "../utils";
const MAX_REMEMBER_SIZE = 100;
@ -57,25 +57,41 @@ export class DiceView {
if (rollIntervals[i]) {
setTimeout(reroll, rollIntervals[i]);
} else {
const size = this.rolls[max].length;
const sum = this.rolls[max].reduce(
(result, value) => result + (value[0] || 0),
0
);
// To prevent double-tap bug on mobile
const preventClick = bounce(1000, true);
el.onclick = (event) => {
if (preventClick.check()) return;
const { shiftKey, ctrlKey, metaKey, altKey } = event;
const anyKey = shiftKey || ctrlKey || metaKey || altKey;
const [single, total] = this.formatForClipboard(value, max);
if (anyKey) {
clickToCopy(`[${size}d${max}: ${sum}]`)(event);
clickToCopy(total)(event);
} else {
clickToCopy(`[d${max}: ${value}]`)(event);
clickToCopy(single)(event);
}
};
el.oncontextmenu = (event) => {
event.preventDefault();
clickToCopy(`[${size}d${max}: ${sum}]`)(event);
event.stopPropagation();
const [_single, total] = this.formatForClipboard(value, max);
clickToCopy(total)(event);
preventClick.set();
};
setTooltip(container, `Total: ${sum}`);
setTooltip(
container,
`${this.rolls[max].length}d${max}: ${sum(
this.rolls[max].map(first)
)}`,
{
delay: 0,
placement: "right",
}
);
}
}
};
@ -87,6 +103,33 @@ export class DiceView {
el.setText(value.toString());
}
formatForClipboard(value: number, max: number): [string, string] {
const size = this.rolls[max].length;
const total = sum(this.rolls[max].map(first));
const singleStr = `d${max}: ${value}`;
const totalStr = `${size}d${max}: ${total}`;
switch (this.view.settings.diceClipboardMode) {
case "plain":
return [singleStr, totalStr];
case "parenthesis":
return [`(${singleStr})`, `(${totalStr})`];
case "square":
return [`[${singleStr}]`, `[${totalStr}]`];
case "curly":
return [`{${singleStr}}`, `{${totalStr}}`];
case "code":
return [`\`${singleStr}\``, `\`${totalStr}\``];
case "code+parenthesis":
return [`\`(${singleStr})\``, `\`(${totalStr})\``];
case "code+square":
return [`\`[${singleStr}]\``, `\`[${totalStr}]\``];
case "code+curly":
return [`\`{${singleStr}}\``, `\`{${totalStr}}\``];
default:
return [singleStr, totalStr];
}
}
createDiceBtn(d: number) {
const container = this.btnsEl.createDiv(`dice-variant dice-variant-${d}`);
@ -97,16 +140,23 @@ export class DiceView {
.setIcon(`srt-d${d}`)
.setTooltip(`Roll d${d}`);
// To prevent double-tap bug on mobile
const preventClick = bounce(1000, true);
btnEl.extraSettingsEl.onclick = (event) => {
if (preventClick.check()) return;
const { shiftKey, ctrlKey, metaKey, altKey } = event;
const a = shiftKey ? 0b001 : 0;
const b = ctrlKey || metaKey ? 0b010 : 0;
const c = altKey ? 0b100 : 0;
this.addResult(resultsEl, d, a + b + c);
};
btnEl.extraSettingsEl.oncontextmenu = (event) => {
event.preventDefault();
event.stopPropagation();
this.addResult(resultsEl, d, 1);
preventClick.set();
};
}

View file

@ -46,7 +46,7 @@ export class SoloToolkitView extends ItemView {
super(leaf);
this.settings = settings;
this.setSettings = setSettings;
this.tab = settings.defaultView || "deck";
this.tab = this.settings.defaultView || "deck";
this.dice = new DiceView(this);
this.deck = new DeckView(this);
this.word = new WordView(this);