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": {
"@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",
"@types/node": "^12.20.21",
"@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": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"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": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -433,9 +485,9 @@
}
},
"node_modules/@quasar/app-vite": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.0.tgz",
"integrity": "sha512-/2HzIYqjm8AayyEeQq7zJnTiZZUQzHFCwEdIms8l+Po7Lhx4a7MXT7VCfR1M1KHGO0Z/EXItpjYwGryo/XNFoA==",
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.5.tgz",
"integrity": "sha512-OB5nU9qKIl3p7Ton9fLWkSQTv1I/7slfQl8izhZPPJZRY755Jn4Kz1exYUoEgJJ4cLSaUI/cpnVOL59pw53NEg==",
"dev": true,
"dependencies": {
"@quasar/render-ssr-error": "^1.0.3",
@@ -457,7 +509,7 @@
"express": "^4.17.3",
"fast-glob": "3.2.12",
"fs-extra": "^11.1.0",
"html-minifier": "^4.0.0",
"html-minifier-terser": "^7.2.0",
"inquirer": "^8.2.1",
"isbinaryfile": "^5.0.0",
"kolorist": "^1.5.1",
@@ -486,6 +538,7 @@
"url": "https://donate.quasar.dev"
},
"peerDependencies": {
"@electron/packager": ">= 18",
"electron-builder": ">= 22",
"electron-packager": ">= 15",
"eslint": "^8.11.0",
@@ -497,6 +550,9 @@
"workbox-build": ">= 6"
},
"peerDependenciesMeta": {
"@electron/packager": {
"optional": true
},
"electron-builder": {
"optional": true
},
@@ -1875,6 +1931,12 @@
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
@@ -1955,13 +2017,13 @@
}
},
"node_modules/camel-case": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
"integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true,
"dependencies": {
"no-case": "^2.2.0",
"upper-case": "^1.1.1"
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
}
},
"node_modules/camelcase": {
@@ -2058,15 +2120,15 @@
}
},
"node_modules/clean-css": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz",
"integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==",
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"dev": true,
"dependencies": {
"source-map": "~0.6.0"
},
"engines": {
"node": ">= 4.0"
"node": ">= 10.0"
}
},
"node_modules/cli-boxes": {
@@ -2198,10 +2260,13 @@
}
},
"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
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true,
"engines": {
"node": ">=14"
}
},
"node_modules/compress-commons": {
"version": "4.1.2",
@@ -2674,6 +2739,16 @@
"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": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
@@ -4148,25 +4223,25 @@
"he": "bin/he"
}
},
"node_modules/html-minifier": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz",
"integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==",
"node_modules/html-minifier-terser": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"dev": true,
"dependencies": {
"camel-case": "^3.0.0",
"clean-css": "^4.2.1",
"commander": "^2.19.0",
"he": "^1.2.0",
"param-case": "^2.1.1",
"camel-case": "^4.1.2",
"clean-css": "~5.3.2",
"commander": "^10.0.0",
"entities": "^4.4.0",
"param-case": "^3.0.4",
"relateurl": "^0.2.7",
"uglify-js": "^3.5.1"
"terser": "^5.15.1"
},
"bin": {
"html-minifier": "cli.js"
"html-minifier-terser": "cli.js"
},
"engines": {
"node": ">=6"
"node": "^14.13.1 || >=16.0.0"
}
},
"node_modules/http-cache-semantics": {
@@ -4976,10 +5051,13 @@
}
},
"node_modules/lower-case": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
"integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==",
"dev": true
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/lowercase-keys": {
"version": "3.0.0",
@@ -5198,12 +5276,13 @@
}
},
"node_modules/no-case": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
"integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"dependencies": {
"lower-case": "^1.1.1"
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/node-forge": {
@@ -5462,12 +5541,13 @@
}
},
"node_modules/param-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
"integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true,
"dependencies": {
"no-case": "^2.2.0"
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/parent-module": {
@@ -5491,6 +5571,16 @@
"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": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -6552,6 +6642,16 @@
"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": {
"version": "1.0.0-pre2",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz",
@@ -6727,6 +6827,30 @@
"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": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -6876,18 +7000,6 @@
"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": {
"version": "3.0.0",
"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"
}
},
"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": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -7830,11 +7936,54 @@
"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": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"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": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -7896,9 +8045,9 @@
}
},
"@quasar/app-vite": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.0.tgz",
"integrity": "sha512-/2HzIYqjm8AayyEeQq7zJnTiZZUQzHFCwEdIms8l+Po7Lhx4a7MXT7VCfR1M1KHGO0Z/EXItpjYwGryo/XNFoA==",
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.8.5.tgz",
"integrity": "sha512-OB5nU9qKIl3p7Ton9fLWkSQTv1I/7slfQl8izhZPPJZRY755Jn4Kz1exYUoEgJJ4cLSaUI/cpnVOL59pw53NEg==",
"dev": true,
"requires": {
"@quasar/render-ssr-error": "^1.0.3",
@@ -7920,7 +8069,7 @@
"express": "^4.17.3",
"fast-glob": "3.2.12",
"fs-extra": "^11.1.0",
"html-minifier": "^4.0.0",
"html-minifier-terser": "^7.2.0",
"inquirer": "^8.2.1",
"isbinaryfile": "^5.0.0",
"kolorist": "^1.5.1",
@@ -8924,6 +9073,12 @@
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
@@ -8980,13 +9135,13 @@
"dev": true
},
"camel-case": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
"integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true,
"requires": {
"no-case": "^2.2.0",
"upper-case": "^1.1.1"
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
}
},
"camelcase": {
@@ -9040,9 +9195,9 @@
"dev": true
},
"clean-css": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz",
"integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==",
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"dev": true,
"requires": {
"source-map": "~0.6.0"
@@ -9140,9 +9295,9 @@
}
},
"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==",
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true
},
"compress-commons": {
@@ -9486,6 +9641,16 @@
"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": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
@@ -10463,19 +10628,19 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"html-minifier": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz",
"integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==",
"html-minifier-terser": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"dev": true,
"requires": {
"camel-case": "^3.0.0",
"clean-css": "^4.2.1",
"commander": "^2.19.0",
"he": "^1.2.0",
"param-case": "^2.1.1",
"camel-case": "^4.1.2",
"clean-css": "~5.3.2",
"commander": "^10.0.0",
"entities": "^4.4.0",
"param-case": "^3.0.4",
"relateurl": "^0.2.7",
"uglify-js": "^3.5.1"
"terser": "^5.15.1"
}
},
"http-cache-semantics": {
@@ -11069,10 +11234,13 @@
}
},
"lower-case": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
"integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==",
"dev": true
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"requires": {
"tslib": "^2.0.3"
}
},
"lowercase-keys": {
"version": "3.0.0",
@@ -11225,12 +11393,13 @@
"dev": true
},
"no-case": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
"integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"requires": {
"lower-case": "^1.1.1"
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node-forge": {
@@ -11411,12 +11580,13 @@
}
},
"param-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
"integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true,
"requires": {
"no-case": "^2.2.0"
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"parent-module": {
@@ -11434,6 +11604,16 @@
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"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": {
"version": "1.0.1",
"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",
"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": {
"version": "1.0.0-pre2",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz",
@@ -12309,6 +12499,26 @@
"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": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -12420,12 +12630,6 @@
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"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": {
"version": "3.0.0",
"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": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

View File

@@ -1,16 +1,18 @@
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
<script setup lang="ts">
import { RouterView } from 'vue-router';
import ProtectedData from './components/ProtectedData.vue';
import IndexPage from 'pages/IndexPage.vue';
defineOptions({
name: 'App'
});
</script>
<template>
<IndexPage></IndexPage>
<router-view />
</template>
<style scoped>
<style>
header {
line-height: 1.5;
display: flex;
@@ -19,4 +21,26 @@ header {
justify-content: center;
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>

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>
<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>
<script setup lang="ts">
@@ -51,55 +9,4 @@ import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue'
defineOptions({
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>

View File

@@ -10,3 +10,34 @@ export interface responseModel {
message: string;
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>
<q-page class="row items-center justify-evenly">
<q-btn v-if="!userStore.keycloak" @click="login()" label="Login" />
<q-btn @click="$router.push('/test')" label="Test" />
</q-page>
<div style="width:100%;display: flex; align-items: center; justify-content: space-between;height:100vh;position: fixed;">
<div style="background: gray; width: 25%;height:100%;">
<div style="display: flex; align-items: center; justify-content: space-between;" class="navigation">
<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 v-slot:append>
<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 lang="ts">
import { defineComponent } from 'vue';
import { useUserStore } from 'stores/user-store';
<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';
defineOptions({
name: 'IndexPage'
});
export default defineComponent({
components: {
const searchQuery = ref("")
const message = ref("");
const gifSearch = ref("");
},
setup() {
const userStore = useUserStore();
const login = () => {
userStore.login();
};
return { login, userStore };
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>
<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'),
children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
},
{
path: '/test',
component: () => import('pages/TestPage.vue')
},
// Always leave this as last one,
// 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: () => ({
user: null as ptpUser | null,
userLoaded: false,
users: [] as ptpUser[],
usersLoaded: false,
keycloak: null as Keycloak | null,
keycloakId: "",
users: [] as ptpUser[],
@@ -22,8 +24,14 @@ export const useUserStore = defineStore('userStore', {
async loadPtpUsersByKeycloakID(keycloakID : string) : Promise<responseModel> {
return (await api.get("/users/login/"+keycloakID)).data;
},
async loadAllUsers(){
this.users = (await api.get("/users/user")).data;
getAllPtpUsers() {
this.loadAllPtpUsers().then((response : ptpUser[]) => {
this.users = response;
this.usersLoaded = true;
})
},
async loadAllPtpUsers() {
return (await api.get("/users/user")).data;
},
async initKeycloak() {
/**
@@ -65,6 +73,6 @@ export const useUserStore = defineStore('userStore', {
},
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;
}
},
},
});

View File

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