Merge pull request #2 from joschuatonn/feature/chatDesign

Feature/chat design
This commit is contained in:
Joschua Tonn
2024-05-13 08:17:15 +02:00
committed by GitHub
12 changed files with 780 additions and 244 deletions

416
package-lock.json generated
View File

@@ -19,7 +19,7 @@
}, },
"devDependencies": { "devDependencies": {
"@intlify/vite-plugin-vue-i18n": "^3.3.1", "@intlify/vite-plugin-vue-i18n": "^3.3.1",
"@quasar/app-vite": "^1.8.0", "@quasar/app-vite": "^1.8.5",
"@quasar/cli": "^2.4.0", "@quasar/cli": "^2.4.0",
"@types/node": "^12.20.21", "@types/node": "^12.20.21",
"@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "^5.10.0",
@@ -351,11 +351,63 @@
} }
} }
}, },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": { "node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15", "version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
}, },
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@nodelib/fs.scandir": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -433,9 +485,9 @@
} }
}, },
"node_modules/@quasar/app-vite": { "node_modules/@quasar/app-vite": {
"version": "1.8.0", "version": "1.8.5",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.0.tgz", "resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.5.tgz",
"integrity": "sha512-/2HzIYqjm8AayyEeQq7zJnTiZZUQzHFCwEdIms8l+Po7Lhx4a7MXT7VCfR1M1KHGO0Z/EXItpjYwGryo/XNFoA==", "integrity": "sha512-OB5nU9qKIl3p7Ton9fLWkSQTv1I/7slfQl8izhZPPJZRY755Jn4Kz1exYUoEgJJ4cLSaUI/cpnVOL59pw53NEg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@quasar/render-ssr-error": "^1.0.3", "@quasar/render-ssr-error": "^1.0.3",
@@ -457,7 +509,7 @@
"express": "^4.17.3", "express": "^4.17.3",
"fast-glob": "3.2.12", "fast-glob": "3.2.12",
"fs-extra": "^11.1.0", "fs-extra": "^11.1.0",
"html-minifier": "^4.0.0", "html-minifier-terser": "^7.2.0",
"inquirer": "^8.2.1", "inquirer": "^8.2.1",
"isbinaryfile": "^5.0.0", "isbinaryfile": "^5.0.0",
"kolorist": "^1.5.1", "kolorist": "^1.5.1",
@@ -486,6 +538,7 @@
"url": "https://donate.quasar.dev" "url": "https://donate.quasar.dev"
}, },
"peerDependencies": { "peerDependencies": {
"@electron/packager": ">= 18",
"electron-builder": ">= 22", "electron-builder": ">= 22",
"electron-packager": ">= 15", "electron-packager": ">= 15",
"eslint": "^8.11.0", "eslint": "^8.11.0",
@@ -497,6 +550,9 @@
"workbox-build": ">= 6" "workbox-build": ">= 6"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@electron/packager": {
"optional": true
},
"electron-builder": { "electron-builder": {
"optional": true "optional": true
}, },
@@ -1875,6 +1931,12 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"node_modules/bundle-name": { "node_modules/bundle-name": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
@@ -1955,13 +2017,13 @@
} }
}, },
"node_modules/camel-case": { "node_modules/camel-case": {
"version": "3.0.0", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"no-case": "^2.2.0", "pascal-case": "^3.1.2",
"upper-case": "^1.1.1" "tslib": "^2.0.3"
} }
}, },
"node_modules/camelcase": { "node_modules/camelcase": {
@@ -2058,15 +2120,15 @@
} }
}, },
"node_modules/clean-css": { "node_modules/clean-css": {
"version": "4.2.4", "version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"source-map": "~0.6.0" "source-map": "~0.6.0"
}, },
"engines": { "engines": {
"node": ">= 4.0" "node": ">= 10.0"
} }
}, },
"node_modules/cli-boxes": { "node_modules/cli-boxes": {
@@ -2198,10 +2260,13 @@
} }
}, },
"node_modules/commander": { "node_modules/commander": {
"version": "2.20.3", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true "dev": true,
"engines": {
"node": ">=14"
}
}, },
"node_modules/compress-commons": { "node_modules/compress-commons": {
"version": "4.1.2", "version": "4.1.2",
@@ -2674,6 +2739,16 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/dot-prop": { "node_modules/dot-prop": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
@@ -4148,25 +4223,25 @@
"he": "bin/he" "he": "bin/he"
} }
}, },
"node_modules/html-minifier": { "node_modules/html-minifier-terser": {
"version": "4.0.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"camel-case": "^3.0.0", "camel-case": "^4.1.2",
"clean-css": "^4.2.1", "clean-css": "~5.3.2",
"commander": "^2.19.0", "commander": "^10.0.0",
"he": "^1.2.0", "entities": "^4.4.0",
"param-case": "^2.1.1", "param-case": "^3.0.4",
"relateurl": "^0.2.7", "relateurl": "^0.2.7",
"uglify-js": "^3.5.1" "terser": "^5.15.1"
}, },
"bin": { "bin": {
"html-minifier": "cli.js" "html-minifier-terser": "cli.js"
}, },
"engines": { "engines": {
"node": ">=6" "node": "^14.13.1 || >=16.0.0"
} }
}, },
"node_modules/http-cache-semantics": { "node_modules/http-cache-semantics": {
@@ -4976,10 +5051,13 @@
} }
}, },
"node_modules/lower-case": { "node_modules/lower-case": {
"version": "1.1.4", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true "dev": true,
"dependencies": {
"tslib": "^2.0.3"
}
}, },
"node_modules/lowercase-keys": { "node_modules/lowercase-keys": {
"version": "3.0.0", "version": "3.0.0",
@@ -5198,12 +5276,13 @@
} }
}, },
"node_modules/no-case": { "node_modules/no-case": {
"version": "2.3.2", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"lower-case": "^1.1.1" "lower-case": "^2.0.2",
"tslib": "^2.0.3"
} }
}, },
"node_modules/node-forge": { "node_modules/node-forge": {
@@ -5462,12 +5541,13 @@
} }
}, },
"node_modules/param-case": { "node_modules/param-case": {
"version": "2.1.1", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"no-case": "^2.2.0" "dot-case": "^3.0.4",
"tslib": "^2.0.3"
} }
}, },
"node_modules/parent-module": { "node_modules/parent-module": {
@@ -5491,6 +5571,16 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"dev": true,
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/path-browserify": { "node_modules/path-browserify": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -6552,6 +6642,16 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/stack-trace": { "node_modules/stack-trace": {
"version": "1.0.0-pre2", "version": "1.0.0-pre2",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz",
@@ -6727,6 +6827,30 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/terser": {
"version": "5.31.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz",
"integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"node_modules/text-table": { "node_modules/text-table": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -6876,18 +7000,6 @@
"node": ">=4.2.0" "node": ">=4.2.0"
} }
}, },
"node_modules/uglify-js": {
"version": "3.17.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
"dev": true,
"bin": {
"uglifyjs": "bin/uglifyjs"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/unique-string": { "node_modules/unique-string": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
@@ -7000,12 +7112,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1" "url": "https://github.com/chalk/chalk?sponsor=1"
} }
}, },
"node_modules/upper-case": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
"integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==",
"dev": true
},
"node_modules/uri-js": { "node_modules/uri-js": {
"version": "4.4.1", "version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -7830,11 +7936,54 @@
"source-map": "0.6.1" "source-map": "0.6.1"
} }
}, },
"@jridgewell/gen-mapping": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"requires": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true
},
"@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true
},
"@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"requires": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"@jridgewell/sourcemap-codec": { "@jridgewell/sourcemap-codec": {
"version": "1.4.15", "version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
}, },
"@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"@nodelib/fs.scandir": { "@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -7896,9 +8045,9 @@
} }
}, },
"@quasar/app-vite": { "@quasar/app-vite": {
"version": "1.8.0", "version": "1.8.5",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.0.tgz", "resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.5.tgz",
"integrity": "sha512-/2HzIYqjm8AayyEeQq7zJnTiZZUQzHFCwEdIms8l+Po7Lhx4a7MXT7VCfR1M1KHGO0Z/EXItpjYwGryo/XNFoA==", "integrity": "sha512-OB5nU9qKIl3p7Ton9fLWkSQTv1I/7slfQl8izhZPPJZRY755Jn4Kz1exYUoEgJJ4cLSaUI/cpnVOL59pw53NEg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@quasar/render-ssr-error": "^1.0.3", "@quasar/render-ssr-error": "^1.0.3",
@@ -7920,7 +8069,7 @@
"express": "^4.17.3", "express": "^4.17.3",
"fast-glob": "3.2.12", "fast-glob": "3.2.12",
"fs-extra": "^11.1.0", "fs-extra": "^11.1.0",
"html-minifier": "^4.0.0", "html-minifier-terser": "^7.2.0",
"inquirer": "^8.2.1", "inquirer": "^8.2.1",
"isbinaryfile": "^5.0.0", "isbinaryfile": "^5.0.0",
"kolorist": "^1.5.1", "kolorist": "^1.5.1",
@@ -8924,6 +9073,12 @@
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true "dev": true
}, },
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"bundle-name": { "bundle-name": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
@@ -8980,13 +9135,13 @@
"dev": true "dev": true
}, },
"camel-case": { "camel-case": {
"version": "3.0.0", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true, "dev": true,
"requires": { "requires": {
"no-case": "^2.2.0", "pascal-case": "^3.1.2",
"upper-case": "^1.1.1" "tslib": "^2.0.3"
} }
}, },
"camelcase": { "camelcase": {
@@ -9040,9 +9195,9 @@
"dev": true "dev": true
}, },
"clean-css": { "clean-css": {
"version": "4.2.4", "version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"dev": true, "dev": true,
"requires": { "requires": {
"source-map": "~0.6.0" "source-map": "~0.6.0"
@@ -9140,9 +9295,9 @@
} }
}, },
"commander": { "commander": {
"version": "2.20.3", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true "dev": true
}, },
"compress-commons": { "compress-commons": {
@@ -9486,6 +9641,16 @@
"esutils": "^2.0.2" "esutils": "^2.0.2"
} }
}, },
"dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"requires": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"dot-prop": { "dot-prop": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
@@ -10463,19 +10628,19 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true "dev": true
}, },
"html-minifier": { "html-minifier-terser": {
"version": "4.0.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"dev": true, "dev": true,
"requires": { "requires": {
"camel-case": "^3.0.0", "camel-case": "^4.1.2",
"clean-css": "^4.2.1", "clean-css": "~5.3.2",
"commander": "^2.19.0", "commander": "^10.0.0",
"he": "^1.2.0", "entities": "^4.4.0",
"param-case": "^2.1.1", "param-case": "^3.0.4",
"relateurl": "^0.2.7", "relateurl": "^0.2.7",
"uglify-js": "^3.5.1" "terser": "^5.15.1"
} }
}, },
"http-cache-semantics": { "http-cache-semantics": {
@@ -11069,10 +11234,13 @@
} }
}, },
"lower-case": { "lower-case": {
"version": "1.1.4", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true "dev": true,
"requires": {
"tslib": "^2.0.3"
}
}, },
"lowercase-keys": { "lowercase-keys": {
"version": "3.0.0", "version": "3.0.0",
@@ -11225,12 +11393,13 @@
"dev": true "dev": true
}, },
"no-case": { "no-case": {
"version": "2.3.2", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true, "dev": true,
"requires": { "requires": {
"lower-case": "^1.1.1" "lower-case": "^2.0.2",
"tslib": "^2.0.3"
} }
}, },
"node-forge": { "node-forge": {
@@ -11411,12 +11580,13 @@
} }
}, },
"param-case": { "param-case": {
"version": "2.1.1", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true, "dev": true,
"requires": { "requires": {
"no-case": "^2.2.0" "dot-case": "^3.0.4",
"tslib": "^2.0.3"
} }
}, },
"parent-module": { "parent-module": {
@@ -11434,6 +11604,16 @@
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"dev": true "dev": true
}, },
"pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"dev": true,
"requires": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"path-browserify": { "path-browserify": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -12187,6 +12367,16 @@
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="
}, },
"source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"stack-trace": { "stack-trace": {
"version": "1.0.0-pre2", "version": "1.0.0-pre2",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz",
@@ -12309,6 +12499,26 @@
"readable-stream": "^3.1.1" "readable-stream": "^3.1.1"
} }
}, },
"terser": {
"version": "5.31.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz",
"integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==",
"dev": true,
"requires": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"dependencies": {
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
}
}
},
"text-table": { "text-table": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -12420,12 +12630,6 @@
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"devOptional": true "devOptional": true
}, },
"uglify-js": {
"version": "3.17.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
"dev": true
},
"unique-string": { "unique-string": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
@@ -12493,12 +12697,6 @@
} }
} }
}, },
"upper-case": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
"integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==",
"dev": true
},
"uri-js": { "uri-js": {
"version": "4.4.1", "version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

View File

@@ -1,16 +1,18 @@
<script lang="ts"> <script setup lang="ts">
import { defineComponent } from 'vue'; import { RouterView } from 'vue-router';
import ProtectedData from './components/ProtectedData.vue';
export default defineComponent({ import IndexPage from 'pages/IndexPage.vue';
defineOptions({
name: 'App' name: 'App'
}); });
</script> </script>
<template> <template>
<IndexPage></IndexPage>
<router-view /> <router-view />
</template> </template>
<style scoped> <style>
header { header {
line-height: 1.5; line-height: 1.5;
display: flex; display: flex;
@@ -19,4 +21,26 @@ header {
justify-content: center; justify-content: center;
padding-top: 7vh; padding-top: 7vh;
} }
/* CUSTOM SCROLLBAR DESIGN START */
/* width */
::-webkit-scrollbar {
width: 5px;
}
/* Track */
::-webkit-scrollbar-track {
background: white;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* CUSTOM SCROLLBAR DESIGN ENDE */
</style> </style>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
const props = defineProps({
ownMessage: Boolean,
timestamp: String,
message: String,
gif: Boolean,
link: Boolean,
url: String,
})
</script>
<template>
<div class="message" :class="{'sent' : props.ownMessage, 'received' : !props.ownMessage}">
<p v-if="!props.gif && !props.link" style="margin-bottom: 0;">{{props.message}}</p>
<img v-if="props.gif" :src="props.url" alt="GIF" style="width: 100%;border-radius: 10px;" />
<a v-if="props.link" :href="props.url" target="_blank">{{props.url}}</a>
<div style="text-align: right;">
<small style="margin-top: 0;">{{props.timestamp}}</small>
</div>
</div>
</template>
<style scoped>
.message {
border-radius: 10px;
width: 15rem;
padding: 7px;
margin:3px;
box-shadow: 1px 1px 5px 0 rgba(0,0,0,0.15);
}
.message p {
max-width: 100%;
overflow-wrap: break-word;
}
.sent {
background: #729EA1;
margin-left: auto;
margin-right: 0;
}
.received {
background: white;
}
</style>

View File

@@ -0,0 +1,49 @@
<script setup lang="ts">
const props = defineProps({
displayName: String,
username: String,
profilePictureUrl: String,
status: String,
})
const profilePicture = "url("+props.profilePictureUrl+")";
</script>
<template>
<div class="profileCard">
<div class="profilePicture"></div>
<div style="margin-left:10px;">
<p style="margin-bottom: 0;line-height: 25px;vertical-align: middle;height: 25px;display: table-cell;">
<span style="font-weight: bold;font-size: 1.2rem;">{{props.displayName}}</span>
@{{props.username}}
</p>
<p style="margin: 0;">{{ props.status }}</p>
</div>
</div>
</template>
<style scoped>
.profilePicture {
width: 50px;
height: 50px;
border-radius: 50%;
background-size: cover;
background-position: center;
background-image: v-bind('profilePicture');
}
.profileCard {
display: flex;
border-radius: 10px;
padding: 10px;
transition: .3s;
cursor: pointer;
}
.profileCard:hover {
transition: .3s;
background: rgba(0,0,0,0.2);
}
</style>

View File

@@ -1,47 +1,5 @@
<template> <template>
<q-layout view="lHh Lpr lFf">
<q-header elevated>
<q-toolbar>
<q-btn
flat
dense
round
icon="menu"
aria-label="Menu"
@click="toggleLeftDrawer"
/>
<q-toolbar-title>
Quasar App
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div>
</q-toolbar>
</q-header>
<q-drawer
v-model="leftDrawerOpen"
bordered
>
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<EssentialLink
v-for="link in linksList"
:key="link.title"
v-bind="link"
/>
</q-list>
</q-drawer>
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -51,55 +9,4 @@ import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue'
defineOptions({ defineOptions({
name: 'MainLayout' name: 'MainLayout'
}); });
const linksList: EssentialLinkProps[] = [
{
title: 'Docs',
caption: 'quasar.dev',
icon: 'school',
link: 'https://quasar.dev'
},
{
title: 'Github',
caption: 'github.com/quasarframework',
icon: 'code',
link: 'https://github.com/quasarframework'
},
{
title: 'Discord Chat Channel',
caption: 'chat.quasar.dev',
icon: 'chat',
link: 'https://chat.quasar.dev'
},
{
title: 'Forum',
caption: 'forum.quasar.dev',
icon: 'record_voice_over',
link: 'https://forum.quasar.dev'
},
{
title: 'Twitter',
caption: '@quasarframework',
icon: 'rss_feed',
link: 'https://twitter.quasar.dev'
},
{
title: 'Facebook',
caption: '@QuasarFramework',
icon: 'public',
link: 'https://facebook.quasar.dev'
},
{
title: 'Quasar Awesome',
caption: 'Community Quasar projects',
icon: 'favorite',
link: 'https://awesome.quasar.dev'
}
];
const leftDrawerOpen = ref(false);
function toggleLeftDrawer () {
leftDrawerOpen.value = !leftDrawerOpen.value;
}
</script> </script>

View File

@@ -10,3 +10,34 @@ export interface responseModel {
message: string; message: string;
response: any; response: any;
} }
export interface message {
content: string;
timestamp: string;
isOwn: boolean;
gif: boolean;
link: boolean;
}
export interface tenorGif {
url: string,
duration: number,
preview: string,
dims: Array<number>,
size: number,
}
export interface testType {
nanogif: tenorGif,
mediumgif: tenorGif,
}
export interface tenorResponseElement {
id: string,
title: string,
media_formats: testType,
}
export interface tenorResponse {
results: Array<tenorGif>,
}

View File

@@ -1,25 +1,280 @@
<template> <template>
<q-page class="row items-center justify-evenly"> <div style="width:100%;display: flex; align-items: center; justify-content: space-between;height:100vh;position: fixed;">
<q-btn v-if="!userStore.keycloak" @click="login()" label="Login" /> <div style="background: gray; width: 25%;height:100%;">
<q-btn @click="$router.push('/test')" label="Test" /> <div style="display: flex; align-items: center; justify-content: space-between;" class="navigation">
</q-page> <div title="Nach Nutzern suchen" @click="activeMenu = 'search'" :class="{menuItemActive : activeMenu === 'search', menuItemInactive : activeMenu !== 'search'}">
<q-icon name="search"></q-icon>
</div>
<div title="Meine Chats anzeigen" @click="activeMenu = 'chats'" :class="{menuItemActive : activeMenu === 'chats', menuItemInactive : activeMenu !== 'chats'}">
<q-icon name="chat"></q-icon>
</div>
</div>
<div style="margin: 20px;" v-if="activeMenu == 'search'">
<q-input filled v-model="searchQuery" placeholder="Nach Nutzern suchen">
<template v-slot:prepend>
<q-icon name="search"></q-icon>
</template>
</q-input>
<div v-if="userStore.usersLoaded && searchQuery.length > 0" style="margin-top: 20px;">
<ProfileCardComponent v-for="user in userStore.users.filter(u => u.username.includes(searchQuery) || searchQuery == '*')" :displayName="user.firstName + ' ' + user.lastName" :username="user.username" profilePictureUrl="https://th.bing.com/th/id/OIP.ab5MRsPm1MXfNDVSMW6cjQHaHa?rs=1&pid=ImgDetMain" status="Hey there!"></ProfileCardComponent>
<div v-if="userStore.users.filter(u => u.username.includes(searchQuery) || searchQuery == '*').length == 0" style="text-align: center;">
<!--<q-icon name="error"></q-icon>
<p>Wir konnten keine Nutzer mit diesem Nutzernamen finden</p>-->
<img src="https://media.tenor.com/KOZLvzU0o4kAAAAd/no-results.gif" style="border-radius: 1rem;" alt="No search results found">
</div>
</div>
<p v-else>Gib einen Nutzername ein, um die Suche zu beginnen</p>
</div>
<div style="margin: 20px;" v-if="activeMenu == 'chats'">
<p>Hier werden dann die Chats angezeigt</p>
</div>
</div>
<div style="width: 75%;height: 100%;background: #DFD0BF;">
<div id="messageContainer" style="padding: 25px;overflow-y: auto;height: 90%;display: flex;flex-direction: column-reverse;">
<div v-for="(message, index) in messages" :key="index">
<MessageComponent
v-if="message.gif"
:url="message.content"
:timestamp="message.timestamp"
:own-message="message.isOwn"
gif
></MessageComponent>
<MessageComponent
v-if="!message.gif && message.link"
:url="message.content"
:timestamp="message.timestamp"
:own-message="message.isOwn"
link
></MessageComponent>
<MessageComponent
v-if="!message.gif && !message.link"
:message="message.content"
:timestamp="message.timestamp"
:own-message="message.isOwn"
></MessageComponent>
</div>
</div>
<div class="footer">
<q-input filled v-model="message" placeholder="Nachricht eingeben" tabindex="0" @keyup.enter.prevent="sendMessage">
<template v-slot:after>
<q-btn round dense flat icon="gif_box" id="sendMessageBtn" style="font-size: 1.2rem;" @click="toggleGifMenu"></q-btn>
</template> </template>
<script lang="ts"> <template v-slot:append>
import { defineComponent } from 'vue'; <q-btn round dense flat icon="send" id="sendMessageBtn" @click="sendMessage"></q-btn>
</template>
</q-input>
</div>
<!-- GIF SUCHE -->
<div style="background: white;padding: 10px;border-radius: 10px;width: 20rem;height: 30rem;overflow-y:auto;position: absolute;right:20px;bottom:5rem;" v-if="showGifMenu" id="gifSearchMenu">
<q-input v-model="gifSearch" @update:model-value="inputChanged" dense placeholder="Nach GIF suchen" id="gifSearchBar">
<template v-slot:append>
<q-icon name="search"></q-icon>
</template>
</q-input>
<div v-if="tenorStore.gifsLoaded" style="display: flex; flex-wrap: nowrap;margin-top: 20px;">
<div v-for="i in [0,1]">
<div style="display: flex;flex-wrap: wrap;">
<div v-for="gif in tenorStore.gifs.filter((e, index) => index % 2 == i)" style="margin: 3px;width: 100%;max-height: 100%;">
<img :src="gif.media_formats.nanogif.url" alt="Gif" style="width: 100%;border-radius: 10px;" class="gifPreview" @click="sendGif(gif.media_formats.mediumgif.url)">
</div>
</div>
</div>
</div>
<div style="text-align: center;" v-if="loadedGifsAmount < 50">
<q-btn round dense flat @click="loadMoreGifs" title="Mehr anzeigen">+</q-btn>
</div>
</div>
<!-- GIF SUCHE ENDE -->
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import MessageComponent from 'components/MessageComponent.vue';
import { useTenorStore } from 'stores/tenor-store';
import ProfileCardComponent from 'components/ProfileCardComponent.vue';
import {message} from 'src/models';
import {useUserStore} from 'stores/user-store'; import {useUserStore} from 'stores/user-store';
defineOptions({
export default defineComponent({ name: 'IndexPage'
components: {
},
setup() {
const userStore = useUserStore();
const login = () => {
userStore.login();
};
return { login, userStore };
}
}); });
const searchQuery = ref("")
const message = ref("");
const gifSearch = ref("");
const activeMenu = ref("search");
let loadedGifsAmount = 10;
let messages : message[] = [
{content: "Halllo", timestamp: "13:38", isOwn: true, gif: false, link: false},
{content: "https://www.google.com/", timestamp: "13:20", isOwn: false, gif: false, link: false},
{content: "Halllo", timestamp: "13:15", isOwn: false, gif: false, link: false},
{content: "Halllo", timestamp: "13:14", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:13", isOwn: true, gif: false, link: false},
{content: "https://media.tenor.com/mtiOW6O-k8YAAAAd/shrek-shrek-rizz.gif", timestamp: "13:11", isOwn: false, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Halllo", timestamp: "13:10", isOwn: true, gif: false, link: false},
{content: "Hallo", timestamp: "13:10", isOwn: true, gif: false, link: false}
];
function isUrl(url : string) {
try {
new URL(url);
return true;
} catch (err) {
return false;
}
}
function isTenorGifUrl(url : string) {
return url.startsWith("https://media.tenor.com/") && url.endsWith(".gif");
}
messages.forEach((msg) => {
if(isTenorGifUrl(msg.content)) {
msg.gif = true;
} else if(isUrl(msg.content)) {
msg.link = true;
}
})
const selectedGifURL = ref("");
const showGifMenu = ref(false);
const changed = ref(true);
function inputChanged() {
changed.value = true;
}
const tenorStore = useTenorStore();
const userStore = useUserStore();
function getGifs() {
let query = gifSearch.value != "" ? gifSearch.value : "shrek";
if(changed.value) {
tenorStore.getGifsBySearchTerm(query, loadedGifsAmount);
changed.value = false;
}
}
function toggleGifMenu() {
showGifMenu.value = !showGifMenu.value;
if(showGifMenu.value) {
// Somehow focus the input field
//document.getElementById("gifSearchBar")!.focus();
}
}
function sendMessage() {
messages.unshift({content: message.value, timestamp: new Date().toTimeString().split(' ')[0].substring(0, 5), isOwn: true, gif: false, link: false});
message.value = "";
}
function sendGif(url : string) {
messages.unshift({content: url, timestamp: new Date().toTimeString().split(' ')[0].substring(0, 5), isOwn: true, gif: true, link: false});
toggleGifMenu();
}
function loadMoreGifs() {
loadedGifsAmount += 10;
console.log(loadedGifsAmount);
changed.value = true;
}
setInterval(getGifs, 500);
userStore.getAllPtpUsers();
</script> </script>
<style scoped>
#sendMessageBtn {
transition: .3s;
}
#sendMessageBtn:hover {
transition: .3s;
background: white;
}
.gifPreview {
cursor: pointer;
transition: .3s;
}
.gifPreview:hover {
transition: .3s;
filter: brightness(0.5);
}
.footer {
width: 75%;
height:auto;
background: gray;
position: absolute;
bottom:0;
padding: 10px;
}
.navigation {
font-size: 2rem;
}
.navigation > div {
width: 50%;
text-align: center;
cursor: pointer;
transition: .3s;
}
.navigation > div:hover {
background: #555555;
transition: .3s;
}
.menuItemActive {
border-bottom: 2px solid black;
}
.menuItemInactive {
border-bottom: 2px solid transparent;
}
</style>

View File

@@ -1,13 +0,0 @@
<script setup lang="ts">
import ProtectedData from 'components/ProtectedData.vue';
</script>
<template>
<h1>Hallloooooooooo</h1>
<ProtectedData />
</template>
<style scoped>
</style>

View File

@@ -6,10 +6,6 @@ const routes: RouteRecordRaw[] = [
component: () => import('layouts/MainLayout.vue'), component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/IndexPage.vue') }], children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
}, },
{
path: '/test',
component: () => import('pages/TestPage.vue')
},
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it

26
src/stores/tenor-store.ts Normal file
View File

@@ -0,0 +1,26 @@
import { defineStore } from 'pinia';
import {api} from 'boot/axios';
import { ptpUser, responseModel, tenorResponseElement } from 'src/models';
import Keycloak from 'keycloak-js';
export const useTenorStore = defineStore('tenorStore', {
state: () => ({
gifs: [] as Array<tenorResponseElement>,
gifsLoaded: false,
}),
getters: {
},
actions: {
getGifsBySearchTerm(searchTerm : string, amount : number) {
this.loadGifsBySearchTerm(searchTerm, amount).then((response : any) => {
this.gifs = response.data.results;
this.gifsLoaded = true;
console.log(this.gifsLoaded + " / from store");
});
},
async loadGifsBySearchTerm(searchTerm : string, amount : number) : Promise<any> {
return await api.get("https://tenor.googleapis.com/v2/search?q="+searchTerm+"&key=AIzaSyBXsUPCjnmjXwcdqMLsyhrH1zm_6VYH_fY&client_key=praxistransferProjekt&limit="+amount);
}
},
});

View File

@@ -7,6 +7,8 @@ export const useUserStore = defineStore('userStore', {
state: () => ({ state: () => ({
user: null as ptpUser | null, user: null as ptpUser | null,
userLoaded: false, userLoaded: false,
users: [] as ptpUser[],
usersLoaded: false,
keycloak: null as Keycloak | null, keycloak: null as Keycloak | null,
keycloakId: "", keycloakId: "",
users: [] as ptpUser[], users: [] as ptpUser[],
@@ -22,8 +24,14 @@ export const useUserStore = defineStore('userStore', {
async loadPtpUsersByKeycloakID(keycloakID : string) : Promise<responseModel> { async loadPtpUsersByKeycloakID(keycloakID : string) : Promise<responseModel> {
return (await api.get("/users/login/"+keycloakID)).data; return (await api.get("/users/login/"+keycloakID)).data;
}, },
async loadAllUsers(){ getAllPtpUsers() {
this.users = (await api.get("/users/user")).data; this.loadAllPtpUsers().then((response : ptpUser[]) => {
this.users = response;
this.usersLoaded = true;
})
},
async loadAllPtpUsers() {
return (await api.get("/users/user")).data;
}, },
async initKeycloak() { async initKeycloak() {
/** /**
@@ -65,6 +73,6 @@ export const useUserStore = defineStore('userStore', {
}, },
async logout() { async logout() {
window.location.href= 'http://localhost:' + process.env.PORT_KEYCLOAK + '/realms/' + process.env.KEYCLOAK_REALM + '/protocol/openid-connect/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost:' + process.env.PORT_FRONTEND + '&client_id=' + process.env.KEYCLOAK_CLIENT_ID; window.location.href= 'http://localhost:' + process.env.PORT_KEYCLOAK + '/realms/' + process.env.KEYCLOAK_REALM + '/protocol/openid-connect/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost:' + process.env.PORT_FRONTEND + '&client_id=' + process.env.KEYCLOAK_CLIENT_ID;
} },
}, },
}); });

View File

@@ -3,4 +3,12 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "." "baseUrl": "."
}, },
"exclude": [
"./dist",
"./.quasar",
"./node_modules",
"./src-capacitor",
"./src-cordova",
"./quasar.config.*.temporary.compiled*"
]
} }