refactor(styles): migrate from CSS to SCSS

- Convert all .css files to .scss format
- Add sass and esbuild-sass-plugin dependencies
- Configure esbuild with sassPlugin for SCSS compilation
- Update all component imports from .css to .scss
- Add _variables.scss for shared SCSS variables
- Add native-layout.scss for new layout styles
This commit is contained in:
Quorafind 2025-12-11 14:33:41 +08:00
parent 7d8e83bddf
commit 7116bb15ae
138 changed files with 2283 additions and 1256 deletions

View file

@ -5,6 +5,7 @@ import fs from "fs";
import path from "path";
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
import { sassPlugin } from "esbuild-sass-plugin";
// Respect release-it dry-run: skip writing build artifacts entirely
const __D_RY__ =
@ -52,10 +53,12 @@ const cssSettingsPluginWithDir = {
// Path to the output CSS file
const cssOutfile = path.join(outDir, "styles.css");
// The settings comment to prepend
// The settings comment to prepend (read from SCSS file now)
const indexFile = fs.existsSync("src/styles/index.scss")
? "src/styles/index.scss"
: "src/styles/index.css";
const settingsComment =
fs.readFileSync("src/styles/index.css", "utf8").split("*/")[0] +
"*/\n\n";
fs.readFileSync(indexFile, "utf8").split("*/")[0] + "*/\n\n";
if (fs.existsSync(cssOutfile)) {
// Read the current content
@ -95,6 +98,12 @@ const buildOptions = {
entryPoints: ["src/index.ts"],
plugins: [
inlineWorkerPlugin({ workerName: "Task Genius Indexer" }),
sassPlugin({
// Enable modern SASS API
type: "css",
// Load paths for @use and @import
loadPaths: [path.resolve(process.cwd(), "src/styles")],
}),
renamePluginWithDir,
cssSettingsPluginWithDir,
copyManifestPlugin,

View file

@ -56,6 +56,7 @@
"dotenv": "^17.2.1",
"esbuild": "0.25.9",
"esbuild-plugin-inline-worker": "workspace:*",
"esbuild-sass-plugin": "^3.3.1",
"globby": "^14.1.0",
"husky": "^9.1.7",
"jest": "^29.5.0",
@ -63,6 +64,7 @@
"jszip": "^3.10.1",
"monkey-around": "^3.0.0",
"release-it": "^19.0.4",
"sass": "^1.96.0",
"semver": "^7.7.2",
"ts-jest": "^29.1.0",
"tslib": "2.4.0",

View file

@ -44,7 +44,7 @@ importers:
devDependencies:
'@codemirror/language':
specifier: https://github.com/lishid/cm-language
version: https://codeload.github.com/lishid/cm-language/tar.gz/a9c3c7efe17dd1d24395ee2a179fe12dd6ed1e76
version: https://codeload.github.com/lishid/cm-language/tar.gz/2d416d7835867d1b1e8d0e726b147fc1135c9f92
'@codemirror/search':
specifier: ^6.0.0
version: 6.5.11
@ -96,6 +96,9 @@ importers:
esbuild-plugin-inline-worker:
specifier: workspace:*
version: link:packages/esbuild-plugin-inline-worker
esbuild-sass-plugin:
specifier: ^3.3.1
version: 3.3.1(esbuild@0.25.9)(sass-embedded@1.96.0)
globby:
specifier: ^14.1.0
version: 14.1.0
@ -117,6 +120,9 @@ importers:
release-it:
specifier: ^19.0.4
version: 19.0.6(@types/node@16.18.126)(magicast@0.3.5)
sass:
specifier: ^1.96.0
version: 1.96.0
semver:
specifier: ^7.7.2
version: 7.7.3
@ -168,13 +174,13 @@ importers:
version: 5.9.3
vite:
specifier: ^5.0.0
version: 5.4.21(@types/node@20.19.25)(terser@5.44.1)
version: 5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
vite-plugin-dts:
specifier: ^3.6.0
version: 3.9.1(@types/node@20.19.25)(rollup@4.53.3)(typescript@5.9.3)(vite@5.4.21(@types/node@20.19.25)(terser@5.44.1))
version: 3.9.1(@types/node@20.19.25)(rollup@4.53.3)(typescript@5.9.3)(vite@5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1))
vitest:
specifier: ^1.0.0
version: 1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(terser@5.44.1)
version: 1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
wrangler:
specifier: ^4.51.0
version: 4.51.0
@ -372,6 +378,9 @@ packages:
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
'@bufbuild/protobuf@2.10.1':
resolution: {integrity: sha512-ckS3+vyJb5qGpEYv/s1OebUHDi/xSNtfgw1wqKZo7MR9F2z+qXr0q5XagafAG/9O0QPVIUfST0smluYSTpYFkg==}
'@cloudflare/kv-asset-handler@0.4.1':
resolution: {integrity: sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==}
engines: {node: '>=18.0.0'}
@ -424,8 +433,8 @@ packages:
'@codemirror/language@6.11.2':
resolution: {integrity: sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==}
'@codemirror/language@https://codeload.github.com/lishid/cm-language/tar.gz/a9c3c7efe17dd1d24395ee2a179fe12dd6ed1e76':
resolution: {tarball: https://codeload.github.com/lishid/cm-language/tar.gz/a9c3c7efe17dd1d24395ee2a179fe12dd6ed1e76}
'@codemirror/language@https://codeload.github.com/lishid/cm-language/tar.gz/2d416d7835867d1b1e8d0e726b147fc1135c9f92':
resolution: {tarball: https://codeload.github.com/lishid/cm-language/tar.gz/2d416d7835867d1b1e8d0e726b147fc1135c9f92}
version: 6.11.2
'@codemirror/lint@6.9.2':
@ -1417,6 +1426,88 @@ packages:
'@octokit/types@16.0.0':
resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==}
'@parcel/watcher-android-arm64@2.5.1':
resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [android]
'@parcel/watcher-darwin-arm64@2.5.1':
resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [darwin]
'@parcel/watcher-darwin-x64@2.5.1':
resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [darwin]
'@parcel/watcher-freebsd-x64@2.5.1':
resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [freebsd]
'@parcel/watcher-linux-arm-glibc@2.5.1':
resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
'@parcel/watcher-linux-arm-musl@2.5.1':
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
'@parcel/watcher-linux-arm64-glibc@2.5.1':
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
'@parcel/watcher-linux-arm64-musl@2.5.1':
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
'@parcel/watcher-linux-x64-glibc@2.5.1':
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
'@parcel/watcher-linux-x64-musl@2.5.1':
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
'@parcel/watcher-win32-arm64@2.5.1':
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [win32]
'@parcel/watcher-win32-ia32@2.5.1':
resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==}
engines: {node: '>= 10.0.0'}
cpu: [ia32]
os: [win32]
'@parcel/watcher-win32-x64@2.5.1':
resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [win32]
'@parcel/watcher@2.5.1':
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
'@phun-ky/typeof@2.0.3':
resolution: {integrity: sha512-oeQJs1aa8Ghke8JIK9yuq/+KjMiaYeDZ38jx7MhkXncXlUKjqQ3wEm2X3qCKyjo+ZZofZj+WsEEiqkTtRuE2xQ==}
engines: {node: ^20.9.0 || >=22.0.0, npm: '>=10.8.2'}
@ -1985,6 +2076,9 @@ packages:
bser@2.1.1:
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
buffer-builder@0.2.0:
resolution: {integrity: sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
@ -2118,6 +2212,9 @@ packages:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
colorjs.io@0.5.2:
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@ -2370,6 +2467,11 @@ packages:
resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==}
engines: {node: '>=12.20'}
detect-libc@1.0.3:
resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
engines: {node: '>=0.10'}
hasBin: true
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
@ -2463,6 +2565,12 @@ packages:
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
engines: {node: '>= 0.4'}
esbuild-sass-plugin@3.3.1:
resolution: {integrity: sha512-SnO1ls+d52n6j8gRRpjexXI8MsHEaumS0IdDHaYM29Y6gakzZYMls6i9ql9+AWMSQk/eryndmUpXEgT34QrX1A==}
peerDependencies:
esbuild: '>=0.20.1'
sass-embedded: ^1.71.1
esbuild@0.21.5:
resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
engines: {node: '>=12'}
@ -2853,6 +2961,9 @@ packages:
immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
immutable@5.1.4:
resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==}
import-fresh@3.3.1:
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
engines: {node: '>=6'}
@ -3470,6 +3581,9 @@ packages:
resolution: {integrity: sha512-NHDDGYudnvRutt/VhKFlX26IotXe1w0cmkDm6JGquh5bz/bDTw0LufSmH/GxTjEdpHEO+bVKFTwdrcGa/9XlKQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
node-fetch-native@1.6.7:
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
@ -3862,9 +3976,126 @@ packages:
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
safe-identifier@0.4.2:
resolution: {integrity: sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==}
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
sass-embedded-all-unknown@1.96.0:
resolution: {integrity: sha512-UfUHoWZtxmsDjDfK+fKCy0aJe6zThu7oaIQx0c/vnHgvprcddEPIay01qTXhiUa3cFcsMmvlBvPTVw0gjKVtVQ==}
cpu: ['!arm', '!arm64', '!riscv64', '!x64']
sass-embedded-android-arm64@1.96.0:
resolution: {integrity: sha512-TJiebTo4TBF5Wrn+lFkUfSN3wazvl8kkFm9a1nA9ZtRdaE0nsJLGnMM6KLQLP2Vl+IOf6ovetZseISkClRoGXw==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [android]
sass-embedded-android-arm@1.96.0:
resolution: {integrity: sha512-0mwVRBFig9hH8vFcRExBuBoR+CfUOcWdwarZwbxIFGI1IyH4BLBGiX85vVn6ssSCVNydpE6lFGm45CN8O0tQig==}
engines: {node: '>=14.0.0'}
cpu: [arm]
os: [android]
sass-embedded-android-riscv64@1.96.0:
resolution: {integrity: sha512-7AVu/EeJqKN3BGNhm+tc1XzmoqbOtCwHG2VgN6j6Lyqh1JZlx0dglRtyQuKDZ7odTKiWmotEIuYZ6OxLmr2Ejg==}
engines: {node: '>=14.0.0'}
cpu: [riscv64]
os: [android]
sass-embedded-android-x64@1.96.0:
resolution: {integrity: sha512-ei/UsT0q8rF5JzWhn1A7B0M1y/IiWVY3l4zibQrXk5MGaOXHlCM6ffZD+2j7C613Jm9/KAQ7yX1NIIu72LPgDQ==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [android]
sass-embedded-darwin-arm64@1.96.0:
resolution: {integrity: sha512-OMvN5NWcrrisC24ZR3GyaWJ1uFxw25qLnUkpEso9TSlaMWiomjU82/uQ/AkQvIMl+EMlJqeYLxZWvq/byLH5Xg==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [darwin]
sass-embedded-darwin-x64@1.96.0:
resolution: {integrity: sha512-J/R5sv0eW+/DU98rccHPO1f3lsTFjVTpdkU9d3P1yB7BFmQjw5PYde9BVRlXeOawPwfgT3p/hvY4RELScICdww==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [darwin]
sass-embedded-linux-arm64@1.96.0:
resolution: {integrity: sha512-VcbVjK0/O/mru0h0FC1WSUWIzMqRrzuJ8eZNMXTs4vApfkh28pxNaUodwU81f1L1nngJ3vpFDBniUKpW6NwJhw==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [linux]
sass-embedded-linux-arm@1.96.0:
resolution: {integrity: sha512-XuQvV6gNld5Bz3rX0SFLtKPGMu4UQdXNp//9A+bDmtVGZ6yu8REIqphQBxOMpgkAKsA4JZLKKk1N97woeVsIlA==}
engines: {node: '>=14.0.0'}
cpu: [arm]
os: [linux]
sass-embedded-linux-musl-arm64@1.96.0:
resolution: {integrity: sha512-lVyLObEeu8Wgw8riC6dSMlkF7jVNAjdZ1jIBhvX1yDsrQwwaI60pM21YXmnZSFyCE6KVFkKAgwRQNO/IkoCwMA==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [linux]
sass-embedded-linux-musl-arm@1.96.0:
resolution: {integrity: sha512-qK7FrnczCVECZXtyYOoI3azFlMDZn70GI1yJPPuZLpWvwIPYoZOLv3u6JSec5o3wT6KeKyWG3ZpGIpigLUjPig==}
engines: {node: '>=14.0.0'}
cpu: [arm]
os: [linux]
sass-embedded-linux-musl-riscv64@1.96.0:
resolution: {integrity: sha512-Y+DuGVRsM2zGl268QN5aF/Y6OFYTILb3f+6huEXKlGL6FK2MXadsmeoVbmKVrTamQHzyA2bWWMU1C0jhVFtlzg==}
engines: {node: '>=14.0.0'}
cpu: [riscv64]
os: [linux]
sass-embedded-linux-musl-x64@1.96.0:
resolution: {integrity: sha512-sAQtUQ8fFNxnxSf3fncOh892Hfxa4PW4e5qrnSE0Y1IGV/wsTzk7m5Z6IeT7sa3BsvXh5TFN6+JGbUoOJ5RigA==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [linux]
sass-embedded-linux-riscv64@1.96.0:
resolution: {integrity: sha512-Bf6bAjuUm6sfGHo0XoZEstjVkEWwmmtOSomGoPuAwXFS9GQnFcqDz9EXKNkZEOsQi2D+aDeDxs8HcU9/OLMT9g==}
engines: {node: '>=14.0.0'}
cpu: [riscv64]
os: [linux]
sass-embedded-linux-x64@1.96.0:
resolution: {integrity: sha512-U4GROkS0XM6ekqs/ubroWwFAGY9N35wqrt5q6Y+MJCpTK5bHPHlgFo7J75ZUSaEObL+UrDqvMDQkCdYEFiiQbg==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [linux]
sass-embedded-unknown-all@1.96.0:
resolution: {integrity: sha512-OHzGEr2VElK2SaQdkkTX0O0KwTbiv1N/EhnHgzXYaZWOTvv0gxEfR7q7x/oScCBIZc2x8dSfvThfBnohIClo/w==}
os: ['!android', '!darwin', '!linux', '!win32']
sass-embedded-win32-arm64@1.96.0:
resolution: {integrity: sha512-KKz1h5pr45fwrKcxrxHsujo3f/HgVkX64YNJ9PRPuOuX7lU8g18IEgDxoTGQ64PPBQ5RXOt6jxpT+x2OLPVnCw==}
engines: {node: '>=14.0.0'}
cpu: [arm64]
os: [win32]
sass-embedded-win32-x64@1.96.0:
resolution: {integrity: sha512-MDreKaWcgiyKD5YPShaRvUBoe5dC2y8IPJK49G7iQjoMfw9INDCBkDdLcz00Mn0eJq4nJJp5UEE98M6ljIrBRg==}
engines: {node: '>=14.0.0'}
cpu: [x64]
os: [win32]
sass-embedded@1.96.0:
resolution: {integrity: sha512-z9PQ7owvdhn7UuZGrpPccdkcH9xJd9iCv+UQhcPqppBslYEp0R9LRQVyyPTZg7jfA77bGxz/I8V48LXJR5LjXQ==}
engines: {node: '>=16.0.0'}
hasBin: true
sass@1.96.0:
resolution: {integrity: sha512-8u4xqqUeugGNCYwr9ARNtQKTOj4KmYiJAVKXf2CTIivTCR51j96htbMKWDru8H5SaQWpyVgTfOF8Ylyf5pun1Q==}
engines: {node: '>=14.0.0'}
hasBin: true
saxes@6.0.0:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
engines: {node: '>=v12.22.7'}
@ -4067,6 +4298,14 @@ packages:
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
sync-child-process@1.0.2:
resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==}
engines: {node: '>=16.0.0'}
sync-message-port@1.1.3:
resolution: {integrity: sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==}
engines: {node: '>=16.0.0'}
temp-dir@3.0.0:
resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==}
engines: {node: '>=14.16'}
@ -4307,6 +4546,9 @@ packages:
resolution: {integrity: sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==}
engines: {node: '>= 0.10'}
varint@6.0.0:
resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
vite-node@1.6.1:
resolution: {integrity: sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==}
engines: {node: ^18.0.0 || >=20.0.0}
@ -4790,6 +5032,8 @@ snapshots:
'@bcoe/v8-coverage@0.2.3': {}
'@bufbuild/protobuf@2.10.1': {}
'@cloudflare/kv-asset-handler@0.4.1':
dependencies:
mime: 3.0.0
@ -4838,7 +5082,7 @@ snapshots:
'@lezer/lr': 1.4.3
style-mod: 4.1.3
'@codemirror/language@https://codeload.github.com/lishid/cm-language/tar.gz/a9c3c7efe17dd1d24395ee2a179fe12dd6ed1e76':
'@codemirror/language@https://codeload.github.com/lishid/cm-language/tar.gz/2d416d7835867d1b1e8d0e726b147fc1135c9f92':
dependencies:
'@codemirror/state': 6.5.2
'@codemirror/view': 6.38.8
@ -5832,6 +6076,67 @@ snapshots:
dependencies:
'@octokit/openapi-types': 27.0.0
'@parcel/watcher-android-arm64@2.5.1':
optional: true
'@parcel/watcher-darwin-arm64@2.5.1':
optional: true
'@parcel/watcher-darwin-x64@2.5.1':
optional: true
'@parcel/watcher-freebsd-x64@2.5.1':
optional: true
'@parcel/watcher-linux-arm-glibc@2.5.1':
optional: true
'@parcel/watcher-linux-arm-musl@2.5.1':
optional: true
'@parcel/watcher-linux-arm64-glibc@2.5.1':
optional: true
'@parcel/watcher-linux-arm64-musl@2.5.1':
optional: true
'@parcel/watcher-linux-x64-glibc@2.5.1':
optional: true
'@parcel/watcher-linux-x64-musl@2.5.1':
optional: true
'@parcel/watcher-win32-arm64@2.5.1':
optional: true
'@parcel/watcher-win32-ia32@2.5.1':
optional: true
'@parcel/watcher-win32-x64@2.5.1':
optional: true
'@parcel/watcher@2.5.1':
dependencies:
detect-libc: 1.0.3
is-glob: 4.0.3
micromatch: 4.0.8
node-addon-api: 7.1.1
optionalDependencies:
'@parcel/watcher-android-arm64': 2.5.1
'@parcel/watcher-darwin-arm64': 2.5.1
'@parcel/watcher-darwin-x64': 2.5.1
'@parcel/watcher-freebsd-x64': 2.5.1
'@parcel/watcher-linux-arm-glibc': 2.5.1
'@parcel/watcher-linux-arm-musl': 2.5.1
'@parcel/watcher-linux-arm64-glibc': 2.5.1
'@parcel/watcher-linux-arm64-musl': 2.5.1
'@parcel/watcher-linux-x64-glibc': 2.5.1
'@parcel/watcher-linux-x64-musl': 2.5.1
'@parcel/watcher-win32-arm64': 2.5.1
'@parcel/watcher-win32-ia32': 2.5.1
'@parcel/watcher-win32-x64': 2.5.1
optional: true
'@phun-ky/typeof@2.0.3': {}
'@polka/url@1.0.0-next.29': {}
@ -6206,7 +6511,7 @@ snapshots:
std-env: 3.10.0
strip-literal: 2.1.1
test-exclude: 6.0.0
vitest: 1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(terser@5.44.1)
vitest: 1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
transitivePeerDependencies:
- supports-color
@ -6241,7 +6546,7 @@ snapshots:
pathe: 1.1.2
picocolors: 1.1.1
sirv: 2.0.4
vitest: 1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(terser@5.44.1)
vitest: 1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
'@vitest/utils@1.6.1':
dependencies:
@ -6473,6 +6778,8 @@ snapshots:
dependencies:
node-int64: 0.4.0
buffer-builder@0.2.0: {}
buffer-from@1.1.2: {}
builtin-modules@3.3.0: {}
@ -6621,6 +6928,8 @@ snapshots:
color-convert: 2.0.1
color-string: 1.9.1
colorjs.io@0.5.2: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
@ -6877,6 +7186,9 @@ snapshots:
detect-indent@7.0.1: {}
detect-libc@1.0.3:
optional: true
detect-libc@2.1.2: {}
detect-newline@3.1.0: {}
@ -6961,6 +7273,14 @@ snapshots:
has-tostringtag: 1.0.2
hasown: 2.0.2
esbuild-sass-plugin@3.3.1(esbuild@0.25.9)(sass-embedded@1.96.0):
dependencies:
esbuild: 0.25.9
resolve: 1.22.11
safe-identifier: 0.4.2
sass: 1.96.0
sass-embedded: 1.96.0
esbuild@0.21.5:
optionalDependencies:
'@esbuild/aix-ppc64': 0.21.5
@ -7488,6 +7808,8 @@ snapshots:
immediate@3.0.6: {}
immutable@5.1.4: {}
import-fresh@3.3.1:
dependencies:
parent-module: 1.0.1
@ -8291,6 +8613,9 @@ snapshots:
dependencies:
type-fest: 2.19.0
node-addon-api@7.1.1:
optional: true
node-fetch-native@1.6.7: {}
node-int64@0.4.0: {}
@ -8784,8 +9109,106 @@ snapshots:
safe-buffer@5.2.1: {}
safe-identifier@0.4.2: {}
safer-buffer@2.1.2: {}
sass-embedded-all-unknown@1.96.0:
dependencies:
sass: 1.96.0
optional: true
sass-embedded-android-arm64@1.96.0:
optional: true
sass-embedded-android-arm@1.96.0:
optional: true
sass-embedded-android-riscv64@1.96.0:
optional: true
sass-embedded-android-x64@1.96.0:
optional: true
sass-embedded-darwin-arm64@1.96.0:
optional: true
sass-embedded-darwin-x64@1.96.0:
optional: true
sass-embedded-linux-arm64@1.96.0:
optional: true
sass-embedded-linux-arm@1.96.0:
optional: true
sass-embedded-linux-musl-arm64@1.96.0:
optional: true
sass-embedded-linux-musl-arm@1.96.0:
optional: true
sass-embedded-linux-musl-riscv64@1.96.0:
optional: true
sass-embedded-linux-musl-x64@1.96.0:
optional: true
sass-embedded-linux-riscv64@1.96.0:
optional: true
sass-embedded-linux-x64@1.96.0:
optional: true
sass-embedded-unknown-all@1.96.0:
dependencies:
sass: 1.96.0
optional: true
sass-embedded-win32-arm64@1.96.0:
optional: true
sass-embedded-win32-x64@1.96.0:
optional: true
sass-embedded@1.96.0:
dependencies:
'@bufbuild/protobuf': 2.10.1
buffer-builder: 0.2.0
colorjs.io: 0.5.2
immutable: 5.1.4
rxjs: 7.8.2
supports-color: 8.1.1
sync-child-process: 1.0.2
varint: 6.0.0
optionalDependencies:
sass-embedded-all-unknown: 1.96.0
sass-embedded-android-arm: 1.96.0
sass-embedded-android-arm64: 1.96.0
sass-embedded-android-riscv64: 1.96.0
sass-embedded-android-x64: 1.96.0
sass-embedded-darwin-arm64: 1.96.0
sass-embedded-darwin-x64: 1.96.0
sass-embedded-linux-arm: 1.96.0
sass-embedded-linux-arm64: 1.96.0
sass-embedded-linux-musl-arm: 1.96.0
sass-embedded-linux-musl-arm64: 1.96.0
sass-embedded-linux-musl-riscv64: 1.96.0
sass-embedded-linux-musl-x64: 1.96.0
sass-embedded-linux-riscv64: 1.96.0
sass-embedded-linux-x64: 1.96.0
sass-embedded-unknown-all: 1.96.0
sass-embedded-win32-arm64: 1.96.0
sass-embedded-win32-x64: 1.96.0
sass@1.96.0:
dependencies:
chokidar: 4.0.3
immutable: 5.1.4
source-map-js: 1.2.1
optionalDependencies:
'@parcel/watcher': 2.5.1
saxes@6.0.0:
dependencies:
xmlchars: 2.2.0
@ -8984,6 +9407,12 @@ snapshots:
symbol-tree@3.2.4: {}
sync-child-process@1.0.2:
dependencies:
sync-message-port: 1.1.3
sync-message-port@1.1.3: {}
temp-dir@3.0.0: {}
tempfile@5.0.0:
@ -9171,13 +9600,15 @@ snapshots:
validator@13.15.23: {}
vite-node@1.6.1(@types/node@20.19.25)(terser@5.44.1):
varint@6.0.0: {}
vite-node@1.6.1(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1):
dependencies:
cac: 6.7.14
debug: 4.4.3
pathe: 1.1.2
picocolors: 1.1.1
vite: 5.4.21(@types/node@20.19.25)(terser@5.44.1)
vite: 5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
transitivePeerDependencies:
- '@types/node'
- less
@ -9189,7 +9620,7 @@ snapshots:
- supports-color
- terser
vite-plugin-dts@3.9.1(@types/node@20.19.25)(rollup@4.53.3)(typescript@5.9.3)(vite@5.4.21(@types/node@20.19.25)(terser@5.44.1)):
vite-plugin-dts@3.9.1(@types/node@20.19.25)(rollup@4.53.3)(typescript@5.9.3)(vite@5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)):
dependencies:
'@microsoft/api-extractor': 7.43.0(@types/node@20.19.25)
'@rollup/pluginutils': 5.3.0(rollup@4.53.3)
@ -9200,13 +9631,13 @@ snapshots:
typescript: 5.9.3
vue-tsc: 1.8.27(typescript@5.9.3)
optionalDependencies:
vite: 5.4.21(@types/node@20.19.25)(terser@5.44.1)
vite: 5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
transitivePeerDependencies:
- '@types/node'
- rollup
- supports-color
vite@5.4.21(@types/node@20.19.25)(terser@5.44.1):
vite@5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1):
dependencies:
esbuild: 0.21.5
postcss: 8.5.6
@ -9214,9 +9645,11 @@ snapshots:
optionalDependencies:
'@types/node': 20.19.25
fsevents: 2.3.3
sass: 1.96.0
sass-embedded: 1.96.0
terser: 5.44.1
vitest@1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(terser@5.44.1):
vitest@1.6.1(@types/node@20.19.25)(@vitest/ui@1.6.1)(jsdom@23.2.0)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1):
dependencies:
'@vitest/expect': 1.6.1
'@vitest/runner': 1.6.1
@ -9235,8 +9668,8 @@ snapshots:
strip-literal: 2.1.1
tinybench: 2.9.0
tinypool: 0.8.4
vite: 5.4.21(@types/node@20.19.25)(terser@5.44.1)
vite-node: 1.6.1(@types/node@20.19.25)(terser@5.44.1)
vite: 5.4.21(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
vite-node: 1.6.1(@types/node@20.19.25)(sass-embedded@1.96.0)(sass@1.96.0)(terser@5.44.1)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 20.19.25

View file

@ -52,10 +52,10 @@ import {
type CalendarEvent as AdapterCalendarEvent,
} from "@/utils/adapters/TaskCalendarAdapter";
import "@taskgenius/calendar/styles.css";
import "@/styles/taskgenius-calendar.css";
import "@/styles/calendar/view.css";
import "@/styles/calendar/event.css";
import "@/styles/calendar/badge.css";
import "@/styles/taskgenius-calendar.scss";
import "@/styles/calendar/view.scss";
import "@/styles/calendar/event.scss";
import "@/styles/calendar/badge.scss";
import { t } from "@/translations/helper";
// Import new TG-based view implementations

View file

@ -6,7 +6,7 @@ import {
TFile,
} from "obsidian";
import { type Task } from "@/types/task";
import "@/styles/gantt/gantt.css";
import "@/styles/gantt/gantt.scss";
// Import new components and helpers
import { DateHelper } from "@/utils/date/date-helper";

View file

@ -20,7 +20,7 @@ import {
import TaskProgressBarPlugin from '@/index';
import { t } from '@/translations/helper';
import { attachIconMenu } from '@/components/ui/menus/IconMenu';
import "@/styles/habit-edit-dialog.css";
import "@/styles/habit-edit-dialog.scss";
export class HabitEditDialog extends Modal {
plugin: TaskProgressBarPlugin;

View file

@ -10,7 +10,7 @@ import { BaseHabitData } from "@/types/habit-card";
import TaskProgressBarPlugin from "@/index";
import { HabitEditDialog } from "@/components/features/habit/components/HabitEditDialog";
import { t } from "@/translations/helper";
import "@/styles/habit-list.css";
import "@/styles/habit-list.scss";
export interface HabitSettings {
habits: BaseHabitData[];

View file

@ -22,7 +22,7 @@ import {
MappingHabitCard,
} from "./habitcard/index"; // Import the habit card classes
import { t } from "@/translations/helper";
import "@/styles/habit.css";
import "@/styles/habit.scss";
import { HabitEditDialog } from "@/components/features/habit/components/HabitEditDialog";
export class Habit extends Component {

View file

@ -6,7 +6,7 @@ import {
} from "@/utils/date/date-formatter";
import { HabitCard } from "@/components/features/habit/habitcard/habitcard";
import { t } from "@/translations/helper";
import "@/styles/habit.css";
import "@/styles/habit.scss";
export class HabitChartModal extends Modal {
private habit: DailyHabitProps;

View file

@ -1,7 +1,7 @@
import { App, Modal, Setting } from "obsidian";
import { RewardItem } from '@/common/setting-definition';
import { t } from '@/translations/helper';
import "@/styles/reward.css";
import "@/styles/reward.scss";
export class RewardModal extends Modal {
private reward: RewardItem;

View file

@ -11,7 +11,7 @@ import { Task } from "@/types/task"; // Adjust path as needed
import { KanbanColumnComponent } from "./kanban-column";
// import { DragManager, DragMoveEvent, DragEndEvent } from "@/components/ui/behavior/DragManager";
import Sortable from "sortablejs";
import "@/styles/kanban/kanban.css";
import "@/styles/kanban/kanban.scss";
import { t } from "@/translations/helper"; // Added import for t
import {
FilterComponent,

View file

@ -17,7 +17,7 @@ import {
FileLocationSuggest,
ActionTypeSuggest,
} from "./OnCompletionSuggesters";
import "@/styles/onCompletion.css";
import "@/styles/onCompletion.scss";
export interface OnCompletionConfiguratorOptions {
initialValue?: string;

View file

@ -5,7 +5,7 @@ import {
} from "./OnCompletionConfigurator";
import TaskProgressBarPlugin from "@/index";
import { t } from "@/translations/helper";
import "@/styles/onCompletion.css";
import "@/styles/onCompletion.scss";
export interface OnCompletionModalOptions {
initialValue?: string;

View file

@ -6,7 +6,7 @@ import {
FolderSuggest,
SimpleFileSuggest as FileSuggest,
} from "@/components/ui/inputs/AutoComplete";
import "@/styles/file-filter-settings.css";
import "@/styles/file-filter-settings.scss";
interface FileFilterRuleEditorModalOptions {
autoAddRuleType?: FileFilterRule["type"];

View file

@ -8,8 +8,8 @@ import {
SimpleFileSuggest as FileSuggest,
} from "@/components/ui/inputs/AutoComplete";
import { FileFilterRuleEditorModal } from "@/components/features/onboarding/modals/FileFilterRuleEditorModal";
import "@/styles/onboarding-components.css";
import "@/styles/file-filter-settings.css";
import "@/styles/onboarding-components.scss";
import "@/styles/file-filter-settings.scss";
/**
* File Filter Configuration Step

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
type ComponentType = "sidebar" | "topnav" | "content" | "project";

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
export class FluentMainNavigationStep {
static render(

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
export class FluentOtherViewsStep {
static render(

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
export class FluentOverviewStep {
static render(

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
export class FluentProjectSectionStep {
static render(

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
export class FluentTopNavigationStep {
static render(

View file

@ -1,7 +1,7 @@
import { t } from "@/translations/helper";
import { OnboardingController } from "../OnboardingController";
import { ComponentPreviewFactory } from "../previews/ComponentPreviewFactory";
import "@/styles/onboarding-components.css";
import "@/styles/onboarding-components.scss";
export class FluentWorkspaceSelectorStep {
static render(

View file

@ -2,7 +2,7 @@ import { t } from "@/translations/helper";
import { SelectableCard, SelectableCardConfig } from "../ui/SelectableCard";
import { OnboardingController } from "../OnboardingController";
import { Alert } from "../ui/Alert";
import "@/styles/layout-placement.css";
import "@/styles/layout-placement.scss";
export type Placement = "sideleaves" | "inline";

View file

@ -4,7 +4,7 @@ import { Task } from "@/types/task";
import { QuadrantDefinition } from './quadrant';
import { QuadrantCardComponent } from "./quadrant-card";
import { t } from "@/translations/helper";
import "@/styles/quadrant/quadrant.css";
import "@/styles/quadrant/quadrant.scss";
export class QuadrantColumnComponent extends Component {
plugin: TaskProgressBarPlugin;

View file

@ -3,7 +3,7 @@ import TaskProgressBarPlugin from "@/index";
import { Task } from "@/types/task";
import { QuadrantColumnComponent } from "./quadrant-column";
import Sortable from "sortablejs";
import "@/styles/quadrant/quadrant.css";
import "@/styles/quadrant/quadrant.scss";
import { t } from "@/translations/helper";
import { FilterComponent } from "@/components/features/task/filter/in-view/filter";
import { ActiveFilter } from "@/components/features/task/filter/in-view/filter-type";

View file

@ -4,7 +4,7 @@ import { CustomCalendarViewConfig } from "@/common/setting-definition";
import { t } from "@/translations/helper";
import { CalendarViewConfigModal } from "@/components/ui/modals/CalendarViewConfigModal";
import Sortable from "sortablejs";
import "@/styles/calendar-view-settings.css";
import "@/styles/calendar-view-settings.scss";
/**
* Built-in calendar view templates that users can use as base

View file

@ -6,7 +6,7 @@ import {
FolderSuggest,
SimpleFileSuggest as FileSuggest,
} from "@/components/ui/inputs/AutoComplete";
import "@/styles/file-filter-settings.css";
import "@/styles/file-filter-settings.scss";
export function renderFileFilterSettingsTab(
settingTab: TaskProgressBarSettingTab,

View file

@ -22,7 +22,7 @@ import {
} from "@/types/ics";
import { t } from "@/translations/helper";
import TaskProgressBarPlugin from "@/index";
import "@/styles/ics-settings.css";
import "@/styles/ics-settings.scss";
import { HolidayDetector } from "@/parsers/holiday-detector";
import { WebcalUrlConverter } from "@/parsers/webcal-converter";

View file

@ -1,276 +1,91 @@
import { Setting, Notice } from "obsidian";
import { TaskProgressBarSettingTab } from "@/setting";
import { t } from "@/translations/helper";
import {
SelectableCard,
SelectableCardConfig,
} from "@/components/features/onboarding/ui/SelectableCard";
import { FluentViewSettings } from "@/common/setting-definition";
export function renderInterfaceSettingsTab(
settingTab: TaskProgressBarSettingTab,
containerEl: HTMLElement
containerEl: HTMLElement,
) {
// Header
new Setting(containerEl)
.setName(t("User Interface"))
.setDesc(
t(
"Choose your preferred interface style and configure how Task Genius displays in your workspace."
)
)
.setDesc(t("Configure how Task Genius displays in your workspace."))
.setHeading();
// Mode Selection Section
// Fluent Interface Settings
new Setting(containerEl)
.setName(t("Interface Mode"))
.setDesc(
t(
"Select between the modern Fluent interface or the classic Legacy interface."
)
)
.setName(t("Interface Settings"))
.setDesc(t("Configure options for the Task Genius interface."))
.setHeading();
// Create mode selection container
const modeSelectionContainer = containerEl.createDiv({
cls: "interface-mode-selection",
});
// Get current mode
const currentMode = settingTab.plugin.settings.fluentView?.enableFluent
? "fluent"
: "legacy";
// Create cards configuration
const cardConfigs: SelectableCardConfig<string>[] = [
{
id: "fluent",
title: t("Fluent"),
subtitle: t("Modern & Sleek"),
description: t(
"New visual design with elegant animations and modern interactions"
// Use workspace side leaves for Sidebar & Details
new Setting(containerEl)
.setName(t("Use workspace side leaves"))
.setDesc(
t(
"Use left/right workspace side leaves for Sidebar and Details. When enabled, the main view won't render in-view sidebar or details.",
),
preview: createFluentPreview(),
},
{
id: "legacy",
title: t("Legacy"),
subtitle: t("Classic & Familiar"),
description: t(
"Keep the familiar interface and interaction style you know"
)
.addToggle((toggle) => {
const current =
settingTab.plugin.settings.fluentView?.useWorkspaceSideLeaves ??
false;
toggle.setValue(current).onChange(async (value) => {
if (!settingTab.plugin.settings.fluentView) {
settingTab.plugin.settings.fluentView = {
enableFluent: true,
};
}
if (!settingTab.plugin.settings.fluentView.fluentConfig) {
settingTab.plugin.settings.fluentView.fluentConfig = {
enableWorkspaces: true,
defaultWorkspace: "default",
};
}
(
settingTab.plugin.settings.fluentView as FluentViewSettings
).useWorkspaceSideLeaves = value;
await settingTab.plugin.saveSettings();
new Notice(t("Saved. Reopen the view to apply."));
});
});
// Max Other Views before overflow threshold
new Setting(containerEl)
.setName(t("Max other views before overflow"))
.setDesc(
t(
"Number of 'Other Views' to show before grouping the rest into an overflow menu (ellipsis)",
),
preview: createLegacyPreview(),
},
];
// Create selectable cards
const card = new SelectableCard<string>(
modeSelectionContainer,
cardConfigs,
{
containerClass: "selectable-cards-container",
cardClass: "selectable-card",
showPreview: true,
},
async (mode) => {
// Update settings
if (!settingTab.plugin.settings.fluentView) {
settingTab.plugin.settings.fluentView = {
enableFluent: false,
};
}
settingTab.plugin.settings.fluentView.enableFluent =
mode === "fluent";
await settingTab.plugin.saveSettings();
// Re-render the settings to show/hide Fluent-specific options
renderFluentSpecificSettings();
}
);
// Set initial selection
card.setSelected(currentMode);
// Container for Fluent-specific settings
const fluentSettingsContainer = containerEl.createDiv({
cls: "fluent-specific-settings",
});
// Function to render Fluent-specific settings
const renderFluentSpecificSettings = () => {
// Clear the container
fluentSettingsContainer.empty();
// Only show if Fluent is enabled
if (!settingTab.plugin.settings.fluentView?.enableFluent) {
return;
}
// Fluent Settings Header
new Setting(fluentSettingsContainer)
.setName(t("Fluent Interface Settings"))
.setDesc(t("Configure options specific to the Fluent interface."))
.setHeading();
new Setting(fluentSettingsContainer)
.setName(t("Interface Style"))
.setDesc(t("Select the interface style to use."))
.addDropdown((dropdown) => {
dropdown.addOption("modern", t("Modern"));
dropdown.addOption("classic", t("Classic"));
dropdown
.setValue(
settingTab.plugin.settings.fluentView?.interfaceStyle ||
"modern"
)
.onChange(async (value) => {
)
.addText((text) => {
const current =
settingTab.plugin.settings.fluentView?.fluentConfig
?.maxOtherViewsBeforeOverflow ?? 5;
text.setPlaceholder("5")
.setValue(String(current))
.onChange(async (value) => {
const n = parseInt(value, 10);
if (!isNaN(n) && n >= 1 && n <= 50) {
if (!settingTab.plugin.settings.fluentView) {
settingTab.plugin.settings.fluentView = {
enableFluent: false,
interfaceStyle: "modern",
useWorkspaceSideLeaves: false,
fluentConfig: {
enableWorkspaces: true,
defaultWorkspace: "default",
maxOtherViewsBeforeOverflow: 5,
},
enableFluent: true,
};
}
settingTab.plugin.settings.fluentView.interfaceStyle =
value as "modern" | "classic";
await settingTab.plugin.saveSettings();
new Notice(t("Saved. Reopen the view to apply."));
});
});
// Use workspace side leaves for Sidebar & Details
new Setting(fluentSettingsContainer)
.setName(t("Use workspace side leaves"))
.setDesc(
t(
"Use left/right workspace side leaves for Sidebar and Details. When enabled, the main fluent view won't render in-view sidebar or details."
)
)
.addToggle((toggle) => {
const current =
settingTab.plugin.settings.fluentView
?.useWorkspaceSideLeaves ?? false;
toggle.setValue(current).onChange(async (value) => {
if (!settingTab.plugin.settings.fluentView) {
settingTab.plugin.settings.fluentView = {
enableFluent: false,
};
}
if (!settingTab.plugin.settings.fluentView.fluentConfig) {
settingTab.plugin.settings.fluentView.fluentConfig = {
enableWorkspaces: true,
defaultWorkspace: "default",
};
}
// Store via 'any' to avoid typing constraints for experimental backfill
(
settingTab.plugin.settings
.fluentView as FluentViewSettings
).useWorkspaceSideLeaves = value;
await settingTab.plugin.saveSettings();
new Notice(t("Saved. Reopen the view to apply."));
});
});
// Max Other Views before overflow threshold
new Setting(fluentSettingsContainer)
.setName(t("Max other views before overflow"))
.setDesc(
t(
"Number of 'Other Views' to show before grouping the rest into an overflow menu (ellipsis)"
)
)
.addText((text) => {
const current =
settingTab.plugin.settings.fluentView?.fluentConfig
?.maxOtherViewsBeforeOverflow ?? 5;
text.setPlaceholder("5")
.setValue(String(current))
.onChange(async (value) => {
const n = parseInt(value, 10);
if (!isNaN(n) && n >= 1 && n <= 50) {
if (!settingTab.plugin.settings.fluentView) {
settingTab.plugin.settings.fluentView = {
enableFluent: false,
if (
!settingTab.plugin.settings.fluentView.fluentConfig
) {
settingTab.plugin.settings.fluentView.fluentConfig =
{
enableWorkspaces: true,
defaultWorkspace: "default",
};
}
if (
!settingTab.plugin.settings.fluentView
.fluentConfig
) {
settingTab.plugin.settings.fluentView.fluentConfig =
{
enableWorkspaces: true,
defaultWorkspace: "default",
};
}
settingTab.plugin.settings.fluentView.fluentConfig.maxOtherViewsBeforeOverflow =
n;
await settingTab.plugin.saveSettings();
}
});
});
};
// Initial render of Fluent-specific settings
renderFluentSpecificSettings();
}
/**
* Create Fluent mode preview
*/
function createFluentPreview(): HTMLElement {
const preview = createDiv({
cls: ["mode-preview", "mode-preview-fluent"],
});
// Check theme
const isDark = document.body.classList.contains("theme-dark");
const theme = isDark ? "" : "-light";
const imageUrl = `https://raw.githubusercontent.com/Quorafind/Obsidian-Task-Progress-Bar/master/media/fluent${theme}.png`;
const img = preview.createEl("img", {
attr: {
src: imageUrl,
alt: "Fluent mode preview",
},
});
img.style.maxWidth = "100%";
img.style.maxHeight = "100%";
img.style.objectFit = "contain";
img.style.borderRadius = "4px";
return preview;
}
/**
* Create Legacy mode preview
*/
function createLegacyPreview(): HTMLElement {
const preview = createDiv({
cls: ["mode-preview", "mode-preview-legacy"],
});
// Check theme
const isDark = document.body.classList.contains("theme-dark");
const theme = isDark ? "" : "-light";
const imageUrl = `https://raw.githubusercontent.com/Quorafind/Obsidian-Task-Progress-Bar/master/media/legacy${theme}.png`;
const img = preview.createEl("img", {
attr: {
src: imageUrl,
alt: "Legacy mode preview",
},
});
img.style.maxWidth = "100%";
img.style.maxHeight = "100%";
img.style.objectFit = "contain";
img.style.borderRadius = "4px";
return preview;
settingTab.plugin.settings.fluentView.fluentConfig.maxOtherViewsBeforeOverflow =
n;
await settingTab.plugin.saveSettings();
}
});
});
}

View file

@ -9,7 +9,7 @@ import { McpServerManager } from "@/mcp/McpServerManager";
import { AuthMiddleware } from "@/mcp/auth/AuthMiddleware";
import { ConfirmModal } from "@/components/ui/modals/ConfirmModal";
import { McpLogModal } from "@/components/ui/modals/McpLogModal";
import "@/styles/mcp-integration.css";
import "@/styles/mcp-integration.scss";
import { TaskProgressBarSettingTab } from "@/setting";
function createConfigBlock(

View file

@ -5,7 +5,7 @@ import { TaskProgressBarSettingTab } from "@/setting";
import { ViewConfigModal } from "@/components/features/task/view/modals/ViewConfigModal";
import { TaskFilterComponent } from "@/components/features/task/filter/ViewTaskFilter";
import Sortable from "sortablejs";
import "@/styles/view-setting-tab.css";
import "@/styles/view-setting-tab.scss";
export function renderViewSettingsTab(
settingTab: TaskProgressBarSettingTab,

View file

@ -14,7 +14,7 @@ import { VirtualScrollManager } from "./VirtualScrollManager";
import { TableHeader, TableHeaderCallbacks } from "./TableHeader";
import { sortTasks } from "@/commands/sortTaskCommands";
import { isProjectReadonly } from "@/utils/task/task-operations";
import "@/styles/table.css";
import "@/styles/table.scss";
export interface TableViewCallbacks {
onTaskSelected?: (task: Task | null) => void;

View file

@ -10,7 +10,7 @@ import {
} from "obsidian";
import Sortable from "sortablejs";
import { t } from "@/translations/helper"; // Adjusted path assuming helper.ts is in src/translations
import "@/styles/global-filter.css";
import "@/styles/global-filter.scss";
import { FilterConfigModal } from "./FilterConfigModal";
import type TaskProgressBarPlugin from "@/index";

View file

@ -6,7 +6,7 @@ import {
FilterCategory,
FilterComponentOptions,
} from "./filter-type";
import "./filter.css";
import "./filter.scss";
import { Task } from "@/types/task";
import TaskProgressBarPlugin from "@/index";
import { t } from "@/translations/helper";

View file

@ -11,7 +11,7 @@ import {
createEmbeddableMarkdownEditor,
EmbeddableMarkdownEditor,
} from "@/editor-extensions/core/markdown-editor";
import "@/styles/inline-editor.css";
import "@/styles/inline-editor.scss";
import {
getEffectiveProject,
isProjectReadonly,

View file

@ -1,9 +1,9 @@
import { App, setIcon } from "obsidian";
import { Task } from "@/types/task";
import { t } from "@/translations/helper";
import "@/styles/project-view.css";
import "@/styles/view-two-column-base.css";
import "@/styles/project-tree.css";
import "@/styles/project-view.scss";
import "@/styles/view-two-column-base.scss";
import "@/styles/project-tree.scss";
import TaskProgressBarPlugin from "@/index";
import { TwoColumnViewBase, TwoColumnViewConfig } from "./TwoColumnViewBase";
import { ProjectTreeComponent } from "./ProjectTreeComponent";

View file

@ -1,8 +1,8 @@
import { App, setIcon } from "obsidian";
import { Task } from "@/types/task";
import { t } from "@/translations/helper";
import "@/styles/tag-view.css";
import "@/styles/view-two-column-base.css";
import "@/styles/tag-view.scss";
import "@/styles/view-two-column-base.scss";
import { TaskListRendererComponent } from "./TaskList";
import TaskProgressBarPlugin from "@/index";
import { TwoColumnViewBase, TwoColumnViewConfig } from "./TwoColumnViewBase";

View file

@ -5,7 +5,7 @@ import { TwoColumnViewBase, TwoColumnViewConfig } from "./TwoColumnViewBase";
import { t } from "@/translations/helper";
import TaskProgressBarPlugin from "@/index";
import { TwoColumnSpecificConfig } from "@/common/setting-definition";
import "@/styles/property-view.css";
import "@/styles/property-view.scss";
import { getEffectiveProject } from "@/utils/task/task-operations";
/**

View file

@ -7,7 +7,7 @@ import {
TimerState,
} from "@/managers/timer-manager";
import { t } from "@/translations/helper";
import "@/styles/timer-statistics.css";
import "@/styles/timer-statistics.scss";
interface TimerStatisticsOptions {
onTaskClick?: (task: Task | null) => void;

View file

@ -10,7 +10,7 @@ import { TaskListRendererComponent } from "./TaskList";
import { t } from "@/translations/helper";
import TaskProgressBarPlugin from "@/index";
import { getInitialViewMode, saveViewMode } from "@/utils/ui/view-mode-utils";
import "@/styles/view.css";
import "@/styles/view.scss";
/**
*

View file

@ -18,10 +18,10 @@ import { TopNavigation } from "@/components/features/fluent/components/FluentTop
import { TaskTimerManager } from "@/managers/timer-manager";
import { TimerStatisticsPanel } from "./TimerStatisticsPanel";
import "@/styles/task-list.css";
import "@/styles/tree-view.css";
import "@/styles/modern.css";
import "@/styles/group-by.css";
import "@/styles/task-list.scss";
import "@/styles/tree-view.scss";
import "@/styles/modern.scss";
import "@/styles/group-by.scss";
// @ts-ignore
import { filterTasks } from "@/utils/task/task-filter-utils";
@ -100,7 +100,7 @@ export class ContentComponent extends Component {
private parentEl: HTMLElement,
private app: App,
private plugin: TaskProgressBarPlugin,
private params: ContentComponentParams = {}
private params: ContentComponentParams = {},
) {
super();
}
@ -194,7 +194,7 @@ export class ContentComponent extends Component {
{
root: this.taskListEl, // Observe within the task list container
threshold: 0.1, // Trigger when 10% of the marker is visible
}
},
);
}
@ -205,11 +205,11 @@ export class ContentComponent extends Component {
this.isTreeView = getInitialViewMode(
this.app,
this.plugin,
this.currentViewId
this.currentViewId,
);
// Update the toggle button icon to match the initial state
const viewToggleBtn = this.headerEl?.querySelector(
".view-toggle-btn"
".view-toggle-btn",
) as HTMLElement;
if (viewToggleBtn) {
setIcon(viewToggleBtn, this.isTreeView ? "git-branch" : "list");
@ -219,7 +219,7 @@ export class ContentComponent extends Component {
private toggleViewMode() {
this.isTreeView = !this.isTreeView;
const viewToggleBtn = this.headerEl.querySelector(
".view-toggle-btn"
".view-toggle-btn",
) as HTMLElement;
if (viewToggleBtn) {
setIcon(viewToggleBtn, this.isTreeView ? "git-branch" : "list");
@ -235,7 +235,7 @@ export class ContentComponent extends Component {
if (this.isTreeView !== isTree) {
this.isTreeView = isTree;
const viewToggleBtn = this.headerEl?.querySelector(
".view-toggle-btn"
".view-toggle-btn",
) as HTMLElement;
if (viewToggleBtn) {
setIcon(viewToggleBtn, this.isTreeView ? "git-branch" : "list");
@ -291,7 +291,7 @@ export class ContentComponent extends Component {
// Show menu at button position
const buttonEl = document.querySelector(
'.fluent-nav-custom-buttons [aria-label="' + t("Group By") + '"]'
'.fluent-nav-custom-buttons [aria-label="' + t("Group By") + '"]',
) as HTMLElement;
if (buttonEl) {
@ -299,7 +299,7 @@ export class ContentComponent extends Component {
new MouseEvent("click", {
clientX: buttonEl.getBoundingClientRect().left,
clientY: buttonEl.getBoundingClientRect().bottom,
})
}),
);
} else {
// Fallback: show at current mouse position
@ -323,7 +323,7 @@ export class ContentComponent extends Component {
this.taskGroups = groupTasksBy(
this.filteredTasks,
this.groupByDimension,
this.plugin.settings
this.plugin.settings,
);
}
}
@ -357,7 +357,7 @@ export class ContentComponent extends Component {
group: TaskGroup,
containerEl: HTMLElement,
taskMap: Map<string, Task>,
level: number
level: number,
): void {
// Create section element with level-specific class
const sectionEl = containerEl.createDiv({
@ -412,13 +412,13 @@ export class ContentComponent extends Component {
setGroupExpandedState(
this.currentViewId,
group.key,
group.isExpanded
group.isExpanded,
);
// Update icon
setIcon(
toggleEl,
group.isExpanded ? "chevron-down" : "chevron-right"
group.isExpanded ? "chevron-down" : "chevron-right",
);
// Show/hide and render/destroy content
@ -448,7 +448,7 @@ export class ContentComponent extends Component {
group: TaskGroup,
containerEl: HTMLElement,
taskMap: Map<string, Task>,
level: number
level: number,
): void {
// Clear existing content
containerEl.empty();
@ -460,7 +460,7 @@ export class ContentComponent extends Component {
childGroup,
containerEl,
taskMap,
level + 1
level + 1,
);
});
} else {
@ -470,7 +470,7 @@ export class ContentComponent extends Component {
containerEl,
this.plugin,
this.app,
this.currentViewId
this.currentViewId,
);
// Set up callbacks
@ -488,7 +488,7 @@ export class ContentComponent extends Component {
// Set up task update callback
group.renderer.onTaskUpdate = async (
originalTask: Task,
updatedTask: Task
updatedTask: Task,
) => {
if (this.params.onTaskUpdate) {
await this.params.onTaskUpdate(originalTask, updatedTask);
@ -500,7 +500,7 @@ export class ContentComponent extends Component {
group.tasks,
this.isTreeView,
taskMap,
t("No tasks in this group.")
t("No tasks in this group."),
);
}
}
@ -513,7 +513,7 @@ export class ContentComponent extends Component {
*/
private destroyGroupContent(
group: TaskGroup,
containerEl: HTMLElement
containerEl: HTMLElement,
): void {
// Recursively destroy child groups (depth-first)
if (group.children && group.children.length > 0) {
@ -548,7 +548,7 @@ export class ContentComponent extends Component {
public setTasks(
tasks: Task[],
notFilteredTasks: Task[],
forceRefresh: boolean = false
forceRefresh: boolean = false,
) {
const updateSignatures = () => {
this.lastAllTasksSignature = this.computeTaskSignature(tasks);
@ -577,7 +577,7 @@ export class ContentComponent extends Component {
// If a force refresh is pending, skip non-forced updates
if (this.pendingForceRefresh) {
console.log(
"ContentComponent: Skipping non-forced update, force refresh is pending"
"ContentComponent: Skipping non-forced update, force refresh is pending",
);
return;
}
@ -590,7 +590,7 @@ export class ContentComponent extends Component {
nextNotFilteredSignature === this.lastNotFilteredTasksSignature
) {
console.log(
"ContentComponent: Task signatures unchanged, skipping refresh"
"ContentComponent: Task signatures unchanged, skipping refresh",
);
return;
}
@ -676,7 +676,7 @@ export class ContentComponent extends Component {
});
console.log(
"[ContentComponent] Registered Group By button in TopNavigation"
"[ContentComponent] Registered Group By button in TopNavigation",
);
}
@ -690,7 +690,7 @@ export class ContentComponent extends Component {
this.topNavigation.unregisterCustomButton("content-group-by");
console.log(
"[ContentComponent] Unregistered Group By button from TopNavigation"
"[ContentComponent] Unregistered Group By button from TopNavigation",
);
}
@ -720,7 +720,7 @@ export class ContentComponent extends Component {
});
console.log(
"[ContentComponent] Registered Timer Statistics button for working-on view"
"[ContentComponent] Registered Timer Statistics button for working-on view",
);
}
@ -778,7 +778,7 @@ export class ContentComponent extends Component {
this.params.onTaskContextMenu(event, task);
}
},
}
},
);
this.addChild(this.timerStatisticsPanel);
this.timerStatisticsPanel.load();
@ -822,17 +822,17 @@ export class ContentComponent extends Component {
this.allTasks,
this.currentViewId,
this.plugin,
{ textQuery: this.filterInput?.value } // Pass text query from input
{ textQuery: this.filterInput?.value }, // Pass text query from input
);
const sortCriteria = this.plugin.settings.viewConfiguration.find(
(view) => view.id === this.currentViewId
(view) => view.id === this.currentViewId,
)?.sortCriteria;
if (sortCriteria && sortCriteria.length > 0) {
this.filteredTasks = sortTasks(
this.filteredTasks,
sortCriteria,
this.plugin.settings
this.plugin.settings,
);
} else {
// Default sorting: completed tasks last, then by priority, due date, content,
@ -860,7 +860,7 @@ export class ContentComponent extends Component {
});
const contentCmp = collator.compare(
a.content ?? "",
b.content ?? ""
b.content ?? "",
);
if (contentCmp !== 0) return contentCmp;
// Lowest-priority tie-breakers to ensure stability across files
@ -897,7 +897,7 @@ export class ContentComponent extends Component {
task.originalMarkdown ?? "",
task.content ?? "",
task.metadata ? JSON.stringify(task.metadata) : "",
].join("|")
].join("|"),
)
.join(";");
}
@ -963,7 +963,7 @@ export class ContentComponent extends Component {
// If a render is already in progress, queue a refresh instead of skipping
if (this.isRendering) {
console.log(
"ContentComponent: Already rendering, queueing a refresh"
"ContentComponent: Already rendering, queueing a refresh",
);
this.pendingForceRefresh = true;
return;
@ -995,7 +995,7 @@ export class ContentComponent extends Component {
this.taskListEl.replaceChildren();
this.disposeComponentList(previousTaskComponents);
this.disposeComponentList(previousTreeComponents);
this.addEmptyState(t("No tasks found."));
this.addEmptyState(t("No tasks here."));
return;
}
@ -1019,19 +1019,19 @@ export class ContentComponent extends Component {
const taskMap = new Map<string, Task>();
// Add all non-filtered tasks to the taskMap
this.notFilteredTasks.forEach((task) =>
taskMap.set(task.id, task)
taskMap.set(task.id, task),
);
this.rootTasks = tasksToTree(this.filteredTasks); // Calculate root tasks
// Sort roots according to view's sort criteria (fallback to sensible defaults)
const viewSortCriteria =
this.plugin.settings.viewConfiguration.find(
(view) => view.id === this.currentViewId
(view) => view.id === this.currentViewId,
)?.sortCriteria;
if (viewSortCriteria && viewSortCriteria.length > 0) {
this.rootTasks = sortTasks(
this.rootTasks,
viewSortCriteria,
this.plugin.settings
this.plugin.settings,
);
} else {
// Default sorting: completed tasks last, then by priority, due date, content,
@ -1060,12 +1060,12 @@ export class ContentComponent extends Component {
});
const contentCmp = collator.compare(
a.content ?? "",
b.content ?? ""
b.content ?? "",
);
if (contentCmp !== 0) return contentCmp;
// Lowest-priority tie-breakers to ensure stability across files
const fp = (a.filePath || "").localeCompare(
b.filePath || ""
b.filePath || "",
);
if (fp !== 0) return fp;
return (a.line ?? 0) - (b.line ?? 0);
@ -1112,7 +1112,7 @@ export class ContentComponent extends Component {
const containerRect = container.getBoundingClientRect();
// Find first visible task item
const items = Array.from(
container.querySelectorAll<HTMLElement>(".task-item")
container.querySelectorAll<HTMLElement>(".task-item"),
);
for (const el of items) {
const rect = el.getBoundingClientRect();
@ -1137,7 +1137,7 @@ export class ContentComponent extends Component {
// Try anchor-based restoration first
if (state.anchorId) {
const anchorEl = container.querySelector<HTMLElement>(
`[data-task-id="${state.anchorId}"]`
`[data-task-id="${state.anchorId}"]`,
);
if (anchorEl) {
const desiredOffset = state.anchorOffset;
@ -1154,7 +1154,7 @@ export class ContentComponent extends Component {
}
private loadTaskBatch(
target: DocumentFragment | HTMLElement = this.taskListEl
target: DocumentFragment | HTMLElement = this.taskListEl,
): number {
const fragment = document.createDocumentFragment();
const countToLoad = this.taskPageSize;
@ -1170,7 +1170,7 @@ export class ContentComponent extends Component {
this.currentViewId, // Pass currentViewId
this.app,
this.plugin,
this.params.selectionManager // Pass selection manager
this.params.selectionManager, // Pass selection manager
);
// Attach event handlers
@ -1201,7 +1201,7 @@ export class ContentComponent extends Component {
private loadRootTaskBatch(
taskMap: Map<string, Task>,
target: DocumentFragment | HTMLElement = this.taskListEl
target: DocumentFragment | HTMLElement = this.taskListEl,
): number {
const fragment = document.createDocumentFragment();
const countToLoad = this.taskPageSize;
@ -1218,7 +1218,7 @@ export class ContentComponent extends Component {
for (let i = start; i < end; i++) {
const rootTask = this.rootTasks[i];
const childTasks = this.notFilteredTasks.filter(
(task) => task.metadata.parent === rootTask.id
(task) => task.metadata.parent === rootTask.id,
);
const treeComponent = new TaskTreeItemComponent(
@ -1229,7 +1229,7 @@ export class ContentComponent extends Component {
childTasks,
taskMap,
this.plugin,
this.params.selectionManager // Pass selection manager
this.params.selectionManager, // Pass selection manager
);
// Attach event handlers
@ -1313,7 +1313,7 @@ export class ContentComponent extends Component {
}
const timerManager = new TaskTimerManager(
this.plugin.settings.taskTimer
this.plugin.settings.taskTimer,
);
let activeDuration = 0;
@ -1325,7 +1325,7 @@ export class ContentComponent extends Component {
if (!blockId) return;
const timer = timerManager.getTimerByFileAndBlock(
task.filePath,
blockId
blockId,
);
if (!timer) return;
const duration = timerManager.getCurrentDuration(timer.taskId);
@ -1349,8 +1349,8 @@ export class ContentComponent extends Component {
this.workingOnSummaryEl.setText(
`${t("Active timers")}: ${activeCount} · ${t(
"Total time"
)}: ${activeText} · ${t("Completed time")}: ${completedText}`
"Total time",
)}: ${activeText} · ${t("Completed time")}: ${completedText}`,
);
// Ensure the summary stays at the top
@ -1370,7 +1370,7 @@ export class ContentComponent extends Component {
// );
const taskMap = new Map<string, Task>();
this.filteredTasks.forEach((task) =>
taskMap.set(task.id, task)
taskMap.set(task.id, task),
);
this.loadRootTaskBatch(taskMap);
} else {
@ -1431,12 +1431,12 @@ export class ContentComponent extends Component {
public updateTask(updatedTask: Task) {
// 1) Update sources
const taskIndexAll = this.allTasks.findIndex(
(t) => t.id === updatedTask.id
(t) => t.id === updatedTask.id,
);
if (taskIndexAll !== -1)
this.allTasks[taskIndexAll] = { ...updatedTask };
const taskIndexNotFiltered = this.notFilteredTasks.findIndex(
(t) => t.id === updatedTask.id
(t) => t.id === updatedTask.id,
);
if (taskIndexNotFiltered !== -1)
this.notFilteredTasks[taskIndexNotFiltered] = { ...updatedTask };
@ -1447,17 +1447,17 @@ export class ContentComponent extends Component {
const prevLen = this.filteredTasks.length;
this.applyFilters();
const taskFromFiltered = this.filteredTasks.find(
(t) => t.id === updatedTask.id
(t) => t.id === updatedTask.id,
);
const taskStillVisible = !!taskFromFiltered;
// Helper: insert list item at correct position (list view)
const insertListItem = (taskToInsert: Task) => {
const compIds = new Set(
this.taskComponents.map((c) => c.getTask().id)
this.taskComponents.map((c) => c.getTask().id),
);
const sortedIndex = this.filteredTasks.findIndex(
(t) => t.id === taskToInsert.id
(t) => t.id === taskToInsert.id,
);
// Find the next rendered neighbor after sortedIndex
let nextComp: any = null;
@ -1465,7 +1465,7 @@ export class ContentComponent extends Component {
const id = this.filteredTasks[i].id;
if (compIds.has(id)) {
nextComp = this.taskComponents.find(
(c) => c.getTask().id === id
(c) => c.getTask().id === id,
);
break;
}
@ -1476,7 +1476,7 @@ export class ContentComponent extends Component {
this.currentViewId,
this.app,
this.plugin,
this.params.selectionManager // Pass selection manager
this.params.selectionManager, // Pass selection manager
);
// Attach events
taskComponent.onTaskSelected = this.selectTask.bind(this);
@ -1497,7 +1497,7 @@ export class ContentComponent extends Component {
if (nextComp) {
this.taskListEl.insertBefore(
taskComponent.element,
nextComp.element
nextComp.element,
);
const idx = this.taskComponents.indexOf(nextComp);
this.taskComponents.splice(idx, 0, taskComponent);
@ -1510,7 +1510,7 @@ export class ContentComponent extends Component {
// Helper: remove list item
const removeListItem = (taskId: string) => {
const idx = this.taskComponents.findIndex(
(c) => c.getTask().id === taskId
(c) => c.getTask().id === taskId,
);
if (idx >= 0) {
const comp = this.taskComponents[idx];
@ -1531,7 +1531,7 @@ export class ContentComponent extends Component {
if (!this.isTreeView) {
// List view: update in place or insert if new to view
const comp = this.taskComponents.find(
(c) => c.getTask().id === updatedTask.id
(c) => c.getTask().id === updatedTask.id,
);
if (comp) {
comp.updateTask(taskFromFiltered!);
@ -1541,7 +1541,7 @@ export class ContentComponent extends Component {
} else {
// Tree view: update existing subtree or insert to parent/root
const comp = this.treeComponents.find(
(c) => c.getTask().id === updatedTask.id
(c) => c.getTask().id === updatedTask.id,
);
if (comp) {
comp.updateTask(taskFromFiltered!);
@ -1566,7 +1566,7 @@ export class ContentComponent extends Component {
const newChildren =
this.notFilteredTasks.filter(
(t) =>
t.metadata.parent === parentId
t.metadata.parent === parentId,
);
parentComp.updateChildTasks(newChildren);
updated = true;
@ -1577,11 +1577,11 @@ export class ContentComponent extends Component {
// Root insertion
const taskMap = new Map<string, Task>();
this.notFilteredTasks.forEach((t) =>
taskMap.set(t.id, t)
taskMap.set(t.id, t),
);
const childTasks = this.notFilteredTasks.filter(
(t) =>
t.metadata.parent === taskFromFiltered!.id
t.metadata.parent === taskFromFiltered!.id,
);
const newRoot = new TaskTreeItemComponent(
taskFromFiltered!,
@ -1591,7 +1591,7 @@ export class ContentComponent extends Component {
childTasks,
taskMap,
this.plugin,
this.params.selectionManager // Pass selection manager
this.params.selectionManager, // Pass selection manager
);
newRoot.onTaskSelected = this.selectTask.bind(this);
newRoot.onTaskCompleted = (t) => {
@ -1616,7 +1616,7 @@ export class ContentComponent extends Component {
if (
rootComparator(
taskFromFiltered!,
this.treeComponents[i].getTask()
this.treeComponents[i].getTask(),
) < 0
) {
insertAt = i;
@ -1626,12 +1626,12 @@ export class ContentComponent extends Component {
if (insertAt < this.treeComponents.length) {
this.taskListEl.insertBefore(
newRoot.element,
this.treeComponents[insertAt].element
this.treeComponents[insertAt].element,
);
this.treeComponents.splice(
insertAt,
0,
newRoot
newRoot,
);
} else {
this.taskListEl.appendChild(newRoot.element);
@ -1653,7 +1653,7 @@ export class ContentComponent extends Component {
// Tree view removal
// If root component exists, remove it
const idx = this.treeComponents.findIndex(
(c) => c.getTask().id === updatedTask.id
(c) => c.getTask().id === updatedTask.id,
);
if (idx >= 0) {
const comp = this.treeComponents[idx];

View file

@ -10,7 +10,7 @@ import {
import { Task } from "@/types/task";
import TaskProgressBarPlugin from "@/index";
import { TaskProgressBarSettings } from "@/common/setting-definition";
import "@/styles/task-details.css";
import "@/styles/task-details.scss";
import { t } from "@/translations/helper";
import { clearAllMarks } from "@/components/ui/renderers/MarkdownRenderer";
import { StatusComponent } from "@/components/ui/feedback/StatusIndicator";

View file

@ -9,8 +9,8 @@ import { Task } from "@/types/task";
import { CalendarComponent, CalendarOptions } from './calendar';
import { TaskListItemComponent } from "./listItem";
import { t } from "@/translations/helper";
import "@/styles/forecast.css";
import "@/styles/calendar.css";
import "@/styles/forecast.scss";
import "@/styles/calendar.scss";
import { TaskTreeItemComponent } from "./treeItem";
import { TaskListRendererComponent } from "./TaskList";
import TaskProgressBarPlugin from "@/index";

View file

@ -10,7 +10,7 @@ import {
import { Task } from "@/types/task";
import { MarkdownRendererComponent } from "@/components/ui/renderers/MarkdownRenderer";
import "@/styles/task-status-indicator.css";
import "@/styles/task-status-indicator.scss";
import { createTaskCheckbox } from "./details";
import { TaskTimerManager } from "@/managers/timer-manager";
import { getRelativeTimeString } from "@/utils/date/date-formatter";

View file

@ -8,8 +8,8 @@ import {
} from "obsidian";
import { Task, TgProject } from "@/types/task";
import { t } from "@/translations/helper";
import "@/styles/project-view.css";
import "@/styles/project-tree.css";
import "@/styles/project-view.scss";
import "@/styles/project-tree.scss";
import { TaskListRendererComponent } from "./TaskList";
import TaskProgressBarPlugin from "@/index";
import { sortTasks } from "@/commands/sortTaskCommands";

View file

@ -11,7 +11,7 @@ import { Task } from "@/types/task";
import { t } from "@/translations/helper";
import { ProjectReviewSetting } from "@/common/setting-definition";
import TaskProgressBarPlugin from "@/index"; // Path used in TaskView.ts
import "@/styles/review-view.css"; // Assuming styles will be added here
import "@/styles/review-view.scss"; // Assuming styles will be added here
import { TaskListRendererComponent } from "./TaskList"; // Import the base renderer
interface SelectedReviewProject {

View file

@ -8,7 +8,7 @@ import {
import { Task } from "@/types/task";
import { TaskListItemComponent } from "./listItem";
import { t } from "@/translations/helper";
import "@/styles/tag-view.css";
import "@/styles/tag-view.scss";
import { TaskTreeItemComponent } from "./treeItem";
import { TaskListRendererComponent } from "./TaskList";
import TaskProgressBarPlugin from "@/index";

View file

@ -19,7 +19,7 @@ import {
EmbeddableMarkdownEditor,
} from "../../../editor-extensions/core/markdown-editor";
import { saveCapture } from "@/utils/file/file-operations";
import "@/styles/timeline-sidebar.css";
import "@/styles/timeline-sidebar.scss";
import { createTaskCheckbox } from "@/components/features/task/view/details";
import { MarkdownRendererComponent } from "@/components/ui/renderers/MarkdownRenderer";

View file

@ -9,7 +9,7 @@ import {
setTooltip,
} from "obsidian";
import { t } from "@/translations/helper";
import "@/styles/date-picker.css";
import "@/styles/date-picker.scss";
import type TaskProgressBarPlugin from "@/index";
export interface DatePickerState {

View file

@ -1,6 +1,6 @@
import { App, ButtonComponent, Modal, MarkdownRenderer } from "obsidian";
import TaskProgressBarPlugin from "@/index";
import "@/styles/modal.css";
import "@/styles/modal.scss";
export class ConfirmModal extends Modal {
private plugin: TaskProgressBarPlugin;

View file

@ -1,7 +1,7 @@
import { Modal, Setting, ButtonComponent } from "obsidian";
import TaskProgressBarPlugin from "@/index";
import { t } from "@/translations/helper";
import "@/styles/modal.css";
import "@/styles/modal.scss";
export interface ListConfigModalParams {
title: string;

View file

@ -1,7 +1,7 @@
import { Modal, ButtonComponent, ExtraButtonComponent } from "obsidian";
import TaskProgressBarPlugin from "@/index";
import { McpLogEntry } from "@/mcp/McpServer";
import "@/styles/modal.css";
import "@/styles/modal.scss";
import { formatDate } from "@/utils/date/date-formatter";
/**

View file

@ -11,7 +11,7 @@ import {
import TaskProgressBarPlugin from "@/index";
import { t } from "@/translations/helper";
import { getSuggestOptionsByTrigger } from "./SpecialCharacterSuggests";
import "@/styles/universal-suggest.css";
import "@/styles/universal-suggest.scss";
export interface SuggestOption {
id: string;

View file

@ -23,7 +23,7 @@ import {
import TaskProgressBarPlugin from "../../index";
import { saveCapture, processDateTemplates } from "@/utils/file/file-operations";
import { t } from "@/translations/helper";
import "@/styles/quick-capture.css";
import "@/styles/quick-capture.scss";
import { FileSuggest } from "@/components/ui/inputs/AutoComplete";
import { QuickCaptureSuggest } from "@/editor-extensions/autocomplete/task-metadata-suggest";

View file

@ -32,7 +32,7 @@ import {
} from "@/utils/task/filter-compatibility";
import { t } from "@/translations/helper";
import { Task as TaskIndexTask } from "@/types/task";
import "@/styles/task-filter.css";
import "@/styles/task-filter.scss";
// Effect to toggle the filter panel
export const toggleTaskFilter = StateEffect.define<boolean>();

View file

@ -23,7 +23,7 @@ import { TaskTimerMetadataDetector } from "@/services/timer-metadata-service";
import { TaskTimerManager, TimerState } from "@/managers/timer-manager";
import { TaskTimerFormatter } from "@/services/timer-format-service";
import { taskStatusChangeAnnotation } from "@/editor-extensions/task-operations/status-switcher";
import "@/styles/task-timer.css";
import "@/styles/task-timer.scss";
// Extension configuration for StateField access
interface TaskTimerConfig {

View file

@ -14,7 +14,7 @@ import { TaskDetailsPopover } from "@/components/features/task/edit/TaskDetailsP
import { MarkdownTaskParser } from "@/dataflow/core/ConfigurableTaskParser";
// @ts-ignore - This import is necessary but TypeScript can't find it
import { syntaxTree, tokenClassNodeProp } from "@codemirror/language";
import "@/styles/task-gutter.css";
import "@/styles/task-gutter.scss";
import { getConfig } from "@/common/task-parser-config";
import { TaskParserConfig } from "@/types/TaskParserConfig";

View file

@ -14,7 +14,7 @@ import { foldable, syntaxTree, tokenClassNodeProp } from "@codemirror/language";
import { RegExpCursor } from "@/editor-extensions/core/regex-cursor";
import TaskProgressBarPlugin from "@/index";
import { shouldHideProgressBarInLivePriview } from "@/utils";
import "../../styles/progressbar.css";
import "../../styles/progressbar.scss";
import { extractTaskAndGoalInfo } from "@/core/goal/edit-mode";
import { showPopoverWithProgressBar } from "@/components/ui";

View file

@ -24,7 +24,7 @@ import { taskStatusChangeAnnotation } from "../task-operations/status-switcher";
import { Range } from "@codemirror/state";
import { RegExpCursor } from "@codemirror/search";
import { setIcon } from "obsidian";
import "../../styles/workflow.css";
import "../../styles/workflow.scss";
// Annotation that marks a transaction as a workflow decorator change
export const workflowDecoratorAnnotation = Annotation.define<string>();

View file

@ -70,17 +70,18 @@ import { MinimalQuickCaptureSuggest } from "./components/features/quick-capture/
import { SuggestManager } from "@/components/ui/suggest";
import { t } from "./translations/helper";
import { TASK_VIEW_TYPE, TaskView } from "./pages/TaskView";
import "./styles/global.css";
import "./styles/setting.css";
import "./styles/view.css";
import "./styles/view-config.css";
import "./styles/task-status.css";
import "./styles/task-selection.css";
import "./styles/quadrant/quadrant.css";
import "./styles/onboarding.css";
import "./styles/universal-suggest.css";
import "./styles/noise.css";
import "./styles/changelog.css";
import "./styles/global.scss";
import "./styles/setting.scss";
import "./styles/view.scss";
import "./styles/native-layout.scss";
import "./styles/view-config.scss";
import "./styles/task-status.scss";
import "./styles/task-selection.scss";
import "./styles/quadrant/quadrant.scss";
import "./styles/onboarding.scss";
import "./styles/universal-suggest.scss";
import "./styles/noise.scss";
import "./styles/changelog.scss";
import {
TASK_SPECIFIC_VIEW_TYPE,
@ -230,7 +231,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.changelogManager = new ChangelogManager(this);
this.registerView(
CHANGELOG_VIEW_TYPE,
(leaf) => new ChangelogView(leaf, this)
(leaf) => new ChangelogView(leaf, this),
);
// Initialize onboarding config manager
@ -273,18 +274,18 @@ export default class TaskProgressBarPlugin extends Plugin {
item.setTitle(
`${t("Set priority")}: ${
priority.text
}`
}`,
);
item.setIcon("arrow-big-up-dash");
item.onClick(() => {
setPriorityAtCursor(
editor,
priority.emoji
priority.emoji,
);
});
});
}
}
},
);
submenu.addSeparator();
@ -294,17 +295,17 @@ export default class TaskProgressBarPlugin extends Plugin {
([key, priority]) => {
submenu.addItem((item) => {
item.setTitle(
`${t("Set priority")}: ${key}`
`${t("Set priority")}: ${key}`,
);
item.setIcon("a-arrow-up");
item.onClick(() => {
setPriorityAtCursor(
editor,
`[#${key}]`
`[#${key}]`,
);
});
});
}
},
);
// Remove priority command
@ -324,7 +325,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (this.settings.workflow.enableWorkflow) {
updateWorkflowContextMenu(menu, editor, this);
}
})
}),
);
this.app.workspace.onLayoutReady(async () => {
@ -336,7 +337,7 @@ export default class TaskProgressBarPlugin extends Plugin {
const deferWorkspaceLeaves =
this.app.workspace.getLeavesOfType(TASK_VIEW_TYPE);
const deferSpecificLeaves = this.app.workspace.getLeavesOfType(
TASK_SPECIFIC_VIEW_TYPE
TASK_SPECIFIC_VIEW_TYPE,
);
const deferTaskGeniusLeaves =
this.app.workspace.getLeavesOfType(FLUENT_TASK_VIEW);
@ -364,8 +365,8 @@ export default class TaskProgressBarPlugin extends Plugin {
this.registerEvent(
this.app.workspace.on(
Events.TASK_CACHE_UPDATED as any,
() => this.notificationManager?.onTaskCacheUpdated()
)
() => this.notificationManager?.onTaskCacheUpdated(),
),
);
}
@ -414,7 +415,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.icsManager = new IcsManager(
this.settings.icsIntegration,
this.settings,
this
this,
);
this.addChild(this.icsManager);
@ -434,7 +435,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.activateTimelineSidebarView().catch((error) => {
console.error(
"Failed to auto-open timeline sidebar:",
error
error,
);
});
}, 1000);
@ -483,7 +484,7 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (error) {
console.error(
"[Plugin] Dataflow version check failed during startup:",
error
error,
);
}
@ -517,16 +518,16 @@ export default class TaskProgressBarPlugin extends Plugin {
this.registerOnboardingView();
this.registerView(TASK_VIEW_TYPE, (leaf) => new TaskView(leaf, this));
// this.registerView(FLUENT_TASK_VIEW, (leaf) => new TaskView(leaf, this));
this.registerView(
TASK_SPECIFIC_VIEW_TYPE,
(leaf) => new TaskSpecificView(leaf, this)
(leaf) => new TaskSpecificView(leaf, this),
);
this.registerView(
TIMELINE_SIDEBAR_VIEW_TYPE,
(leaf) => new TimelineSidebarView(leaf, this)
(leaf) => new TimelineSidebarView(leaf, this),
);
try {
@ -548,7 +549,7 @@ export default class TaskProgressBarPlugin extends Plugin {
new OnboardingView(leaf, this, () => {
console.log("Onboarding completed successfully");
leaf.detach();
})
}),
);
}
@ -623,7 +624,7 @@ export default class TaskProgressBarPlugin extends Plugin {
t("Open Task Genius view"),
() => {
this.activateTaskView();
}
},
);
};
@ -681,16 +682,16 @@ export default class TaskProgressBarPlugin extends Plugin {
detectionMethods:
this.settings.projectConfig?.metadataConfig
?.detectionMethods || [],
}
},
);
return true;
} catch (error) {
console.error(
"[Plugin] Failed to initialize dataflow orchestrator:",
error
error,
);
new Notice(
t("Failed to initialize task system. Please restart Obsidian.")
t("Failed to initialize task system. Please restart Obsidian."),
);
this.dataflowOrchestrator = undefined;
return false;
@ -720,7 +721,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.app.vault,
this.app.metadataCache,
this,
getTaskById
getTaskById,
);
}
@ -758,7 +759,7 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (error) {
console.error(
"[Plugin] Failed registering deferred commands:",
error
error,
);
}
}, 100);
@ -815,7 +816,7 @@ export default class TaskProgressBarPlugin extends Plugin {
}
view.dispatch({
effects: toggleTaskFilter.of(
!view.state.field(taskFilterState)
!view.state.field(taskFilterState),
),
});
},
@ -835,7 +836,7 @@ export default class TaskProgressBarPlugin extends Plugin {
preset.options = migrateOldFilterOptions(preset.options);
}
return preset;
}
},
);
await this.saveSettings();
console.timeEnd("[Task Genius] migratePresetTaskFilters");
@ -853,14 +854,14 @@ export default class TaskProgressBarPlugin extends Plugin {
const changes = sortTasksInDocument(
editorView,
this,
false
false,
);
if (changes) {
new Notice(
t(
"Tasks sorted (using settings). Change application needs refinement."
)
"Tasks sorted (using settings). Change application needs refinement.",
),
);
} else {
// Notice is already handled within sortTasksInDocument if no changes or sorting disabled
@ -884,11 +885,11 @@ export default class TaskProgressBarPlugin extends Plugin {
return changes;
});
new Notice(
t("Entire document sorted (using settings).")
t("Entire document sorted (using settings)."),
);
} else {
new Notice(
t("Tasks already sorted or no tasks found.")
t("Tasks already sorted or no tasks found."),
);
}
},
@ -989,10 +990,12 @@ export default class TaskProgressBarPlugin extends Plugin {
) {
// Use dataflow orchestrator for force reindex
console.log(
"[Command] Force reindexing via dataflow"
"[Command] Force reindexing via dataflow",
);
new Notice(
t("Clearing task cache and rebuilding index...")
t(
"Clearing task cache and rebuilding index...",
),
);
// Clear all caches and rebuild from scratch
@ -1092,7 +1095,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allCompleted"
"allCompleted",
);
},
});
@ -1107,7 +1110,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directChildren"
"directChildren",
);
},
});
@ -1122,7 +1125,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"all"
"all",
);
},
});
@ -1138,7 +1141,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allCompleted"
"allCompleted",
);
},
});
@ -1146,7 +1149,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.addCommand({
id: "auto-move-direct-completed-subtasks",
name: t(
"Auto-move direct completed subtasks to default file"
"Auto-move direct completed subtasks to default file",
),
editorCheckCallback: (checking, editor, ctx) => {
return autoMoveCompletedTasksCommand(
@ -1154,7 +1157,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directChildren"
"directChildren",
);
},
});
@ -1168,7 +1171,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"all"
"all",
);
},
});
@ -1187,7 +1190,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allIncompleted"
"allIncompleted",
);
},
});
@ -1202,7 +1205,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directIncompletedChildren"
"directIncompletedChildren",
);
},
});
@ -1218,7 +1221,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"allIncompleted"
"allIncompleted",
);
},
});
@ -1226,7 +1229,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.addCommand({
id: "auto-move-direct-incomplete-subtasks",
name: t(
"Auto-move direct incomplete subtasks to default file"
"Auto-move direct incomplete subtasks to default file",
),
editorCheckCallback: (checking, editor, ctx) => {
return autoMoveCompletedTasksCommand(
@ -1234,7 +1237,7 @@ export default class TaskProgressBarPlugin extends Plugin {
editor,
ctx,
this,
"directIncompletedChildren"
"directIncompletedChildren",
);
},
});
@ -1300,8 +1303,8 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (e) {
new Notice(
t(
"Could not open quick capture panel in the current editor"
)
"Could not open quick capture panel in the current editor",
),
);
}
}, 100);
@ -1320,7 +1323,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this
this,
);
},
});
@ -1333,7 +1336,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this
this,
);
},
});
@ -1346,7 +1349,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this
this,
);
},
});
@ -1359,7 +1362,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this
this,
);
},
});
@ -1372,7 +1375,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this
this,
);
},
});
@ -1385,7 +1388,7 @@ export default class TaskProgressBarPlugin extends Plugin {
checking,
editor,
ctx,
this
this,
);
},
});
@ -1396,12 +1399,12 @@ export default class TaskProgressBarPlugin extends Plugin {
if (this.settings.taskTimer?.enabled) {
if (!this.taskTimerManager) {
this.taskTimerManager = new TaskTimerManager(
this.settings.taskTimer
this.settings.taskTimer,
);
}
if (!this.taskTimerExporter) {
this.taskTimerExporter = new TaskTimerExporter(
this.taskTimerManager
this.taskTimerManager,
);
}
}
@ -1436,7 +1439,7 @@ export default class TaskProgressBarPlugin extends Plugin {
URL.revokeObjectURL(url);
new Notice(
`Exported ${stats.activeTimers} timer records`
`Exported ${stats.activeTimers} timer records`,
);
} catch (error) {
console.error("Error exporting timer data:", error);
@ -1467,17 +1470,17 @@ export default class TaskProgressBarPlugin extends Plugin {
if (success) {
new Notice(
"Timer data imported successfully"
"Timer data imported successfully",
);
} else {
new Notice(
"Failed to import timer data - invalid format"
"Failed to import timer data - invalid format",
);
}
} catch (error) {
console.error(
"Error importing timer data:",
error
error,
);
new Notice("Failed to import timer data");
}
@ -1521,12 +1524,12 @@ export default class TaskProgressBarPlugin extends Plugin {
URL.revokeObjectURL(url);
new Notice(
`Exported ${stats.activeTimers} timer records to YAML`
`Exported ${stats.activeTimers} timer records to YAML`,
);
} catch (error) {
console.error(
"Error exporting timer data to YAML:",
error
error,
);
new Notice("Failed to export timer data to YAML");
}
@ -1574,7 +1577,7 @@ export default class TaskProgressBarPlugin extends Plugin {
let message = `Task Timer Statistics:\n`;
message += `Active timers: ${stats.activeTimers}\n`;
message += `Total duration: ${Math.round(
stats.totalDuration / 60000
stats.totalDuration / 60000,
)} minutes\n`;
if (stats.oldestTimer) {
@ -1604,12 +1607,12 @@ export default class TaskProgressBarPlugin extends Plugin {
// Initialize task timer manager and exporter
if (!this.taskTimerManager) {
this.taskTimerManager = new TaskTimerManager(
this.settings.taskTimer
this.settings.taskTimer,
);
}
if (!this.taskTimerExporter) {
this.taskTimerExporter = new TaskTimerExporter(
this.taskTimerManager
this.taskTimerManager,
);
}
@ -1683,7 +1686,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (this.settings.quickCapture.enableMinimalMode) {
this.minimalQuickCaptureSuggest = new MinimalQuickCaptureSuggest(
this.app,
this
this,
);
this.registerEditorSuggest(this.minimalQuickCaptureSuggest);
}
@ -1710,7 +1713,7 @@ export default class TaskProgressBarPlugin extends Plugin {
this.dataflowOrchestrator.cleanup().catch((error) => {
console.error(
"Error cleaning up dataflow orchestrator:",
error
error,
);
});
// Set to undefined to prevent any further access
@ -1779,11 +1782,11 @@ export default class TaskProgressBarPlugin extends Plugin {
const v2Leaves = workspace.getLeavesOfType(FLUENT_TASK_VIEW);
v2Leaves.forEach((leaf) => leaf.detach());
const specificLeaves = workspace.getLeavesOfType(
TASK_SPECIFIC_VIEW_TYPE
TASK_SPECIFIC_VIEW_TYPE,
);
specificLeaves.forEach((leaf) => leaf.detach());
const timelineLeaves = workspace.getLeavesOfType(
TIMELINE_SIDEBAR_VIEW_TYPE
TIMELINE_SIDEBAR_VIEW_TYPE,
);
timelineLeaves.forEach((leaf) => leaf.detach());
const changelogLeaves = workspace.getLeavesOfType(CHANGELOG_VIEW_TYPE);
@ -1842,7 +1845,7 @@ export default class TaskProgressBarPlugin extends Plugin {
lastVersion !== "9.9.0"
) {
console.log(
`[Task Genius] Migration detected: ${previousVersion} -> ${currentVersion}, opening onboarding`
`[Task Genius] Migration detected: ${previousVersion} -> ${currentVersion}, opening onboarding`,
);
// Directly open onboarding view (same pattern as maybeShowChangelog)
@ -1855,7 +1858,7 @@ export default class TaskProgressBarPlugin extends Plugin {
} catch (error) {
console.error(
"[Task Genius] Failed to check migration onboarding:",
error
error,
);
}
}
@ -1896,16 +1899,16 @@ export default class TaskProgressBarPlugin extends Plugin {
enabled: true,
lastVersion: "",
},
this.settings.changelog ?? {}
this.settings.changelog ?? {},
);
try {
console.debug(
"[Plugin][loadSettings] fileMetadataInheritance (raw):",
savedData?.fileMetadataInheritance
savedData?.fileMetadataInheritance,
);
console.debug(
"[Plugin][loadSettings] fileMetadataInheritance (effective):",
this.settings.fileMetadataInheritance
this.settings.fileMetadataInheritance,
);
} catch {}
@ -1915,7 +1918,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Repair and validate status cycles
if (this.settings.statusCycles) {
this.settings.statusCycles = repairStatusCycles(
this.settings.statusCycles
this.settings.statusCycles,
);
}
@ -1957,7 +1960,7 @@ export default class TaskProgressBarPlugin extends Plugin {
try {
console.debug(
"[Plugin][saveSettings] fileMetadataInheritance:",
this.settings?.fileMetadataInheritance
this.settings?.fileMetadataInheritance,
);
} catch {}
await this.saveData(this.settings);
@ -1974,7 +1977,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Add any missing default views to user settings
defaultViews.forEach((defaultView) => {
const existingView = this.settings.viewConfiguration.find(
(v) => v.id === defaultView.id
(v) => v.id === defaultView.id,
);
if (!existingView) {
this.settings.viewConfiguration.push({ ...defaultView });
@ -1998,9 +2001,8 @@ export default class TaskProgressBarPlugin extends Plugin {
try {
const { workspace } = this.app;
const viewType = this.settings.fluentView?.enableFluent
? FLUENT_TASK_VIEW
: TASK_VIEW_TYPE;
// Always use Fluent View as the default
const viewType = FLUENT_TASK_VIEW;
// Check if view is already open
const existingLeaves = workspace.getLeavesOfType(viewType);
@ -2038,7 +2040,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Check if view is already open
const existingLeaves = workspace.getLeavesOfType(
TIMELINE_SIDEBAR_VIEW_TYPE
TIMELINE_SIDEBAR_VIEW_TYPE,
);
if (existingLeaves.length > 0) {
@ -2084,7 +2086,7 @@ export default class TaskProgressBarPlugin extends Plugin {
// Update Timeline Sidebar Views
const timelineViewLeaves = this.app.workspace.getLeavesOfType(
TIMELINE_SIDEBAR_VIEW_TYPE
TIMELINE_SIDEBAR_VIEW_TYPE,
);
if (timelineViewLeaves.length > 0) {
for (const leaf of timelineViewLeaves) {
@ -2118,7 +2120,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (!diagnosticInfo.canWrite) {
throw new Error(
"Cannot write to version storage - storage may be corrupted"
"Cannot write to version storage - storage may be corrupted",
);
}
@ -2127,7 +2129,7 @@ export default class TaskProgressBarPlugin extends Plugin {
diagnosticInfo.previousVersion
) {
console.warn(
"Invalid version data detected, attempting recovery"
"Invalid version data detected, attempting recovery",
);
await this.versionManager.recoverFromCorruptedVersion();
}
@ -2138,7 +2140,7 @@ export default class TaskProgressBarPlugin extends Plugin {
if (versionResult.requiresRebuild) {
console.log(
`Task Genius (Dataflow): ${versionResult.rebuildReason}`
`Task Genius (Dataflow): ${versionResult.rebuildReason}`,
);
// Get all supported files for progress tracking
@ -2147,13 +2149,13 @@ export default class TaskProgressBarPlugin extends Plugin {
.filter(
(file) =>
file.extension === "md" ||
file.extension === "canvas"
file.extension === "canvas",
);
// Start rebuild progress tracking
this.rebuildProgressManager.startRebuild(
allFiles.length,
versionResult.rebuildReason
versionResult.rebuildReason,
);
// After dataflow rebuild, refresh habits to keep in sync
@ -2179,20 +2181,20 @@ export default class TaskProgressBarPlugin extends Plugin {
} else {
// No rebuild needed, dataflow already initialized during creation
console.log(
"Task Genius (Dataflow): No rebuild needed, using existing cache"
"Task Genius (Dataflow): No rebuild needed, using existing cache",
);
}
} catch (error) {
console.error(
"Error during dataflow initialization with version check:",
error
error,
);
// Trigger emergency rebuild for dataflow
try {
const emergencyResult =
await this.versionManager.handleEmergencyRebuild(
`Dataflow initialization failed: ${error.message}`
`Dataflow initialization failed: ${error.message}`,
);
// Get all supported files for progress tracking
@ -2201,13 +2203,13 @@ export default class TaskProgressBarPlugin extends Plugin {
.filter(
(file) =>
file.extension === "md" ||
file.extension === "canvas"
file.extension === "canvas",
);
// Start emergency rebuild
this.rebuildProgressManager.startRebuild(
allFiles.length,
emergencyResult.rebuildReason
emergencyResult.rebuildReason,
);
// Force rebuild dataflow
@ -2225,12 +2227,12 @@ export default class TaskProgressBarPlugin extends Plugin {
await this.versionManager.markVersionProcessed();
console.log(
"Emergency dataflow rebuild completed successfully"
"Emergency dataflow rebuild completed successfully",
);
} catch (emergencyError) {
console.error(
"Emergency dataflow rebuild failed:",
emergencyError
emergencyError,
);
throw emergencyError;
}
@ -2245,7 +2247,7 @@ export default class TaskProgressBarPlugin extends Plugin {
private async initializeTaskManagerWithVersionCheck(): Promise<void> {
// This method is deprecated and should not be called
console.warn(
"initializeTaskManagerWithVersionCheck is deprecated and should not be used"
"initializeTaskManagerWithVersionCheck is deprecated and should not be used",
);
return Promise.resolve();
}

View file

@ -1,11 +1,11 @@
import { debounce, ItemView, Scope, WorkspaceLeaf, setIcon } from "obsidian";
import TaskProgressBarPlugin from "@/index";
import { Task } from "@/types/task";
import "@/styles/fluent/fluent-main.css";
import "@/styles/fluent/fluent-secondary.css";
import "@/styles/fluent/fluent-content-header.css";
import "@/styles/fluent/fluent-project-popover.css";
import "@/styles/fluent/fluent-modern.css";
import "@/styles/fluent/fluent-main.scss";
import "@/styles/fluent/fluent-secondary.scss";
import "@/styles/fluent/fluent-content-header.scss";
import "@/styles/fluent/fluent-project-popover.scss";
import "@/styles/fluent/fluent-modern.scss";
import {
TopNavigation,
ViewMode,

View file

@ -22,7 +22,7 @@ import {
TaskDetailsComponent,
createTaskCheckbox,
} from "@/components/features/task/view/details";
import "../styles/view.css";
import "../styles/view.scss";
import TaskProgressBarPlugin from "../index";
import { QuickCaptureModal } from "@/components/features/quick-capture/modals/QuickCaptureModalWithSwitch";
import { t } from "@/translations/helper";

View file

@ -24,7 +24,7 @@ import {
TaskDetailsComponent,
createTaskCheckbox,
} from "@/components/features/task/view/details";
import "../styles/view.css";
import "../styles/view.scss";
import TaskProgressBarPlugin from "../index";
import { QuickCaptureModal } from "@/components/features/quick-capture/modals/QuickCaptureModalWithSwitch";
import { t } from "@/translations/helper";

View file

@ -10,12 +10,12 @@ import {
import TaskProgressBarPlugin from ".";
import { t } from "./translations/helper";
import "./styles/setting.css";
import "./styles/setting-v2.css";
import "./styles/beta-warning.css";
import "./styles/settings-search.css";
import "./styles/settings-migration.css";
import "./styles/workspace-settings-selector.css";
import "./styles/setting.scss";
import "./styles/setting-v2.scss";
import "./styles/beta-warning.scss";
import "./styles/settings-search.scss";
import "./styles/settings-migration.scss";
import "./styles/workspace-settings-selector.scss";
import {
renderAboutSettingsTab,
renderBetaTestSettingsTab,

119
src/styles/_variables.scss Normal file
View file

@ -0,0 +1,119 @@
// ==========================================================================
// Task Genius - SCSS Variables
// ==========================================================================
// ==========================================================================
// 1. Plugin-specific Variables (Native Layout)
// ==========================================================================
// Background colors
$tg-bg-primary: var(--background-primary);
$tg-bg-secondary: var(--background-secondary);
// Dark theme specific background
$tg-bg-primary-dark: #1c1c1c;
$tg-bg-secondary-dark: #1c1c1c;
// Border color
$tg-border-color: var(--background-modifier-border);
// Interaction states - unified hover/active
$tg-hover-bg: var(--background-modifier-hover);
$tg-active-bg: var(--background-modifier-hover);
// ==========================================================================
// 2. Shadows (Fluent-inspired)
// ==========================================================================
$tg-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
$tg-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
$tg-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
$tg-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
$tg-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
// Dark theme shadows
$tg-shadow-sm-dark: 0 1px 2px 0 rgb(0 0 0 / 0.3);
$tg-shadow-dark: 0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.3);
$tg-shadow-md-dark: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.3);
$tg-shadow-lg-dark: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.3);
$tg-shadow-xl-dark: 0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.3);
// ==========================================================================
// 3. Animations & Transitions
// ==========================================================================
$tg-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
$tg-transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
$tg-transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
// ==========================================================================
// 4. Border Radius
// ==========================================================================
$tg-radius-sm: 0.25rem;
$tg-radius: 0.375rem;
$tg-radius-md: 0.5rem;
$tg-radius-lg: 0.75rem;
$tg-radius-full: 9999px;
// ==========================================================================
// 5. Spacing (based on Obsidian's size variables)
// ==========================================================================
$tg-space-1: var(--size-2-1);
$tg-space-2: var(--size-2-2);
$tg-space-3: var(--size-2-3);
$tg-space-4: var(--size-4-2);
$tg-space-6: var(--size-4-3);
$tg-space-8: var(--size-4-4);
// ==========================================================================
// 6. Layout - Zero Gap Approach
// ==========================================================================
// Force zero gaps for native layout
$tg-gap-none: 0;
// ==========================================================================
// 7. Mixins
// ==========================================================================
// Remove gaps mixin
@mixin no-gap {
gap: $tg-gap-none;
margin: 0;
padding: 0;
}
// Flat container (no shadow, no float effect)
@mixin flat-container {
box-shadow: none;
border-radius: 0;
}
// Interactive hover state
@mixin hover-state {
transition: background-color $tg-transition-fast;
&:hover {
background-color: $tg-hover-bg;
}
}
// Active/Selected state
@mixin active-state {
background-color: $tg-active-bg;
}
// Border separator (instead of gap)
@mixin border-right {
border-right: 1px solid $tg-border-color;
}
@mixin border-bottom {
border-bottom: 1px solid $tg-border-color;
}
@mixin border-top {
border-top: 1px solid $tg-border-color;
}

View file

@ -472,7 +472,7 @@ button.fluent-new-task-btn:hover {
}
.fluent-view-tab.is-active {
background-color: var(--background-primary);
background-color: var(--background-secondary-alt);
color: var(--text-normal);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

View file

@ -1,20 +1,17 @@
/* 现代 Fluent 侧边栏配色和布局变量 */
.fluent-modern {
--modern-background-secondary: var(--color-base-25);
--modern-background-secondary: var(--background-secondary);
--modern-background-primary: var(--background-primary);
}
.theme-dark .fluent-modern {
--modern-background-secondary: var(--background-primary);
--modern-background-primary: var(--background-secondary);
--modern-background-secondary: var(--background-secondary);
--modern-background-primary: var(--background-primary);
}
/* —— Fluent 侧边栏及其内容区域 —— */
.fluent-modern {
.tg-fluent-sidebar-container.fluent-sidebar {
border-radius: var(--radius-l);
}
.tg-fluent-sidebar-container {
background-color: var(--modern-background-primary);
background-color: var(--background-secondary);
border-right: unset;
}
.fluent-sidebar-content {
@ -30,16 +27,16 @@
height: 100%;
width: 100%;
overflow: hidden;
padding: var(--size-4-2) 0;
gap: var(--size-4-2);
background: var(--modern-background-secondary);
/* padding: var(--size-4-2) 0; */
/* gap: var(--size-4-2); */
/* background: var(--modern-background-secondary); */
}
.tg-fluent-main-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
gap: var(--size-4-2);
/* gap: var(--size-4-2); */
}
/* 内容包裹 */
@ -53,7 +50,7 @@
.tg-fluent-content {
flex: 1;
overflow-y: auto;
background: var(--modern-background-primary);
/* background: var(--modern-background-secondary); */
}
/* 搜索栏 */
@ -84,6 +81,7 @@
cursor: pointer;
gap: var(--size-2-3);
min-height: 40px;
border-radius: var(--radius-s);
}
.task-item,
.task-item:hover {
@ -111,20 +109,14 @@
height: 56px;
padding: 0 20px;
gap: 20px;
background-color: var(--modern-background-primary);
background-color: var(--background-primary);
border-radius: var(--radius-m);
border-bottom: unset;
/* border-bottom: unset; */
/* 其他可选边框/阴影已注释 */
}
/* 视图标题栏和容器样式 */
.workspace-leaf-content[data-type^="fluent-task-genius-view"] {
padding: var(--size-4-3);
background: var(--modern-background-secondary);
}
.workspace-leaf-content[data-type^="fluent-task-genius-view"] .view-header {
background-color: var(--modern-background-primary);
background-color: var(--modern-background-secondary);
border-radius: var(--radius-m);
height: var(--header-height);
display: flex;
@ -137,8 +129,8 @@
.is-mobile .fluent-modern {
.workspace-leaf-content[data-type^="fluent-task-genius-view"] {
padding: var(--size-4-2);
background: var(--modern-background-secondary);
/* padding: var(--size-4-2); */
/* background: var(--modern-background-secondary); */
}
.workspace-leaf-content[data-type^="fluent-task-genius-view"] .view-header {
@ -155,7 +147,7 @@
.task-details-container {
width: 300px;
flex-shrink: 0;
background-color: var(--modern-background-secondary);
/* background-color: var(--modern-background-secondary); */
order: 1;
padding: var(--size-4-2) 0 var(--size-4-2) var(--size-4-2);
border-radius: var(--radius-m);
@ -172,7 +164,4 @@
background-color: var(--background-primary);
border-radius: var(--radius-m);
}
.tg-fluent-container {
background: var(--modern-background-secondary);
}
}

View file

@ -1,23 +0,0 @@
/* 删除与 fluent-modern.css 重复内容,仅保留 modern.css 独有或变体样式 */
.task-item {
border-bottom: 1px solid var(--color-base-20);
/* 若需覆盖 fluent 变体可在此添加非重复样式 */
}
/* 以下样式已在 fluent-modern.css 定义无需重复
.fluent-search-container input[type="search"] {
width: 100%;
background-color: var(--background-primary-alt);
height: var(--size-4-8);
border: unset;
}
.search-input-container {
width: 100%;
}
.task-list {
padding: var(--size-4-2);
}
*/

6
src/styles/modern.scss Normal file
View file

@ -0,0 +1,6 @@
/* 删除与 fluent-modern.css 重复内容,仅保留 modern.css 独有或变体样式 */
.task-item {
border-bottom: 1px solid var(--color-base-20);
/* 若需覆盖 fluent 变体可在此添加非重复样式 */
}

View file

@ -0,0 +1,393 @@
/* src/styles/native-layout.css */
/* ==========================================================================
Native Layout - Obsidian PDF Viewer Style
Zero gaps, border-based separation, flat visual hierarchy
NOTE: This file does NOT modify Fluent Sidebar (.tg-fluent-sidebar-container)
which maintains its original fluent-main.css styling.
========================================================================== */
/* ==========================================================================
1. CSS Variables Definition
========================================================================== */
.task-genius-container,
.tg-fluent-container,
.task-genius-view,
.task-genius-fluent-view {
/* Core background color - uses Obsidian variables by default */
--tg-bg-primary: var(--background-primary);
--tg-bg-secondary: var(--tg-bg-primary);
/* Border color for separation */
--tg-border-color: var(--background-modifier-border);
/* Interaction states - unified to use Obsidian's hover variable */
--tg-hover-bg: var(--background-modifier-hover);
--tg-active-bg: var(--background-modifier-hover);
}
/* Dark theme override - user specified #1c1c1c for main content area */
.theme-dark .task-genius-container,
.theme-dark .tg-fluent-container,
.theme-dark .task-genius-view,
.theme-dark .task-genius-fluent-view {
--tg-bg-primary: var(--background-primary);
/* Keep secondary as Obsidian default for sidebar compatibility */
--tg-bg-secondary: var(--background-secondary);
}
/* Light theme - provide reasonable alternative */
.theme-light .task-genius-container,
.theme-light .tg-fluent-container,
.theme-light .task-genius-view,
.theme-light .task-genius-fluent-view {
--tg-bg-primary: var(--background-primary);
--tg-bg-secondary: var(--tg-bg-primary);
}
/* ==========================================================================
2. Main Container Layout - Remove Gaps
========================================================================== */
/* Main containers - only affect layout, not sidebar */
.task-genius-container,
.tg-fluent-container {
display: flex;
flex-direction: row;
gap: 0;
padding: 0;
margin: 0;
height: 100%;
width: 100%;
border-top: 1px solid var(--tg-border-color);
}
/* Two-column layout containers */
.two-column-container {
gap: 0;
padding: 0;
}
.two-column-content {
gap: 0;
}
/* ==========================================================================
3. Legacy Sidebar Styles (Non-Fluent) - Flat, No Float Effect
========================================================================== */
/* Standard sidebar (Legacy view only, not Fluent) */
.task-sidebar {
background-color: var(--tg-bg-secondary);
border-right: 1px solid var(--tg-border-color);
margin: 0;
padding: 0;
box-shadow: none;
}
/* Sidebar navigation - remove internal gaps (Legacy only) */
.sidebar-nav {
gap: 0;
padding: 8px 0;
}
/* Two-column left column */
.two-column-left-column {
background-color: var(--tg-bg-secondary);
border-right: 1px solid var(--tg-border-color);
margin: 0;
}
/* ==========================================================================
4. Main Content Area - Apply New Background
========================================================================== */
/* Legacy task content */
.task-content {
background-color: var(--tg-bg-primary);
flex: 1;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
gap: 0;
border: none;
box-shadow: none;
}
/* Fluent main container (right side content area, NOT sidebar) */
.tg-fluent-main-container {
background-color: var(--tg-bg-primary);
flex: 1;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
gap: 0;
border: none;
box-shadow: none;
}
.two-column-right-column {
background-color: var(--tg-bg-primary);
margin: 0;
}
/* Fluent content area (task list area) */
.tg-fluent-content {
background-color: var(--tg-bg-primary);
}
/* ==========================================================================
5. Header / Toolbar - Flat Look with Border Separation
========================================================================== */
/* Standard content header */
.content-header {
background-color: var(--tg-bg-primary);
border-bottom: 1px solid var(--tg-border-color);
padding: 10px 16px;
margin: 0;
}
/* Fluent top navigation bar */
.tg-fluent-top-nav {
background-color: var(--tg-bg-primary);
border-bottom: 1px solid var(--tg-border-color);
}
.fluent-top-navigation {
background-color: var(--tg-bg-primary);
}
/* Two-column headers */
.two-column-sidebar-header,
.two-column-task-header {
background-color: transparent;
border-bottom: 1px solid var(--tg-border-color);
margin: 0;
}
/* ==========================================================================
6. Toolbar Buttons - Unified Active/Hover States
========================================================================== */
/* View tabs in fluent toolbar */
.fluent-view-tab {
background-color: transparent;
border: none;
border-radius: var(--radius-s);
color: var(--text-muted);
transition:
background-color 0.15s ease,
color 0.15s ease;
}
.fluent-view-tab:hover {
background-color: var(--tg-hover-bg);
color: var(--text-normal);
}
/* Active state - use hover background as specified */
.fluent-view-tab.is-active,
.fluent-view-tab.active {
background-color: var(--tg-active-bg);
color: var(--text-normal);
box-shadow: none;
}
/* Icon buttons in toolbar */
.fluent-nav-icon-button {
background-color: transparent;
border-radius: var(--radius-s);
transition:
background-color 0.15s ease,
color 0.15s ease;
}
.fluent-nav-icon-button:hover {
background-color: var(--tg-hover-bg);
color: var(--text-normal);
}
.fluent-nav-icon-button.is-active {
background-color: var(--tg-active-bg);
}
/* Standard clickable icons */
.clickable-icon {
transition: background-color 0.15s ease;
}
.clickable-icon:hover {
background-color: var(--tg-hover-bg);
}
/* Nav buttons */
.fluent-nav-button {
background-color: transparent;
border: 1px solid var(--tg-border-color);
transition: background-color 0.15s ease;
}
.fluent-nav-button:hover {
background-color: var(--tg-hover-bg);
}
/* ==========================================================================
7. Legacy Sidebar Navigation Items (Non-Fluent)
========================================================================== */
/* Standard sidebar nav items (Legacy view) */
.sidebar-nav-item {
margin: 0 4px;
border-radius: var(--radius-s);
background-color: transparent;
transition: background-color 0.15s ease;
}
.sidebar-nav-item:hover {
background-color: var(--tg-hover-bg);
}
/* Active state - override the accent color with hover background */
.sidebar-nav-item.is-active {
background-color: var(--tg-active-bg);
color: var(--text-normal);
--background-modifier-hover: var(--tg-hover-bg);
}
/* Two-column list items */
.two-column-list-item {
border-radius: var(--radius-s);
transition: background-color 0.15s ease;
}
.two-column-list-item:hover {
background-color: var(--tg-hover-bg);
}
.two-column-list-item.selected {
background-color: var(--tg-active-bg);
}
/* ==========================================================================
8. Task List Items - Border Separation, Unified Hover
========================================================================== */
/* Standard task items */
.task-item {
background-color: transparent;
border-bottom: 1px solid var(--tg-border-color);
margin: 0;
/* border-radius: 0; */
transition: background-color 0.15s ease;
}
.task-item:hover {
background-color: var(--tg-hover-bg);
}
.task-item.selected {
background-color: var(--tg-active-bg);
}
/* Last task item - optionally remove bottom border */
.task-list > .task-item:last-child {
border-bottom: none;
}
/* Fluent task list items */
.tg-task-list-item {
background-color: transparent;
border: none;
border-bottom: 1px solid var(--tg-border-color);
border-radius: 0;
margin: 0;
transition: background-color 0.15s ease;
}
.tg-task-list-item:hover {
background-color: var(--tg-hover-bg);
box-shadow: none;
transform: none;
}
.tg-task-list-item:hover::before {
background: transparent;
}
/* ==========================================================================
9. Task List Container - Remove Gaps
========================================================================== */
.task-list {
padding: 0;
gap: 0;
}
.task-list-container {
padding: 0;
gap: 0;
}
.task-tree-container {
padding: 0;
gap: 0;
}
/* Two-column task list */
.two-column-task-list {
padding: 0;
}
.two-column-sidebar-list {
padding: 4px;
gap: 0;
}
/* ==========================================================================
10. Tree View Items
========================================================================== */
.task-genius-view .tree-item {
border-radius: var(--radius-s);
transition: background-color 0.15s ease;
}
.task-genius-view .tree-item:hover {
background-color: var(--tg-hover-bg);
}
.task-genius-view .tree-item.selected {
background-color: var(--tg-active-bg);
}
/* ==========================================================================
11. Fluent View Tabs Container
========================================================================== */
.fluent-view-tabs {
background-color: transparent;
border-radius: var(--radius-s);
padding: 2px;
gap: 2px;
}
/* ==========================================================================
12. Embedded Views
========================================================================== */
.internal-embed .task-genius-container {
border-top: 1px solid var(--tg-border-color);
}
/* ==========================================================================
13. Bases View Integration
========================================================================== */
.bases-view.task-genius-container {
border-top: none;
background-color: var(--tg-bg-primary);
}

Some files were not shown because too many files have changed in this diff Show more