Compare commits

...

3 Commits

Author SHA1 Message Date
f060f11ba5 Reformat Rust code 2025-03-06 11:37:22 +01:00
cb964988d4 Fix old Matcha dialog 2025-03-06 11:31:52 +01:00
796f0ee351 Update JS Dep 2025-03-06 11:31:42 +01:00
6 changed files with 310 additions and 275 deletions

View File

@@ -1,6 +1,11 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="54" name="Rust" />
</Languages>
</inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />

View File

@@ -7,8 +7,8 @@
"compile": "tailwindcss -i styles/tailwind.css -o autoassets/main.css"
},
"devDependencies": {
"@tailwindcss/cli": "^4.0.3",
"daisyui": "5.0.0-beta.6",
"tailwindcss": "^4.0.3"
"@tailwindcss/cli": "^4.0.10",
"daisyui": "5.0.0",
"tailwindcss": "^4.0.10"
}
}

244
pnpm-lock.yaml generated
View File

@@ -9,14 +9,14 @@ importers:
.:
devDependencies:
'@tailwindcss/cli':
specifier: ^4.0.3
version: 4.0.3
specifier: ^4.0.10
version: 4.0.10
daisyui:
specifier: 5.0.0-beta.6
version: 5.0.0-beta.6
specifier: 5.0.0
version: 5.0.0
tailwindcss:
specifier: ^4.0.3
version: 4.0.3
specifier: ^4.0.10
version: 4.0.10
packages:
@@ -102,97 +102,101 @@ packages:
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
'@tailwindcss/cli@4.0.3':
resolution: {integrity: sha512-EPmuqS5e1yax6Qe1vRoWFbCCttMS/Thc+yFGSE/nzYe/BdYDlUc+OoE7D5DawAz4sI5H8v8Zx/mYyEdy+saB0w==}
'@tailwindcss/cli@4.0.10':
resolution: {integrity: sha512-V+L70OlINpdCg78q9Ihb2eJhDXnsFOBt+bDp9HO7U+nbMf7lQ/nkkSivdsQeVNI4KIp9YIInzyWBFMyFRed3qw==}
hasBin: true
'@tailwindcss/node@4.0.3':
resolution: {integrity: sha512-QsVJokOl0pJ4AbJV33D2npvLcHGPWi5MOSZtrtE0GT3tSx+3D0JE2lokLA8yHS1x3oCY/3IyRyy7XX6tmzid7A==}
'@tailwindcss/node@4.0.10':
resolution: {integrity: sha512-5YuI8pXfNkg5Ng12wgMic6jrFe4K8+eVmaC1kLsbA6g7iMgrj5fyl4hoLqHjmBDGpJXKxUAjwMSuJmc4oetnrg==}
'@tailwindcss/oxide-android-arm64@4.0.3':
resolution: {integrity: sha512-S8XOTQuMnpijZRlPm5HBzPJjZ28quB+40LSRHjRnQF6rRYKsvpr1qkY7dfwsetNdd+kMLOMDsvmuT8WnqqETvg==}
'@tailwindcss/oxide-android-arm64@4.0.10':
resolution: {integrity: sha512-HymaBJV/oB7fAMabW/EdWBrNskw9BOXoChYVnk/n3xq9LpK3eWNOcLeB4P52Bks+OpAyv8u0I/0WdrOkPRPv0A==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [android]
'@tailwindcss/oxide-darwin-arm64@4.0.3':
resolution: {integrity: sha512-smrY2DpzhXvgDhZtQlYAl8+vxJ04lv2/64C1eiRxvsRT2nkw/q+zA1/eAYKvUHat6cIuwqDku3QucmrUT6pCeg==}
'@tailwindcss/oxide-darwin-arm64@4.0.10':
resolution: {integrity: sha512-PJtNobUOQCydEpBbOmVhP+diTD8JEM7HRxgX9O72SODg+ynKDM0fNDkqKOX0CFR6+mCdOwRQdhnoulM6hM27TA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.0.3':
resolution: {integrity: sha512-NTz8x/LcGUjpZAWUxz0ZuzHao90Wj9spoQgomwB+/hgceh5gcJDfvaBYqxLFpKzVglpnbDSq1Fg0p0zI4oa5Pg==}
'@tailwindcss/oxide-darwin-x64@4.0.10':
resolution: {integrity: sha512-jUqYWjThIoLEUTX5WGwukGh0js+RGGFqjt0YhQnDyCDofBD/CBxOdbrsXX6CnYmbGw+a3BDrl0r3xbPY2fX8Mw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.0.3':
resolution: {integrity: sha512-yQc9Q0JCOp3kkAV8gKgDctXO60IkQhHpqGB+KgOccDtD5UmN6Q5+gd+lcsDyQ7N8dRuK1fAud51xQpZJgKfm7g==}
'@tailwindcss/oxide-freebsd-x64@4.0.10':
resolution: {integrity: sha512-m4SdTo/MkZJX2FEyiOjtQAsKG17q9d/RJXTlXDu6owVIM/U9TG0Vy3XdW/L4Yh0mHsayhHUJVIpvV0ZaWMs7nQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.3':
resolution: {integrity: sha512-e1ivVMLSnxTOU1O3npnxN16FEyWM/g3SuH2pP6udxXwa0/SnSAijRwcAYRpqIlhVKujr158S8UeHxQjC4fGl4w==}
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.10':
resolution: {integrity: sha512-cdq+Xa4cgYOYgg2n8RdL2/COIuW0FZJRvSg+AtGuZWG0omVS9XIf/wLlL+ln7pCTMt9zGOX1Yyryfrw12tYw4Q==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.0.3':
resolution: {integrity: sha512-PLrToqQqX6sdJ9DmMi8IxZWWrfjc9pdi9AEEPTrtMts3Jm9HBi1WqEeF1VwZZ2aW9TXloE5OwA35zuuq1Bhb/Q==}
'@tailwindcss/oxide-linux-arm64-gnu@4.0.10':
resolution: {integrity: sha512-6PMpTsv8vE0xiaPnpOptSvO99JkIqW9KrtmPYp/Khr6i9AkVmf95XGQxqcgwlU7Gdo7eb02fK5z0c5crK/pTew==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.0.3':
resolution: {integrity: sha512-YlzRxx7N1ampfgSKzEDw0iwDkJXUInR4cgNEqmR4TzHkU2Vhg59CGPJrTI7dxOBofD8+O35R13Nk9Ytyv0JUFg==}
'@tailwindcss/oxide-linux-arm64-musl@4.0.10':
resolution: {integrity: sha512-tI264V1H4yxRnYaOzYWm+5x94QtoreoBpVkX0OpQTycvnv6JPUC6wqsZkrDwpphaDitUGY+mv7rGQZ5vzB/Tlg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.0.3':
resolution: {integrity: sha512-Xfc3z/li6XkuD7Hs+Uk6pjyCXnfnd9zuQTKOyDTZJ544xc2yoMKUkuDw6Et9wb31MzU2/c0CIUpTDa71lL9KHw==}
'@tailwindcss/oxide-linux-x64-gnu@4.0.10':
resolution: {integrity: sha512-Xe15DqfzcYzozbhhgTUeZNnmnr56HdnqeollvLumxKvrCicDFkeZimz299Czyw4GeRUHZgcdccwr+Do3/Y2aZA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.0.3':
resolution: {integrity: sha512-ugKVqKzwa/cjmqSQG17aS9DYrEcQ/a5NITcgmOr3JLW4Iz64C37eoDlkC8tIepD3S/Td/ywKAolTQ8fKbjEL4g==}
'@tailwindcss/oxide-linux-x64-musl@4.0.10':
resolution: {integrity: sha512-L0NTk+UPpx4l/xD0G+UDBYhu6whA7xh415nErEnliFK8KV5lQlWz66icpHLmT4fTpAZTBaD+ul+GorlL1D1xCg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-win32-arm64-msvc@4.0.3':
resolution: {integrity: sha512-qHPDMl+UUwsk1RMJMgAXvhraWqUUT+LR/tkXix5RA39UGxtTrHwsLIN1AhNxI5i2RFXAXfmFXDqZCdyQ4dWmAQ==}
'@tailwindcss/oxide-win32-arm64-msvc@4.0.10':
resolution: {integrity: sha512-IXNvUmLBmTJNcMofOl8B0fzNvwUFPNvFE799THaEPgi16zj+WqFLVQh4N5+zuI1vgtZTaIJrZmqHhjqNPLOItg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.0.3':
resolution: {integrity: sha512-+ujwN4phBGyOsPyLgGgeCyUm4Mul+gqWVCIGuSXWgrx9xVUnf6LVXrw0BDBc9Aq1S2qMyOTX4OkCGbZeoIo8Qw==}
'@tailwindcss/oxide-win32-x64-msvc@4.0.10':
resolution: {integrity: sha512-K/51OZBREcq2J4JE8r9qdX2qjnVfUrm8AT4R+Pd9E27AiIyr7IkLQQjR3mj2Lpb/jUtQ8NS0KkJ1nXMoQpSlkQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@tailwindcss/oxide@4.0.3':
resolution: {integrity: sha512-FFcp3VNvRjjmFA39ORM27g2mbflMQljhvM7gxBAujHxUy4LXlKa6yMF9wbHdTbPqTONiCyyOYxccvJyVyI/XBg==}
'@tailwindcss/oxide@4.0.10':
resolution: {integrity: sha512-vAPYXF1c2yH8jmepA82on3kLpgrHZQ0B7Q2tPeASXnKxJx3GP/Fe0j1RB6PDmR5UntwA0y0Z0bZYwLcnw4/OGw==}
engines: {node: '>= 10'}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
daisyui@5.0.0-beta.6:
resolution: {integrity: sha512-gwXHv6MApRBrvUayzg83vS6bfZ+y7/1VGLu0a8/cEAMviS4rXLCd4AndEdlVxhq+25wkAp0CZRkNQ7O4wIoFnQ==}
daisyui@5.0.0:
resolution: {integrity: sha512-U0K9Bac3Bi3zZGm6ojrw12F0vBHTpEgf46zv/BYxLe07hF0Xnx7emIQliwaRBgJuYhY0BhwQ6wSnq5cJXHA2yA==}
detect-libc@1.0.3:
resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
engines: {node: '>=0.10'}
hasBin: true
enhanced-resolve@5.18.0:
resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==}
detect-libc@2.0.3:
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
engines: {node: '>=8'}
enhanced-resolve@5.18.1:
resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
engines: {node: '>=10.13.0'}
fill-range@7.1.1:
@@ -218,68 +222,68 @@ packages:
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
hasBin: true
lightningcss-darwin-arm64@1.29.1:
resolution: {integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==}
lightningcss-darwin-arm64@1.29.2:
resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [darwin]
lightningcss-darwin-x64@1.29.1:
resolution: {integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==}
lightningcss-darwin-x64@1.29.2:
resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [darwin]
lightningcss-freebsd-x64@1.29.1:
resolution: {integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==}
lightningcss-freebsd-x64@1.29.2:
resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [freebsd]
lightningcss-linux-arm-gnueabihf@1.29.1:
resolution: {integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==}
lightningcss-linux-arm-gnueabihf@1.29.2:
resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==}
engines: {node: '>= 12.0.0'}
cpu: [arm]
os: [linux]
lightningcss-linux-arm64-gnu@1.29.1:
resolution: {integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==}
lightningcss-linux-arm64-gnu@1.29.2:
resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
lightningcss-linux-arm64-musl@1.29.1:
resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==}
lightningcss-linux-arm64-musl@1.29.2:
resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
lightningcss-linux-x64-gnu@1.29.1:
resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==}
lightningcss-linux-x64-gnu@1.29.2:
resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
lightningcss-linux-x64-musl@1.29.1:
resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==}
lightningcss-linux-x64-musl@1.29.2:
resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
lightningcss-win32-arm64-msvc@1.29.1:
resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==}
lightningcss-win32-arm64-msvc@1.29.2:
resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [win32]
lightningcss-win32-x64-msvc@1.29.1:
resolution: {integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==}
lightningcss-win32-x64-msvc@1.29.2:
resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [win32]
lightningcss@1.29.1:
resolution: {integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==}
lightningcss@1.29.2:
resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
engines: {node: '>= 12.0.0'}
micromatch@4.0.8:
@@ -300,8 +304,8 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
tailwindcss@4.0.3:
resolution: {integrity: sha512-ImmZF0Lon5RrQpsEAKGxRvHwCvMgSC4XVlFRqmbzTEDb/3wvin9zfEZrMwgsa3yqBbPqahYcVI6lulM2S7IZAA==}
tailwindcss@4.0.10:
resolution: {integrity: sha512-Z8U/6E2BWSdDkt3IWPiphoV+8V6aNzRmu2SriSbuhm6i3QIcY3TdUJzUP5NX8M8MZuIl+v4/77Rer8u4YSrSsg==}
tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
@@ -373,79 +377,81 @@ snapshots:
'@parcel/watcher-win32-ia32': 2.5.1
'@parcel/watcher-win32-x64': 2.5.1
'@tailwindcss/cli@4.0.3':
'@tailwindcss/cli@4.0.10':
dependencies:
'@parcel/watcher': 2.5.1
'@tailwindcss/node': 4.0.3
'@tailwindcss/oxide': 4.0.3
enhanced-resolve: 5.18.0
lightningcss: 1.29.1
'@tailwindcss/node': 4.0.10
'@tailwindcss/oxide': 4.0.10
enhanced-resolve: 5.18.1
lightningcss: 1.29.2
mri: 1.2.0
picocolors: 1.1.1
tailwindcss: 4.0.3
tailwindcss: 4.0.10
'@tailwindcss/node@4.0.3':
'@tailwindcss/node@4.0.10':
dependencies:
enhanced-resolve: 5.18.0
enhanced-resolve: 5.18.1
jiti: 2.4.2
tailwindcss: 4.0.3
tailwindcss: 4.0.10
'@tailwindcss/oxide-android-arm64@4.0.3':
'@tailwindcss/oxide-android-arm64@4.0.10':
optional: true
'@tailwindcss/oxide-darwin-arm64@4.0.3':
'@tailwindcss/oxide-darwin-arm64@4.0.10':
optional: true
'@tailwindcss/oxide-darwin-x64@4.0.3':
'@tailwindcss/oxide-darwin-x64@4.0.10':
optional: true
'@tailwindcss/oxide-freebsd-x64@4.0.3':
'@tailwindcss/oxide-freebsd-x64@4.0.10':
optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.3':
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.10':
optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.0.3':
'@tailwindcss/oxide-linux-arm64-gnu@4.0.10':
optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.0.3':
'@tailwindcss/oxide-linux-arm64-musl@4.0.10':
optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.0.3':
'@tailwindcss/oxide-linux-x64-gnu@4.0.10':
optional: true
'@tailwindcss/oxide-linux-x64-musl@4.0.3':
'@tailwindcss/oxide-linux-x64-musl@4.0.10':
optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.0.3':
'@tailwindcss/oxide-win32-arm64-msvc@4.0.10':
optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.0.3':
'@tailwindcss/oxide-win32-x64-msvc@4.0.10':
optional: true
'@tailwindcss/oxide@4.0.3':
'@tailwindcss/oxide@4.0.10':
optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.0.3
'@tailwindcss/oxide-darwin-arm64': 4.0.3
'@tailwindcss/oxide-darwin-x64': 4.0.3
'@tailwindcss/oxide-freebsd-x64': 4.0.3
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.3
'@tailwindcss/oxide-linux-arm64-gnu': 4.0.3
'@tailwindcss/oxide-linux-arm64-musl': 4.0.3
'@tailwindcss/oxide-linux-x64-gnu': 4.0.3
'@tailwindcss/oxide-linux-x64-musl': 4.0.3
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.3
'@tailwindcss/oxide-win32-x64-msvc': 4.0.3
'@tailwindcss/oxide-android-arm64': 4.0.10
'@tailwindcss/oxide-darwin-arm64': 4.0.10
'@tailwindcss/oxide-darwin-x64': 4.0.10
'@tailwindcss/oxide-freebsd-x64': 4.0.10
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.10
'@tailwindcss/oxide-linux-arm64-gnu': 4.0.10
'@tailwindcss/oxide-linux-arm64-musl': 4.0.10
'@tailwindcss/oxide-linux-x64-gnu': 4.0.10
'@tailwindcss/oxide-linux-x64-musl': 4.0.10
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.10
'@tailwindcss/oxide-win32-x64-msvc': 4.0.10
braces@3.0.3:
dependencies:
fill-range: 7.1.1
daisyui@5.0.0-beta.6: {}
daisyui@5.0.0: {}
detect-libc@1.0.3: {}
enhanced-resolve@5.18.0:
detect-libc@2.0.3: {}
enhanced-resolve@5.18.1:
dependencies:
graceful-fs: 4.2.11
tapable: 2.2.1
@@ -466,50 +472,50 @@ snapshots:
jiti@2.4.2: {}
lightningcss-darwin-arm64@1.29.1:
lightningcss-darwin-arm64@1.29.2:
optional: true
lightningcss-darwin-x64@1.29.1:
lightningcss-darwin-x64@1.29.2:
optional: true
lightningcss-freebsd-x64@1.29.1:
lightningcss-freebsd-x64@1.29.2:
optional: true
lightningcss-linux-arm-gnueabihf@1.29.1:
lightningcss-linux-arm-gnueabihf@1.29.2:
optional: true
lightningcss-linux-arm64-gnu@1.29.1:
lightningcss-linux-arm64-gnu@1.29.2:
optional: true
lightningcss-linux-arm64-musl@1.29.1:
lightningcss-linux-arm64-musl@1.29.2:
optional: true
lightningcss-linux-x64-gnu@1.29.1:
lightningcss-linux-x64-gnu@1.29.2:
optional: true
lightningcss-linux-x64-musl@1.29.1:
lightningcss-linux-x64-musl@1.29.2:
optional: true
lightningcss-win32-arm64-msvc@1.29.1:
lightningcss-win32-arm64-msvc@1.29.2:
optional: true
lightningcss-win32-x64-msvc@1.29.1:
lightningcss-win32-x64-msvc@1.29.2:
optional: true
lightningcss@1.29.1:
lightningcss@1.29.2:
dependencies:
detect-libc: 1.0.3
detect-libc: 2.0.3
optionalDependencies:
lightningcss-darwin-arm64: 1.29.1
lightningcss-darwin-x64: 1.29.1
lightningcss-freebsd-x64: 1.29.1
lightningcss-linux-arm-gnueabihf: 1.29.1
lightningcss-linux-arm64-gnu: 1.29.1
lightningcss-linux-arm64-musl: 1.29.1
lightningcss-linux-x64-gnu: 1.29.1
lightningcss-linux-x64-musl: 1.29.1
lightningcss-win32-arm64-msvc: 1.29.1
lightningcss-win32-x64-msvc: 1.29.1
lightningcss-darwin-arm64: 1.29.2
lightningcss-darwin-x64: 1.29.2
lightningcss-freebsd-x64: 1.29.2
lightningcss-linux-arm-gnueabihf: 1.29.2
lightningcss-linux-arm64-gnu: 1.29.2
lightningcss-linux-arm64-musl: 1.29.2
lightningcss-linux-x64-gnu: 1.29.2
lightningcss-linux-x64-musl: 1.29.2
lightningcss-win32-arm64-msvc: 1.29.2
lightningcss-win32-x64-msvc: 1.29.2
micromatch@4.0.8:
dependencies:
@@ -524,7 +530,7 @@ snapshots:
picomatch@2.3.1: {}
tailwindcss@4.0.3: {}
tailwindcss@4.0.10: {}
tapable@2.2.1: {}

View File

@@ -1,35 +1,39 @@
use diesel::prelude::*;
use anyhow::{anyhow, Result, Context};
use anyhow::{anyhow, Context, Result};
use askama_axum::Template;
use axum::{extract::{Path, State}, http::{Method, header, StatusCode, Request, Uri}, response::{IntoResponse, Response, Html}, routing::{get, post}, Json, Router, Form, http};
use axum::http::HeaderValue;
use deadpool_diesel::sqlite::{Runtime, Manager, Pool};
use axum::{
extract::{Path, State},
http,
http::{header, Method, Request, StatusCode, Uri},
response::{Html, IntoResponse, Response},
routing::{get, post},
Form, Json, Router,
};
use clap::Parser;
use tower::{ServiceBuilder};
use deadpool_diesel::sqlite::{Manager, Pool, Runtime};
use diesel::prelude::*;
use serde::Deserialize;
use tower::ServiceBuilder;
use tower_http::{
cors::{Any, CorsLayer},
trace::{TraceLayer, DefaultOnResponse},
services::ServeDir,
LatencyUnit
};
use serde::Deserialize;
use tracing::{
info, error, debug, info_span, enabled,
instrument, Level, Span
trace::{DefaultOnResponse, TraceLayer},
LatencyUnit,
};
use tracing::{debug, enabled, error, info, info_span, instrument, Level, Span};
pub mod models;
pub mod schema;
use self::models::*;
#[derive(Parser,Clone)]
#[derive(Parser, Clone)]
struct Config {
#[arg(long,env)]
#[arg(long, env)]
database_url: String,
#[arg(long,env)]
#[arg(long, env)]
http_host: String,
#[arg(long,env)]
#[arg(long, env)]
http_port: u16,
}
@@ -41,10 +45,7 @@ struct AppContext {
async fn establish_connection(database_url: &str) -> Pool {
let manager = Manager::new(database_url, Runtime::Tokio1);
let pool = Pool::builder(manager)
.max_size(8)
.build()
.unwrap();
let pool = Pool::builder(manager).max_size(8).build().unwrap();
let _ = pool.get().await.expect("DB connection failed"); // Test if DB connection was fine
pool
}
@@ -82,10 +83,9 @@ async fn main() -> Result<()> {
.on_response(
DefaultOnResponse::new()
.level(Level::DEBUG)
.latency_unit(LatencyUnit::Millis)
.latency_unit(LatencyUnit::Millis),
);
let middlewares = ServiceBuilder::new()
.layer(tracelayer).layer(cors);
let middlewares = ServiceBuilder::new().layer(tracelayer).layer(cors);
// Launch Web Server
let app = Router::new()
// TODO: Serve a mano di favicon
@@ -100,190 +100,211 @@ async fn main() -> Result<()> {
.with_state(context.clone());
// Run our app with hyper
let listener = tokio::net::TcpListener::bind((config.http_host.as_str(), config.http_port))
.await.context(format!("Failed to bind Web Service on {}:{}", config.http_host, config.http_port))?;
.await
.context(format!(
"Failed to bind Web Service on {}:{}",
config.http_host, config.http_port
))?;
info!("Listening on {}:{}", config.http_host, config.http_port);
axum::serve(listener, app).await.context("Failed to serve Web Service")?;
axum::serve(listener, app)
.await
.context("Failed to serve Web Service")?;
Ok(())
}
#[derive(Template)]
#[template(path="feed.html")]
#[template(path = "feed.html")]
struct FeedTemplate {
feed: RssFeed
feed: RssFeed,
}
async fn get_feed(
State(ctx): State<AppContext>,
Path(feed_id): Path<i32>
) -> FeedTemplate {
async fn get_feed(State(ctx): State<AppContext>, Path(feed_id): Path<i32>) -> FeedTemplate {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let result = conn.interact(move |conn| {
rss_feeds
.find(feed_id)
.select(RssFeed::as_select())
.first(conn)
.optional()
.expect("Error loading feeds")
}).await.unwrap();
let result = conn
.interact(move |conn| {
rss_feeds
.find(feed_id)
.select(RssFeed::as_select())
.first(conn)
.optional()
.expect("Error loading feeds")
})
.await
.unwrap();
if let Some(feed) = result {
FeedTemplate{ feed }
FeedTemplate { feed }
} else {
FeedTemplate{
feed: RssFeed{
FeedTemplate {
feed: RssFeed {
id: -1,
name: "ERROR".to_string(),
feed_url: "ERROR".to_string(),
last_pub_date: Some("ERROR".to_string())
}
last_pub_date: Some("ERROR".to_string()),
},
}
}
}
#[derive(Template)]
#[template(path="feed_form.html")]
#[template(path = "feed_form.html")]
struct FeedFormTemplate {
feed: RssFeed
feed: RssFeed,
}
async fn get_feed_form(
State(ctx): State<AppContext>,
Path(feed_id): Path<i32>
Path(feed_id): Path<i32>,
) -> impl IntoResponse {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let result = conn.interact(move |conn| {
rss_feeds
.find(feed_id)
.select(RssFeed::as_select())
.first(conn)
.optional()
.expect("Error loading feeds")
}).await.unwrap();
let result = conn
.interact(move |conn| {
rss_feeds
.find(feed_id)
.select(RssFeed::as_select())
.first(conn)
.optional()
.expect("Error loading feeds")
})
.await
.unwrap();
if let Some(feed) = result {
FeedFormTemplate{ feed }
FeedFormTemplate { feed }
} else {
FeedFormTemplate{
feed: RssFeed{
FeedFormTemplate {
feed: RssFeed {
id: -1,
name: "ERROR".to_string(),
feed_url: "ERROR".to_string(),
last_pub_date: Some("ERROR".to_string())
}
last_pub_date: Some("ERROR".to_string()),
},
}
}
}
#[derive(Template)]
#[template(path="feed_inline.html")]
#[template(path = "feed_inline.html")]
struct FeedInlineTemplate {
feed: RssFeed
feed: RssFeed,
}
async fn get_feed_inline(
State(ctx): State<AppContext>,
Path(feed_id): Path<i32>
Path(feed_id): Path<i32>,
) -> impl IntoResponse {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let result = conn.interact(move |conn| {
rss_feeds
.find(feed_id)
.select(RssFeed::as_select())
.first(conn)
.optional()
.expect("Error loading feeds")
}).await.unwrap();
let result = conn
.interact(move |conn| {
rss_feeds
.find(feed_id)
.select(RssFeed::as_select())
.first(conn)
.optional()
.expect("Error loading feeds")
})
.await
.unwrap();
if let Some(feed) = result {
FeedInlineTemplate{ feed }
FeedInlineTemplate { feed }
} else {
FeedInlineTemplate{
feed: RssFeed{
FeedInlineTemplate {
feed: RssFeed {
id: -1,
name: "ERROR".to_string(),
feed_url: "ERROR".to_string(),
last_pub_date: Some("ERROR".to_string())
}
last_pub_date: Some("ERROR".to_string()),
},
}
}
}
#[derive(Deserialize, AsChangeset)]
#[diesel(table_name = crate::schema::rss_feeds)]
struct PostForm{
struct PostForm {
name: String,
feed_url: String,
}
async fn post_feed(
State(ctx): State<AppContext>,
Form(post): Form<PostForm>,
) -> impl IntoResponse {
async fn post_feed(State(ctx): State<AppContext>, Form(post): Form<PostForm>) -> impl IntoResponse {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let result = conn.interact(move |conn| {
let new_feed = NewRssFeed{name: post.name.as_str(), feed_url: post.feed_url.as_str() };
diesel::insert_into(rss_feeds)
.values(&new_feed)
.returning(RssFeed::as_select())
.get_result(conn)
.expect("Error saving new feed")
}).await.unwrap();
FeedTemplate{ feed: result }
let result = conn
.interact(move |conn| {
let new_feed = NewRssFeed {
name: post.name.as_str(),
feed_url: post.feed_url.as_str(),
};
diesel::insert_into(rss_feeds)
.values(&new_feed)
.returning(RssFeed::as_select())
.get_result(conn)
.expect("Error saving new feed")
})
.await
.unwrap();
FeedTemplate { feed: result }
}
async fn put_feed(
State(ctx): State<AppContext>,
Path(feed_id): Path<i32>,
Form(post): Form<PostForm>
Form(post): Form<PostForm>,
) -> impl IntoResponse {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let result = conn.interact(move |conn| {
diesel::update(rss_feeds.find(feed_id))
.set(post)
.returning(RssFeed::as_select())
.get_result(conn)
.expect("Error updating feed")
}).await.unwrap();
FeedTemplate{ feed: result }
let result = conn
.interact(move |conn| {
diesel::update(rss_feeds.find(feed_id))
.set(post)
.returning(RssFeed::as_select())
.get_result(conn)
.expect("Error updating feed")
})
.await
.unwrap();
FeedTemplate { feed: result }
}
#[derive(Template)]
#[template(source="\
#[template(
source = "\
{% for feed in feeds %}
{% include \"feed.html\" %}
{% endfor %}", ext="html")]
{% endfor %}",
ext = "html"
)]
struct FeedsTemplate {
feeds: Vec<RssFeed>
feeds: Vec<RssFeed>,
}
async fn get_list_feed(
State(ctx): State<AppContext>,
) -> FeedsTemplate {
async fn get_list_feed(State(ctx): State<AppContext>) -> FeedsTemplate {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let result = conn.interact(|conn| {
rss_feeds
.select(RssFeed::as_select())
.load(conn)
.expect("Error loading feeds")
}).await.unwrap();
FeedsTemplate{ feeds: result }
let result = conn
.interact(|conn| {
rss_feeds
.select(RssFeed::as_select())
.load(conn)
.expect("Error loading feeds")
})
.await
.unwrap();
FeedsTemplate { feeds: result }
}
async fn delete_feed(
State(ctx): State<AppContext>,
Path(feed_id): Path<i32>,
) -> impl IntoResponse {
async fn delete_feed(State(ctx): State<AppContext>, Path(feed_id): Path<i32>) -> impl IntoResponse {
let conn = ctx.pool.get().await.unwrap();
use self::schema::rss_feeds::dsl::*;
let num_deleted = conn.interact(move |conn| {
diesel::delete(rss_feeds.find(feed_id))
.execute(conn)
.expect("Error deleting posts")
}).await.unwrap();
let num_deleted = conn
.interact(move |conn| {
diesel::delete(rss_feeds.find(feed_id))
.execute(conn)
.expect("Error deleting posts")
})
.await
.unwrap();
if num_deleted == 0 {
(StatusCode::NOT_FOUND, "Not found")
} else {
@@ -296,12 +317,10 @@ async fn delete_feed(
#[derive(Template)]
#[template(path = "index.html")]
struct IndexTemplate {
feeds: FeedsTemplate
feeds: FeedsTemplate,
}
async fn index(
State(ctx): State<AppContext>,
) -> IndexTemplate {
async fn index(State(ctx): State<AppContext>) -> IndexTemplate {
let feeds = get_list_feed(State(ctx)).await;
IndexTemplate { feeds }
}

View File

@@ -1,29 +1,34 @@
<div id="modal" x-data>
<div class="overlay" style="z-index: 30"></div>
<dialog open style="z-index: 31">
<header>
<h2>Modify RSS Feed subscription</h2>
</header>
<form id="modify_form" hx-put="/feed/{{feed.id}}" hx-target="#feed_{{feed.id}}" hx-swap="outerHTML"
hx-indicator="#mod_indicator"
@htmx:after-on-load="document.getElementById('modal').remove()">
<label>
Name
<input type="text" name="name" value="{{feed.name}}">
</label>
<label>
Feed URL
<input type="url" name="feed_url" value="{{feed.feed_url}}">
</label>
<div id="modify_modal" x-data="{modal: null}">
<dialog class="modal" x-ref="modal" x-init="$refs.modal.showModal()" @close="$refs.modal.remove()">
<div class="modal-box">
<h3 class="text-lg font-bold pb-2">Modify RSS Feed subscription</h3>
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<form id="modify_form" hx-put="/feed/{{feed.id}}" hx-target="#feed_{{feed.id}}" hx-swap="outerHTML"
hx-indicator="#mod_indicator"
@htmx:after-on-load="$refs.modal.close()">
<fieldset class="fieldset gap-2">
<label class="floating-label">
<span>Name</span>
<input type="text" name="name" value="{{feed.name}}" class="input input-md w-full" placeholder="Name">
</label>
<label class="floating-label">
<span>Feed URL</span>
<input type="url" name="feed_url" value="{{feed.feed_url}}" class="input input-md w-full" placeholder="Feed URL">
</label>
</fieldset>
<div class="modal-action">
<button class="btn btn-primary" form="modify_form" type="submit">
Submit
<img id="mod_indicator" class="htmx-inline htmx-indicator" src="/assets/oval.svg"
style="height: 1rem; margin-left: 2px" alt="...">
</button>
</div>
</form>
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
<footer>
<button class="btn" form="modify_form" type="reset" @click="document.getElementById('modal').remove()">Close
</button>
<button class="btn" form="modify_form" type="submit">
Submit
<img id="mod_indicator" class="htmx-indicator" src="/assets/oval.svg"
style="height: 1rem; margin-left: 2px" alt="...">
</button>
</footer>
</dialog>
</div>

View File

@@ -35,7 +35,7 @@
</label>
</fieldset>
<div class="modal-action">
<button class="btn btn-primary" form="create_form" type="submit">
<button class="btn btn-primary" type="submit">
Submit
<img id="indicator" class="htmx-inline htmx-indicator" src="/assets/oval.svg"
style="height: 1rem; margin-left: 2px"