feat: add startup sync toggle and sync command

This commit is contained in:
Graham 2025-03-22 19:24:49 -07:00
parent 22ff519a4b
commit 62d269e956
Signed by: puregarlic
SSH key fingerprint: SHA256:j2sN/ABe7mfw8RwswfUi4owiaZYA2sTKCSkKlqYb35M
4 changed files with 200 additions and 7 deletions

View file

@ -18,10 +18,15 @@ export type Input = LimitlessPluginSettings & {
vault: Vault;
};
export type Events = {
type: "lifelogs::sync";
};
export const pluginActor = setup({
types: {
context: {} as Context,
input: {} as Input,
events: {} as Events,
},
actors: {
queryLifelogs,
@ -34,13 +39,15 @@ export const pluginActor = setup({
hasCursor: ({ context }) => Boolean(context.cursor),
},
actions: {
persistLatestLog: (_, _params: { endDate: Date }) => {
// Write back to settings
throw new Error("This action must be provided!");
},
updateLatestLog: assign(({ context }, params: { endDate: Date }) => {
if (context.latestLog && isAfter(context.latestLog, params.endDate)) {
return context;
}
// TODO: Write back to settings
return {
latestLog: params.endDate,
};
@ -68,7 +75,7 @@ export const pluginActor = setup({
},
}).createMachine({
id: "obsidian-limitless-plugin",
initial: "querying",
initial: "idle",
context: ({ input }) => ({
apiKey: input.apiKey,
latestLog: input.latestLog ? parse(input.latestLog) : undefined,
@ -79,8 +86,8 @@ export const pluginActor = setup({
}),
states: {
idle: {
after: {
[10 * 60 * 1000]: {
on: {
"lifelogs::sync": {
target: "querying",
},
},
@ -140,6 +147,12 @@ export const pluginActor = setup({
endDate: event.output,
}),
},
{
type: "persistLatestLog",
params: ({ event }) => ({
endDate: event.output,
}),
},
],
},
},

137
deno.lock generated
View file

@ -1,10 +1,36 @@
{
"version": "4",
"specifiers": {
"jsr:@luca/esbuild-deno-loader@~0.11.1": "0.11.1",
"jsr:@std/bytes@^1.0.2": "1.0.5",
"jsr:@std/encoding@^1.0.5": "1.0.7",
"jsr:@std/path@^1.0.6": "1.0.8",
"npm:@formkit/tempo@~0.1.2": "0.1.2",
"npm:builtin-modules@5": "5.0.0",
"npm:esbuild@~0.25.1": "0.25.1",
"npm:ky@^1.7.5": "1.7.5",
"npm:obsidian@^1.8.7": "1.8.7_@codemirror+state@6.5.2_@codemirror+view@6.36.4",
"npm:xstate@^5.19.2": "5.19.2"
},
"jsr": {
"@luca/esbuild-deno-loader@0.11.1": {
"integrity": "dc020d16d75b591f679f6b9288b10f38bdb4f24345edb2f5732affa1d9885267",
"dependencies": [
"jsr:@std/bytes",
"jsr:@std/encoding",
"jsr:@std/path"
]
},
"@std/bytes@1.0.5": {
"integrity": "4465dd739d7963d964c809202ebea6d5c6b8e3829ef25c6a224290fbb8a1021e"
},
"@std/encoding@1.0.7": {
"integrity": "f631247c1698fef289f2de9e2a33d571e46133b38d042905e3eac3715030a82d"
},
"@std/path@1.0.8": {
"integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
}
},
"npm": {
"@codemirror/state@6.5.2": {
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
@ -20,6 +46,81 @@
"w3c-keyname"
]
},
"@esbuild/aix-ppc64@0.25.1": {
"integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ=="
},
"@esbuild/android-arm64@0.25.1": {
"integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA=="
},
"@esbuild/android-arm@0.25.1": {
"integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q=="
},
"@esbuild/android-x64@0.25.1": {
"integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw=="
},
"@esbuild/darwin-arm64@0.25.1": {
"integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ=="
},
"@esbuild/darwin-x64@0.25.1": {
"integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA=="
},
"@esbuild/freebsd-arm64@0.25.1": {
"integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A=="
},
"@esbuild/freebsd-x64@0.25.1": {
"integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww=="
},
"@esbuild/linux-arm64@0.25.1": {
"integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ=="
},
"@esbuild/linux-arm@0.25.1": {
"integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ=="
},
"@esbuild/linux-ia32@0.25.1": {
"integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ=="
},
"@esbuild/linux-loong64@0.25.1": {
"integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg=="
},
"@esbuild/linux-mips64el@0.25.1": {
"integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg=="
},
"@esbuild/linux-ppc64@0.25.1": {
"integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg=="
},
"@esbuild/linux-riscv64@0.25.1": {
"integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ=="
},
"@esbuild/linux-s390x@0.25.1": {
"integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ=="
},
"@esbuild/linux-x64@0.25.1": {
"integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA=="
},
"@esbuild/netbsd-arm64@0.25.1": {
"integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g=="
},
"@esbuild/netbsd-x64@0.25.1": {
"integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA=="
},
"@esbuild/openbsd-arm64@0.25.1": {
"integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg=="
},
"@esbuild/openbsd-x64@0.25.1": {
"integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw=="
},
"@esbuild/sunos-x64@0.25.1": {
"integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg=="
},
"@esbuild/win32-arm64@0.25.1": {
"integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ=="
},
"@esbuild/win32-ia32@0.25.1": {
"integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A=="
},
"@esbuild/win32-x64@0.25.1": {
"integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg=="
},
"@formkit/tempo@0.1.2": {
"integrity": "sha512-jNPPbjL8oj7hK3eHX++CwbR6X4GKQt+x00/q4yeXkwynXHGKL27dylYhpEgwrmediPP4y7s0XtN1if/M/JYujg=="
},
@ -41,6 +142,42 @@
"@types/estree"
]
},
"builtin-modules@5.0.0": {
"integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg=="
},
"esbuild@0.25.1": {
"integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
"dependencies": [
"@esbuild/aix-ppc64",
"@esbuild/android-arm",
"@esbuild/android-arm64",
"@esbuild/android-x64",
"@esbuild/darwin-arm64",
"@esbuild/darwin-x64",
"@esbuild/freebsd-arm64",
"@esbuild/freebsd-x64",
"@esbuild/linux-arm",
"@esbuild/linux-arm64",
"@esbuild/linux-ia32",
"@esbuild/linux-loong64",
"@esbuild/linux-mips64el",
"@esbuild/linux-ppc64",
"@esbuild/linux-riscv64",
"@esbuild/linux-s390x",
"@esbuild/linux-x64",
"@esbuild/netbsd-arm64",
"@esbuild/netbsd-x64",
"@esbuild/openbsd-arm64",
"@esbuild/openbsd-x64",
"@esbuild/sunos-x64",
"@esbuild/win32-arm64",
"@esbuild/win32-ia32",
"@esbuild/win32-x64"
]
},
"ky@1.7.5": {
"integrity": "sha512-HzhziW6sc5m0pwi5M196+7cEBtbt0lCYi67wNsiwMUmz833wloE0gbzJPWKs1gliFKQb34huItDQX97LyOdPdA=="
},
"moment@2.29.4": {
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},

23
main.ts
View file

@ -15,7 +15,16 @@ export default class LimitlessPlugin extends Plugin {
this.addSettingTab(new LimitlessSettingTab(this.app, this));
const actor = createActor(pluginActor, {
const readyActor = pluginActor.provide({
actions: {
persistLatestLog: async (_, params) => {
this.settings.latestLog = params.endDate.toISOString();
await this.saveSettings();
},
},
});
const actor = createActor(readyActor, {
input: {
...this.settings,
vault: this.app.vault,
@ -27,6 +36,18 @@ export default class LimitlessPlugin extends Plugin {
});
actor.start();
this.addCommand({
id: "limitless-lifelogs-sync",
name: "Sync Lifelogs Now",
callback: () => {
actor.send({ type: "lifelogs::sync" });
},
});
if (this.settings.syncAtStart) {
actor.send({ type: "lifelogs::sync" });
}
}
override onunload() {

View file

@ -2,12 +2,14 @@ import { App, PluginSettingTab, Setting } from "obsidian";
import LimitlessPlugin from "./main.ts";
export interface LimitlessPluginSettings {
syncAtStart: boolean;
apiKey: string;
lifelogsDir: string;
latestLog?: string;
}
export const DEFAULT_SETTINGS: LimitlessPluginSettings = {
syncAtStart: false,
apiKey: "",
lifelogsDir: "",
latestLog: undefined,
@ -26,9 +28,15 @@ export class LimitlessSettingTab extends PluginSettingTab {
containerEl.empty();
containerEl.createEl("h1", { text: "Unofficial Limitless Plugin" });
containerEl.createEl("p", {
text:
"Please note that you must own a Limitless Pendant to use this plugin, for now.",
});
new Setting(containerEl)
.setName("API Key")
.setDesc("It's a secret")
.setDesc("Retrieve this from your Developer settings on desktop or web")
.addText((text) => {
text.inputEl.type = "password";
@ -41,6 +49,20 @@ export class LimitlessSettingTab extends PluginSettingTab {
});
});
containerEl.createEl("h2", { text: "Lifelogs" });
new Setting(containerEl)
.setName("Sync at Start")
.setDesc("Whether or not to sync lifelogs when Obsidian opens")
.addToggle((toggle) => {
return toggle
.setValue(this.plugin.settings.syncAtStart)
.onChange(async (value) => {
this.plugin.settings.syncAtStart = value;
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName("Lifelogs Directory")
.setDesc("The directory where you want Lifelogs placed")