toggle switches
This commit is contained in:
parent
f276a6276e
commit
aa820d4910
12 changed files with 396 additions and 58 deletions
35
lib/queries.ts
Normal file
35
lib/queries.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import { useQuery } from "react-query";
|
||||||
|
|
||||||
|
type JournalQueryDate = JournalEntry[];
|
||||||
|
|
||||||
|
interface JournalEntry {
|
||||||
|
"journal-day": number;
|
||||||
|
"original-name": string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useJournals(dateStart: Date, dateEnd: Date) {
|
||||||
|
const fmtStart = journalFmt(dateStart);
|
||||||
|
const fmtEnd = journalFmt(dateEnd);
|
||||||
|
|
||||||
|
return useQuery(["journals", dateStart, dateEnd], async () => {
|
||||||
|
const journals: JournalQueryDate[] = await logseq.DB.datascriptQuery(`
|
||||||
|
[:find (pull ?p [*])
|
||||||
|
:where
|
||||||
|
[?b :block/page ?p]
|
||||||
|
[?p :block/journal? true]
|
||||||
|
[?p :block/journal-day ?d]
|
||||||
|
[(>= ?d ${fmtStart})] [(<= ?d ${fmtEnd})]]
|
||||||
|
`);
|
||||||
|
|
||||||
|
return new Map(
|
||||||
|
journals
|
||||||
|
.flatMap((dates) => dates)
|
||||||
|
.map((entry) => [entry["journal-day"].toString(), entry])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function journalFmt(date: Date) {
|
||||||
|
return format(date, "YMMdd");
|
||||||
|
}
|
203
package-lock.json
generated
203
package-lock.json
generated
|
@ -13,7 +13,8 @@
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-keybind": "^0.9.4"
|
"react-keybind": "^0.9.4",
|
||||||
|
"react-query": "^3.39.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@logseq/libs": "^0.0.1-alpha.29",
|
"@logseq/libs": "^0.0.1-alpha.29",
|
||||||
|
@ -868,6 +869,19 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
|
},
|
||||||
|
"node_modules/big-integer": {
|
||||||
|
"version": "1.6.51",
|
||||||
|
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
|
||||||
|
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
@ -877,6 +891,15 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
@ -889,6 +912,21 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/broadcast-channel": {
|
||||||
|
"version": "3.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
|
||||||
|
"integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.7.2",
|
||||||
|
"detect-node": "^2.1.0",
|
||||||
|
"js-sha3": "0.8.0",
|
||||||
|
"microseconds": "0.2.0",
|
||||||
|
"nano-time": "1.0.0",
|
||||||
|
"oblivious-set": "1.0.0",
|
||||||
|
"rimraf": "3.0.2",
|
||||||
|
"unload": "2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.21.10",
|
"version": "4.21.10",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
|
||||||
|
@ -1002,6 +1040,11 @@
|
||||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||||
|
},
|
||||||
"node_modules/convert-source-map": {
|
"node_modules/convert-source-map": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||||
|
@ -1046,6 +1089,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/detect-node": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
|
||||||
|
},
|
||||||
"node_modules/dompurify": {
|
"node_modules/dompurify": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.1.tgz",
|
||||||
|
@ -1147,6 +1195,11 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
@ -1170,6 +1223,25 @@
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/glob": {
|
||||||
|
"version": "7.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^3.1.1",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/glob-parent": {
|
"node_modules/glob-parent": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
@ -1212,11 +1284,19 @@
|
||||||
"integrity": "sha512-808ZFYMsIRAjLAu5xkKo0TsbY9LBy9H5MazTKIEHerNkg0ymgilGfBPMR/3G7d/ihGmuK2Hw8S1izY2d3kd3wA==",
|
"integrity": "sha512-808ZFYMsIRAjLAu5xkKo0TsbY9LBy9H5MazTKIEHerNkg0ymgilGfBPMR/3G7d/ihGmuK2Hw8S1izY2d3kd3wA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
|
"dependencies": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
|
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/is-binary-path": {
|
"node_modules/is-binary-path": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
|
@ -1260,6 +1340,11 @@
|
||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-sha3": {
|
||||||
|
"version": "0.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
|
||||||
|
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
@ -1324,12 +1409,45 @@
|
||||||
"yallist": "^3.0.2"
|
"yallist": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/match-sorter": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"remove-accents": "0.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/microseconds": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
|
||||||
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/nano-time": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
|
||||||
|
"dependencies": {
|
||||||
|
"big-integer": "^1.6.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||||
|
@ -1373,6 +1491,19 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/oblivious-set": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path": {
|
"node_modules/path": {
|
||||||
"version": "0.12.7",
|
"version": "0.12.7",
|
||||||
"resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
|
"resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
|
||||||
|
@ -1383,6 +1514,14 @@
|
||||||
"util": "^0.10.3"
|
"util": "^0.10.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
|
@ -1466,6 +1605,31 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-keybind/-/react-keybind-0.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-keybind/-/react-keybind-0.9.4.tgz",
|
||||||
"integrity": "sha512-JVlXJ4ONQFQtEDZqXpc5NZ3oLEJtj7lKCPMLsbAO6FfkXJ21VHKyDtiLUIMio3d3oSC8QfxDOQtUEeVrMW6HfQ=="
|
"integrity": "sha512-JVlXJ4ONQFQtEDZqXpc5NZ3oLEJtj7lKCPMLsbAO6FfkXJ21VHKyDtiLUIMio3d3oSC8QfxDOQtUEeVrMW6HfQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-query": {
|
||||||
|
"version": "3.39.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
|
||||||
|
"integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"broadcast-channel": "^3.4.1",
|
||||||
|
"match-sorter": "^6.0.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/tannerlinsley"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
|
||||||
|
@ -1492,6 +1656,25 @@
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||||
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
|
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/remove-accents": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
|
||||||
|
},
|
||||||
|
"node_modules/rimraf": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
|
"dependencies": {
|
||||||
|
"glob": "^7.1.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rimraf": "bin.js"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "3.28.1",
|
"version": "3.28.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz",
|
||||||
|
@ -1633,6 +1816,15 @@
|
||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unload": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.6.2",
|
||||||
|
"detect-node": "^2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
|
||||||
|
@ -1746,6 +1938,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||||
|
},
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-keybind": "^0.9.4"
|
"react-keybind": "^0.9.4",
|
||||||
|
"react-query": "^3.39.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
randomshit.txt
Normal file
22
randomshit.txt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
const monthColors = [
|
||||||
|
"#AA3939",
|
||||||
|
"#FFAAAA",
|
||||||
|
"#D46A6A",
|
||||||
|
"#801515",
|
||||||
|
"#550000",
|
||||||
|
"#AA6C39",
|
||||||
|
"#FFD1AA",
|
||||||
|
"#D49A6A",
|
||||||
|
"#804515",
|
||||||
|
"#552700",
|
||||||
|
"#226666",
|
||||||
|
"#669999",
|
||||||
|
"#407F7F",
|
||||||
|
"#0D4D4D",
|
||||||
|
"#003333",
|
||||||
|
"#2D882D",
|
||||||
|
"#88CC88",
|
||||||
|
"#55AA55",
|
||||||
|
"#116611",
|
||||||
|
"#004400",
|
||||||
|
];
|
|
@ -9,4 +9,8 @@ main.app {
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
|
flex-basis: 120px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
23
src/App.tsx
23
src/App.tsx
|
@ -2,6 +2,9 @@ import { endOfMonth, format, startOfMonth } from "date-fns";
|
||||||
import styles from "./App.module.scss";
|
import styles from "./App.module.scss";
|
||||||
import Calendar from "./calendar/Calendar";
|
import Calendar from "./calendar/Calendar";
|
||||||
import KeyboardShortcutWrapper from "./KeyboardShortcutWrapper";
|
import KeyboardShortcutWrapper from "./KeyboardShortcutWrapper";
|
||||||
|
import { QueryClient, QueryClientProvider } from "react-query";
|
||||||
|
|
||||||
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const onDateClick = async (date: Date) => {
|
const onDateClick = async (date: Date) => {
|
||||||
|
@ -44,15 +47,17 @@ export default function App() {
|
||||||
const exit = () => logseq.hideMainUI();
|
const exit = () => logseq.hideMainUI();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardShortcutWrapper onExit={exit}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<main className={styles.app}>
|
<KeyboardShortcutWrapper onExit={exit}>
|
||||||
<div className="header">
|
<main className={styles.app}>
|
||||||
Header
|
<div className={styles.header}>
|
||||||
<button onClick={exit}>Close</button>
|
Header
|
||||||
</div>
|
<button onClick={exit}>Close</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Calendar onDateClick={onDateClick} />
|
<Calendar onDateClick={onDateClick} />
|
||||||
</main>
|
</main>
|
||||||
</KeyboardShortcutWrapper>
|
</KeyboardShortcutWrapper>
|
||||||
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,13 @@
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controlButtons {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
} from "date-fns";
|
} from "date-fns";
|
||||||
import Month from "./Month";
|
import Month from "./Month";
|
||||||
import { monthNameOf, weekBoundsOfMonth } from "lib/month";
|
import { monthNameOf, weekBoundsOfMonth } from "lib/month";
|
||||||
|
import { useJournals } from "lib/queries";
|
||||||
|
import ToggleSwitch from "src/widgets/ToggleSwitch";
|
||||||
|
|
||||||
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||||
const NUM_MONTHS_SHOWN = 5;
|
const NUM_MONTHS_SHOWN = 5;
|
||||||
|
@ -32,6 +34,9 @@ export default function Calendar({ onDateClick }: CalendarProps) {
|
||||||
range.map((x) => addMonths(centerMonth, x))
|
range.map((x) => addMonths(centerMonth, x))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const startDate = monthsShown[0];
|
||||||
|
const endDate = monthsShown[NUM_MONTHS_SHOWN - 1];
|
||||||
|
|
||||||
const [firstLoad, setFirstLoad] = useState(true);
|
const [firstLoad, setFirstLoad] = useState(true);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (firstLoad && scrollyEl && viewportHeight > 0) {
|
if (firstLoad && scrollyEl && viewportHeight > 0) {
|
||||||
|
@ -72,7 +77,7 @@ export default function Calendar({ onDateClick }: CalendarProps) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!scrollyEl) return;
|
if (!scrollyEl) return;
|
||||||
|
|
||||||
const children = [...scrollyEl.children];
|
const children: HTMLElement[] = [...scrollyEl.children];
|
||||||
if (children.length !== NUM_MONTHS_SHOWN) throw new Error("wtf");
|
if (children.length !== NUM_MONTHS_SHOWN) throw new Error("wtf");
|
||||||
const firstChild = children[0];
|
const firstChild = children[0];
|
||||||
const lastChild = children[NUM_MONTHS_SHOWN - 1];
|
const lastChild = children[NUM_MONTHS_SHOWN - 1];
|
||||||
|
@ -86,7 +91,7 @@ export default function Calendar({ onDateClick }: CalendarProps) {
|
||||||
|
|
||||||
if (entry.target === firstChild) {
|
if (entry.target === firstChild) {
|
||||||
console.log("intersected");
|
console.log("intersected");
|
||||||
const firstChildDate = new Date(firstChild.dataset.isodate);
|
const firstChildDate = new Date(firstChild.dataset.isodate!);
|
||||||
const prevMonth = subMonths(firstChildDate, 1);
|
const prevMonth = subMonths(firstChildDate, 1);
|
||||||
newMonthsShown = [prevMonth, ...monthsShown];
|
newMonthsShown = [prevMonth, ...monthsShown];
|
||||||
newMonthsShown = newMonthsShown.slice(0, NUM_MONTHS_SHOWN);
|
newMonthsShown = newMonthsShown.slice(0, NUM_MONTHS_SHOWN);
|
||||||
|
@ -96,7 +101,7 @@ export default function Calendar({ onDateClick }: CalendarProps) {
|
||||||
scrollyEl.scrollTop - firstChild.offsetTop,
|
scrollyEl.scrollTop - firstChild.offsetTop,
|
||||||
]);
|
]);
|
||||||
} else if (entry.target === lastChild) {
|
} else if (entry.target === lastChild) {
|
||||||
const lastChildDate = new Date(lastChild.dataset.isodate);
|
const lastChildDate = new Date(lastChild.dataset.isodate!);
|
||||||
const nextMonth = addMonths(lastChildDate, 1);
|
const nextMonth = addMonths(lastChildDate, 1);
|
||||||
newMonthsShown = [...monthsShown, nextMonth];
|
newMonthsShown = [...monthsShown, nextMonth];
|
||||||
newMonthsShown = newMonthsShown.slice(-NUM_MONTHS_SHOWN);
|
newMonthsShown = newMonthsShown.slice(-NUM_MONTHS_SHOWN);
|
||||||
|
@ -139,19 +144,31 @@ export default function Calendar({ onDateClick }: CalendarProps) {
|
||||||
// middleMonthEl?.scrollIntoView();
|
// middleMonthEl?.scrollIntoView();
|
||||||
// }, [middleMonthRef]);
|
// }, [middleMonthRef]);
|
||||||
|
|
||||||
|
const [currentLayout, setCurrentLayout] = useState("Month");
|
||||||
|
const [currentView, setCurrentView] = useState("Calendar");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.calendar}>
|
<div className={styles.calendar}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.title}>
|
<div className={styles.title}>
|
||||||
<b>{monthName}</b>
|
<div>
|
||||||
{centerMonth.getFullYear()}
|
<b>{monthName}</b>
|
||||||
(months shown:{" "}
|
{centerMonth.getFullYear()}
|
||||||
{JSON.stringify(
|
</div>
|
||||||
monthsShown.map((x) =>
|
|
||||||
x.toLocaleDateString("default", { month: "long" })
|
<div className={styles.controlButtons}>
|
||||||
)
|
<ToggleSwitch
|
||||||
)}
|
options={["Week", "Month", "Year"]}
|
||||||
)
|
value={currentLayout}
|
||||||
|
setValue={setCurrentLayout}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ToggleSwitch
|
||||||
|
options={["Calendar", "Graph"]}
|
||||||
|
value={currentView}
|
||||||
|
setValue={setCurrentView}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.daysOfWeek}>
|
<div className={styles.daysOfWeek}>
|
||||||
|
@ -173,6 +190,7 @@ export default function Calendar({ onDateClick }: CalendarProps) {
|
||||||
const props = {
|
const props = {
|
||||||
month,
|
month,
|
||||||
dateGridHeight,
|
dateGridHeight,
|
||||||
|
dateCellHeight,
|
||||||
};
|
};
|
||||||
const ref = undefined;
|
const ref = undefined;
|
||||||
// (month === currentlyShownMonth && middleMonthRef) || undefined;
|
// (month === currentlyShownMonth && middleMonthRef) || undefined;
|
||||||
|
|
|
@ -11,40 +11,26 @@ import {
|
||||||
} from "date-fns";
|
} from "date-fns";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { weekBoundsOfMonth } from "lib/month";
|
import { weekBoundsOfMonth } from "lib/month";
|
||||||
|
import { journalFmt, useJournals } from "lib/queries";
|
||||||
|
|
||||||
interface MonthProps {
|
interface MonthProps {
|
||||||
month: Date;
|
month: Date;
|
||||||
dateGridHeight: number;
|
dateGridHeight: number;
|
||||||
|
dateCellHeight: number;
|
||||||
onDateClick?: (_: Date) => void;
|
onDateClick?: (_: Date) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const monthColors = [
|
function Month(
|
||||||
"#AA3939",
|
{ month, dateGridHeight, dateCellHeight, onDateClick }: MonthProps,
|
||||||
"#FFAAAA",
|
ref
|
||||||
"#D46A6A",
|
) {
|
||||||
"#801515",
|
|
||||||
"#550000",
|
|
||||||
"#AA6C39",
|
|
||||||
"#FFD1AA",
|
|
||||||
"#D49A6A",
|
|
||||||
"#804515",
|
|
||||||
"#552700",
|
|
||||||
"#226666",
|
|
||||||
"#669999",
|
|
||||||
"#407F7F",
|
|
||||||
"#0D4D4D",
|
|
||||||
"#003333",
|
|
||||||
"#2D882D",
|
|
||||||
"#88CC88",
|
|
||||||
"#55AA55",
|
|
||||||
"#116611",
|
|
||||||
"#004400",
|
|
||||||
];
|
|
||||||
|
|
||||||
function Month({ month, dateGridHeight, onDateClick }: MonthProps, ref) {
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const monthName = month.toLocaleString("default", { month: "long" });
|
const monthName = month.toLocaleString("default", { month: "long" });
|
||||||
|
|
||||||
|
const firstDay = startOfMonth(month);
|
||||||
|
const lastDay = endOfMonth(month);
|
||||||
|
const { status, data: journals } = useJournals(firstDay, lastDay);
|
||||||
|
|
||||||
const [startWeek, endWeek] = weekBoundsOfMonth(month);
|
const [startWeek, endWeek] = weekBoundsOfMonth(month);
|
||||||
const numWeeks = differenceInWeeks(endWeek, startWeek) + 1;
|
const numWeeks = differenceInWeeks(endWeek, startWeek) + 1;
|
||||||
const weeksArr = Array(numWeeks)
|
const weeksArr = Array(numWeeks)
|
||||||
|
@ -61,13 +47,18 @@ function Month({ month, dateGridHeight, onDateClick }: MonthProps, ref) {
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={styles.dateGrid}
|
className={styles.dateGrid}
|
||||||
style={{ height: `${dateGridHeight}px` }}
|
// style={{ height: `${dateGridHeight}px` }}
|
||||||
|
style={{ gridTemplateRows: `repeat(${numWeeks}, ${dateCellHeight}px)` }}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
data-isodate={month}
|
data-isodate={month}
|
||||||
>
|
>
|
||||||
{datesArr.map((date) => {
|
{datesArr.map((date) => {
|
||||||
const isFirst = isSameDay(date, startOfMonth(date));
|
const isFirst = isSameDay(date, startOfMonth(date));
|
||||||
const isToday = isSameDay(date, now);
|
const isToday = isSameDay(date, now);
|
||||||
|
|
||||||
|
const journalDate = journalFmt(date);
|
||||||
|
const hasJournal = journals?.has(journalDate);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={date.toString()}
|
key={date.toString()}
|
||||||
|
@ -78,18 +69,15 @@ function Month({ month, dateGridHeight, onDateClick }: MonthProps, ref) {
|
||||||
className={styles.dateNumber}
|
className={styles.dateNumber}
|
||||||
onClick={() => onDateClick?.(date)}
|
onClick={() => onDateClick?.(date)}
|
||||||
>
|
>
|
||||||
<span
|
<span className={classNames(isToday && styles.today)}>
|
||||||
className={classNames(isFirst && styles.today)}
|
|
||||||
style={
|
|
||||||
isFirst
|
|
||||||
? { backgroundColor: monthColors[date.getMonth()] }
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{isFirst && monthName}
|
{isFirst && monthName}
|
||||||
{date.getDate()}
|
{date.getDate()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.dateCellBody}>
|
||||||
|
<p>j: {JSON.stringify(hasJournal)}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
:root {
|
||||||
|
--text-color: black;
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--text-color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body,
|
body,
|
||||||
#app {
|
#app {
|
||||||
|
@ -8,4 +16,5 @@ body,
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
19
src/widgets/ToggleSwitch.module.scss
Normal file
19
src/widgets/ToggleSwitch.module.scss
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
.toggleSwitch {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
border-radius: 9999px;
|
||||||
|
background-color: lightgray;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
border-radius: 9999px;
|
||||||
|
padding: 4px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
|
}
|
33
src/widgets/ToggleSwitch.tsx
Normal file
33
src/widgets/ToggleSwitch.tsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import classNames from "classnames";
|
||||||
|
import styles from "./ToggleSwitch.module.scss";
|
||||||
|
|
||||||
|
interface ToggleSwitchProps {
|
||||||
|
options: string[];
|
||||||
|
defaultOption?: string;
|
||||||
|
value: string;
|
||||||
|
setValue: (_: string) => any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ToggleSwitch({
|
||||||
|
options,
|
||||||
|
defaultOption,
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
}: ToggleSwitchProps) {
|
||||||
|
return (
|
||||||
|
<div className={styles.toggleSwitch}>
|
||||||
|
{options.map((option) => {
|
||||||
|
const isSelected = option === value;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={option}
|
||||||
|
className={classNames(styles.option, isSelected && styles.selected)}
|
||||||
|
onClick={() => setValue(option)}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in a new issue