From e7ce9ac76dfc9b3bd8f4dbbfa64454d8dcada25b Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Wed, 24 May 2023 08:21:04 +0200 Subject: [PATCH] More svg injection, removing stringed html from code --- client/copy.bat | 3 + client/demo.js | 9 +- client/package-lock.json | 59 +- client/package.json | 6 +- client/prepare.bat | 2 + client/public/images/bullseye.png | Bin 1382 -> 0 bytes client/public/images/bullseye.xcf | Bin 263593 -> 0 bytes client/public/images/bullseye0.png | Bin 4552 -> 0 bytes client/public/images/bullseye1.png | Bin 3800 -> 0 bytes client/public/images/bullseye2.png | Bin 4357 -> 0 bytes client/public/images/buttons/edit.svg | 3 - client/public/images/buttons/reorder.svg | 21 - client/public/images/formations/azimuth.png | Bin 2145 -> 0 bytes client/public/images/formations/range.png | Bin 5057 -> 0 bytes client/public/images/formations/single.png | Bin 1895 -> 0 bytes client/public/images/icons/bullseye-solid.svg | 1 - client/public/images/icons/formation.png | Bin 19556 -> 0 bytes client/public/images/icons/leader.png | Bin 22070 -> 0 bytes client/public/images/icons/singleton.png | Bin 14026 -> 0 bytes .../images/icons/square-check-regular.svg | 1 - .../public/images/icons/trash-can-regular.svg | 1 - .../public/javascripts/leaflet.nauticscale.js | 38 + client/public/javascripts/svg-inject.js | 697 ------------------ client/public/stylesheets/layout/layout.css | 249 +------ client/public/stylesheets/markers/airbase.css | 39 +- .../public/stylesheets/markers/bullseye.css | 22 + client/public/stylesheets/markers/units.css | 50 +- client/public/stylesheets/olympus.css | 382 +++++++--- .../public/stylesheets/other/contextmenus.css | 226 +++--- client/public/stylesheets/other/popup.css | 10 - .../stylesheets/panels/connectionstatus.css | 16 +- .../public/stylesheets/panels/mouseinfo.css | 68 +- .../public/stylesheets/panels/unitcontrol.css | 33 +- client/public/stylesheets/panels/unitinfo.css | 107 ++- .../themes/olympus/images/actions/180.svg | 4 - .../themes/olympus/images/actions/cancel.svg | 3 - .../themes/olympus/images/actions/gas.svg | 3 - .../themes/olympus/images/actions/nothing.svg | 3 - .../themes/olympus/images/actions/rtb.svg | 3 - .../themes/olympus/images/actions/search.svg | 3 - .../images/buttons/emissions/attack.svg | 44 ++ .../images/buttons/emissions/defend.svg | 43 ++ .../olympus/images/buttons/emissions/free.svg | 43 ++ .../images/buttons/emissions/silent.svg | 43 ++ .../spawn_aircraft.svg => spawn/aircraft.svg} | 0 .../spawn_ground.svg => spawn/ground.svg} | 0 .../spawn_smoke.svg => spawn/smoke.svg} | 0 .../olympus/images/buttons/threat/evade.svg | 3 +- .../olympus}/images/icons/altitude.svg | 0 .../images/icons/arrow-pointer-solid.svg | 0 .../images/icons/arrows-to-eye-solid.svg | 0 .../images/{other => icons}/check_square.svg | 0 .../images/{other => icons}/chevron-down.svg | 0 .../olympus}/images/icons/echelon-lh.svg | 0 .../olympus}/images/icons/echelon-rh.svg | 0 .../olympus}/images/icons/echelon.svg | 0 .../olympus}/images/icons/follow.svg | 0 .../olympus}/images/icons/formation-end.svg | 0 .../images/icons/formation-middle.svg | 0 .../olympus}/images/icons/front.svg | 0 .../olympus}/images/icons/fuel.svg | 0 .../olympus}/images/icons/gears-solid.svg | 0 .../images/icons/grip-lines-solid.svg | 0 .../olympus}/images/icons/heading.svg | 0 .../olympus}/images/icons/line-abreast.svg | 0 .../images/{other => icons}/map_source.svg | 0 .../olympus/images/icons}/pin.png | Bin .../olympus}/images/icons/ruler.svg | 0 .../olympus}/images/icons/speed.svg | 0 .../images/icons/square-check-solid.svg | 0 .../olympus}/images/icons/square-regular.svg | 0 .../olympus}/images/icons/sword.svg | 0 .../olympus}/images/icons/trail.svg | 0 .../images/{mission => markers}/airbase.svg | 0 .../olympus/images/markers/bullseye.svg | 43 ++ .../olympus/images/markers}/marker-icon.png | Bin .../olympus/images/markers}/marker-shadow.png | Bin .../images/markers/temporary-icon.png} | Bin .../images/other/icons_misc_brush_blue.svg | 3 - .../images/other/icons_misc_brush_dark.svg | 3 - .../images/other/icons_misc_brush_light.svg | 3 - .../images/other/icons_misc_gas_blue.svg | 3 - .../images/other/icons_misc_gas_dark.svg | 3 - .../images/other/icons_misc_gas_light.svg | 3 - .../images/other/icons_misc_map_blue.svg | 3 - .../images/other/icons_misc_map_dark.svg | 3 - .../images/other/icons_misc_map_light.svg | 3 - .../images/other/icons_misc_plane_blue.svg | 3 - .../images/other/icons_misc_plane_dark.svg | 3 - .../images/other/icons_misc_plane_light.svg | 3 - .../images/other/icons_misc_settings_blue.svg | 3 - .../images/other/icons_misc_settings_dark.svg | 3 - .../other/icons_misc_settings_light.svg | 3 - .../images/other/icons_misc_visible_blue.svg | 3 - .../images/other/icons_misc_visible_dark.svg | 3 - .../images/other/icons_misc_visible_light.svg | 3 - .../olympus/images/splash/1.png} | Bin client/src/@types/server.d.ts | 2 +- client/src/controls/airbasecontextmenu.ts | 33 +- client/src/controls/contextmenu.ts | 15 +- client/src/controls/dropdown.ts | 52 +- client/src/controls/mapcontextmenu.ts | 14 +- client/src/controls/slider.ts | 55 +- client/src/controls/unitcontextmenu.ts | 23 +- client/src/features/featureswitches.ts | 52 +- client/src/features/toggleablefeature.ts | 12 +- client/src/map/boxselect.ts | 14 +- client/src/map/clickableminimap.ts | 12 + client/src/map/custommarker.ts | 24 + client/src/map/destinationpreviewmarker.ts | 15 + client/src/map/map.ts | 114 ++- client/src/map/temporaryunitmarker.ts | 13 + client/src/missionhandler/airbase.ts | 28 +- client/src/missionhandler/bullseye.ts | 36 + client/src/missionhandler/missionhandler.ts | 90 +-- client/src/other/utils.ts | 6 + client/src/panels/mouseinfopanel.ts | 4 +- client/src/panels/unitcontrolpanel.ts | 2 +- client/src/units/unit.ts | 223 ++++-- client/views/index.ejs | 4 +- client/views/panels/navbar.ejs | 2 +- client/views/panels/unitcontrol.ejs | 6 +- client/views/uikit/uikit.ejs | 82 +-- 123 files changed, 1439 insertions(+), 1829 deletions(-) create mode 100644 client/copy.bat create mode 100644 client/prepare.bat delete mode 100644 client/public/images/bullseye.png delete mode 100644 client/public/images/bullseye.xcf delete mode 100644 client/public/images/bullseye0.png delete mode 100644 client/public/images/bullseye1.png delete mode 100644 client/public/images/bullseye2.png delete mode 100644 client/public/images/buttons/edit.svg delete mode 100644 client/public/images/buttons/reorder.svg delete mode 100644 client/public/images/formations/azimuth.png delete mode 100644 client/public/images/formations/range.png delete mode 100644 client/public/images/formations/single.png delete mode 100644 client/public/images/icons/bullseye-solid.svg delete mode 100644 client/public/images/icons/formation.png delete mode 100644 client/public/images/icons/leader.png delete mode 100644 client/public/images/icons/singleton.png delete mode 100644 client/public/images/icons/square-check-regular.svg delete mode 100644 client/public/images/icons/trash-can-regular.svg create mode 100644 client/public/javascripts/leaflet.nauticscale.js delete mode 100644 client/public/javascripts/svg-inject.js create mode 100644 client/public/stylesheets/markers/bullseye.css delete mode 100644 client/public/themes/olympus/images/actions/180.svg delete mode 100644 client/public/themes/olympus/images/actions/cancel.svg delete mode 100644 client/public/themes/olympus/images/actions/gas.svg delete mode 100644 client/public/themes/olympus/images/actions/nothing.svg delete mode 100644 client/public/themes/olympus/images/actions/rtb.svg delete mode 100644 client/public/themes/olympus/images/actions/search.svg create mode 100644 client/public/themes/olympus/images/buttons/emissions/attack.svg create mode 100644 client/public/themes/olympus/images/buttons/emissions/defend.svg create mode 100644 client/public/themes/olympus/images/buttons/emissions/free.svg create mode 100644 client/public/themes/olympus/images/buttons/emissions/silent.svg rename client/public/themes/olympus/images/buttons/{other/spawn_aircraft.svg => spawn/aircraft.svg} (100%) rename client/public/themes/olympus/images/buttons/{other/spawn_ground.svg => spawn/ground.svg} (100%) rename client/public/themes/olympus/images/buttons/{other/spawn_smoke.svg => spawn/smoke.svg} (100%) rename client/public/{ => themes/olympus}/images/icons/altitude.svg (100%) rename client/public/{ => themes/olympus}/images/icons/arrow-pointer-solid.svg (100%) rename client/public/{ => themes/olympus}/images/icons/arrows-to-eye-solid.svg (100%) rename client/public/themes/olympus/images/{other => icons}/check_square.svg (100%) rename client/public/themes/olympus/images/{other => icons}/chevron-down.svg (100%) rename client/public/{ => themes/olympus}/images/icons/echelon-lh.svg (100%) rename client/public/{ => themes/olympus}/images/icons/echelon-rh.svg (100%) rename client/public/{ => themes/olympus}/images/icons/echelon.svg (100%) rename client/public/{ => themes/olympus}/images/icons/follow.svg (100%) rename client/public/{ => themes/olympus}/images/icons/formation-end.svg (100%) rename client/public/{ => themes/olympus}/images/icons/formation-middle.svg (100%) rename client/public/{ => themes/olympus}/images/icons/front.svg (100%) rename client/public/{ => themes/olympus}/images/icons/fuel.svg (100%) rename client/public/{ => themes/olympus}/images/icons/gears-solid.svg (100%) rename client/public/{ => themes/olympus}/images/icons/grip-lines-solid.svg (100%) rename client/public/{ => themes/olympus}/images/icons/heading.svg (100%) rename client/public/{ => themes/olympus}/images/icons/line-abreast.svg (100%) rename client/public/themes/olympus/images/{other => icons}/map_source.svg (100%) rename client/public/{images => themes/olympus/images/icons}/pin.png (100%) rename client/public/{ => themes/olympus}/images/icons/ruler.svg (100%) rename client/public/{ => themes/olympus}/images/icons/speed.svg (100%) rename client/public/{ => themes/olympus}/images/icons/square-check-solid.svg (100%) rename client/public/{ => themes/olympus}/images/icons/square-regular.svg (100%) rename client/public/{ => themes/olympus}/images/icons/sword.svg (100%) rename client/public/{ => themes/olympus}/images/icons/trail.svg (100%) rename client/public/themes/olympus/images/{mission => markers}/airbase.svg (100%) create mode 100644 client/public/themes/olympus/images/markers/bullseye.svg rename client/public/{images => themes/olympus/images/markers}/marker-icon.png (100%) rename client/public/{images => themes/olympus/images/markers}/marker-shadow.png (100%) rename client/public/{images/icon-temporary.png => themes/olympus/images/markers/temporary-icon.png} (100%) delete mode 100644 client/public/themes/olympus/images/other/icons_misc_brush_blue.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_brush_dark.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_brush_light.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_gas_blue.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_gas_dark.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_gas_light.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_map_blue.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_map_dark.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_map_light.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_plane_blue.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_plane_dark.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_plane_light.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_settings_blue.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_settings_dark.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_settings_light.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_visible_blue.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_visible_dark.svg delete mode 100644 client/public/themes/olympus/images/other/icons_misc_visible_light.svg rename client/public/{images/splash/splash_pic_ship.png => themes/olympus/images/splash/1.png} (100%) create mode 100644 client/src/map/clickableminimap.ts create mode 100644 client/src/map/custommarker.ts create mode 100644 client/src/map/destinationpreviewmarker.ts create mode 100644 client/src/map/temporaryunitmarker.ts create mode 100644 client/src/missionhandler/bullseye.ts diff --git a/client/copy.bat b/client/copy.bat new file mode 100644 index 00000000..1acc220e --- /dev/null +++ b/client/copy.bat @@ -0,0 +1,3 @@ +copy .\\node_modules\\leaflet\\dist\\leaflet.css .\\public\\stylesheets\\leaflet\\leaflet.css +copy .\\node_modules\\@iconfu\\svg-inject\\dist\\svg-inject.js .\\public\\javascripts\\svg-inject.js +copy .\\node_modules\\leaflet.nauticscale\\dist\\leaflet.nauticscale.js .\\public\\javascripts\\leaflet.nauticscale.js diff --git a/client/demo.js b/client/demo.js index ac750b83..292e2f52 100644 --- a/client/demo.js +++ b/client/demo.js @@ -677,15 +677,18 @@ class DemoDataGenerator { var ret = {bullseyes: { "0": { latitude: 37.25, - longitude: -115.8 + longitude: -115.8, + coalition: "neutral" }, "1": { latitude: 37.25, - longitude: -115.75 + longitude: -115.75, + coalition: "red" }, "2": { latitude: 37.25, - longitude: -115.7 + longitude: -115.7, + coalition: "blue" } }}; ret.time = Date.now(); diff --git a/client/package-lock.json b/client/package-lock.json index b4457d1c..44990dba 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -25,6 +25,7 @@ "devDependencies": { "@babel/preset-env": "^7.21.4", "@iconfu/svg-inject": "^1.2.3", + "@tanem/svg-injector": "^10.1.55", "@types/gtag.js": "^0.0.12", "@types/node": "^18.16.1", "@types/sortablejs": "^1.15.0", @@ -1688,9 +1689,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", + "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.11" @@ -1831,6 +1832,17 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, + "node_modules/@tanem/svg-injector": { + "version": "10.1.55", + "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-10.1.55.tgz", + "integrity": "sha512-xh8ejdvjDaH1eddZC0CdI45eeid4BIU2ppjNEhiTiWMYcLGT19KWjbES/ttDS4mq9gIAQfXx57g5zimEVohqYA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.5", + "content-type": "^1.0.5", + "tslib": "^2.5.0" + } + }, "node_modules/@types/geojson": { "version": "7946.0.10", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", @@ -2824,9 +2836,9 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } @@ -5344,9 +5356,9 @@ } }, "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", + "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==", "dev": true }, "node_modules/tty-browserify": { @@ -6842,9 +6854,9 @@ "dev": true }, "@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", + "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", "dev": true, "requires": { "regenerator-runtime": "^0.13.11" @@ -6960,6 +6972,17 @@ } } }, + "@tanem/svg-injector": { + "version": "10.1.55", + "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-10.1.55.tgz", + "integrity": "sha512-xh8ejdvjDaH1eddZC0CdI45eeid4BIU2ppjNEhiTiWMYcLGT19KWjbES/ttDS4mq9gIAQfXx57g5zimEVohqYA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.21.5", + "content-type": "^1.0.5", + "tslib": "^2.5.0" + } + }, "@types/geojson": { "version": "7946.0.10", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", @@ -7768,9 +7791,9 @@ "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==" }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, "convert-source-map": { "version": "1.1.3", @@ -9806,9 +9829,9 @@ } }, "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", + "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==", "dev": true }, "tty-browserify": { diff --git a/client/package.json b/client/package.json index 678d17e5..8fa54c31 100644 --- a/client/package.json +++ b/client/package.json @@ -5,7 +5,7 @@ "version": "v0.2.1-alpha", "private": true, "scripts": { - "copy": "copy .\\node_modules\\leaflet\\dist\\leaflet.css .\\public\\stylesheets\\leaflet\\leaflet.css & copy .\\node_modules\\@iconfu\\svg-inject\\dist\\svg-inject.js .\\public\\javascripts\\svg-inject.js", + "copy": "copy.bat", "start": "npm run copy & concurrently --kill-others \"npm run watch\" \"nodemon ./bin/www\"", "watch": "watchify .\\src\\index.ts --debug -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ]" }, @@ -16,17 +16,15 @@ "debug": "~2.6.9", "ejs": "^3.1.8", "express": "~4.16.1", - "geomag": "^1.0.0", "leaflet": "^1.9.3", "leaflet-control-mini-map": "^0.4.0", "leaflet.nauticscale": "^1.1.0", - "milsymbol": "^2.0.0", "morgan": "~1.9.1", "save": "^2.9.0" }, "devDependencies": { "@babel/preset-env": "^7.21.4", - "@iconfu/svg-inject": "^1.2.3", + "@tanem/svg-injector": "^10.1.55", "@types/gtag.js": "^0.0.12", "@types/node": "^18.16.1", "@types/sortablejs": "^1.15.0", diff --git a/client/prepare.bat b/client/prepare.bat new file mode 100644 index 00000000..f163f70e --- /dev/null +++ b/client/prepare.bat @@ -0,0 +1,2 @@ +copy .\\node_modules\\leaflet\\dist\\leaflet.css .\\public\\stylesheets\\leaflet\\leaflet.css +copy .\\node_modules\\leaflet.nauticscale\\dist\\leaflet.nauticscale.js .\\public\\javascripts\\leaflet.nauticscale.js diff --git a/client/public/images/bullseye.png b/client/public/images/bullseye.png deleted file mode 100644 index f70249546be7042ad275a9ff5d40cb7b0186ddcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1382 zcmV-s1)2JZP)EX>4Tx04R}tkv&MmP!xqvQ>7vm2Rn##$WWauh>EC_RIvyaN?V~-2a}inL6e3g z#l=x@EjakISaoo5*44pP5CnffTwR{K$3L|nWrS; zby?xO#aXS?SnHnrg~7bGlIA+CFydH30!fIFQ9~IOScuZDkzyi6=P?iekmFC1OD0zt zj2sK7LWSh`!T;d*Y|X;NxSJG=0o^aQ{V@y#c7bNyw!e>UyLkfmpMfi_?XNa~=}*$@ zZ7p&H^lt+f*KJMS11@)f!6#iZBuDbo5()+2{fxdT2MpW-y=(5=TIV=@05UYIy{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2j>AC2RkYPd~jv}000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0009$NklE=>@?WZIN8kQbo(NUeIRmER!(Y(IgT)RJtdOJ&0dDNu%h+Z0+-7y4)_l;R)* zEO6M}+1Z)>=bt(Fk3=u4sFZpPWWc*+^v$w{^F05~f1drTp=mU}*btFEaICd{1317L zW8MJABGS*YY~#TURw|XYh#ZMX4mhRM2{2Gfz0_L2^xr3d6Omj*j-n`P-^*wihFxGJ zB13EKp0&1FSnm080~W2DaUB1ulo|q~D2jes)@~1QK@hwE+H=->CG%~sTxI24ZsYGpHi}S_-4l_#)oQJO%G*BR;`kQ5KD?JjqtBlGBEUYd zzq`9DGsZ8y4gmfv=g*!i$37$3zBhT)Vz!Z7@L9)WnHlYJi%NVC~o zUr3q0v`r~Mc3rPRXKM=903 z0n$zD6UTA)UQClD$;O;!@0C*ORavuFtyUkd+w}Fc5B#RJJ}&_4+>=9pVahy^^p<|Z o`~1R)$e+fTi#*TY@qd!P0POehO~k`~g8%>k07*qoM6N<$g0tU+Z~y=R diff --git a/client/public/images/bullseye.xcf b/client/public/images/bullseye.xcf deleted file mode 100644 index 097722f6875070d185e944d4580c54f5eab676ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 263593 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�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

&cU@WqEP}0pxAU_lzzUQW0PTlI3>uc9v=VN-- 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 - - diff --git a/client/public/images/buttons/reorder.svg b/client/public/images/buttons/reorder.svg deleted file mode 100644 index 4ae9b04e..00000000 --- a/client/public/images/buttons/reorder.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - diff --git a/client/public/images/formations/azimuth.png b/client/public/images/formations/azimuth.png deleted file mode 100644 index 1264e20a86bbb26860fa032c4f3cad1cb53789b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2145 zcmbtVYfuwc6i%^L#j%~vSn%0y!{|UI**p-sfsjEGo(YctB@BWMn*|n3Hf|OYK(Mur z)rz8ku|X@A7I2`gBcd$`#iAf0U^OZu27DnFg#{Evi9$D#S39MD+?m}y=icx8&bjBF zySpO(99MCB@sx&+upKjIVQMP3m zqytt6k<6#RPD&;T0lYCB0o<5u2Fzly05^yU!7%KiKp?I&z+rJXAd3sKT^MW^9?Ol# z;Q$jCoeGF6;(1b`&qO%Nq;MNO=A#4Ix*-h`*3erzDsts^GCjLN1#vguEcgg-tnL!nNKI#P;Th zI4qGj*L#vH#NZSqq9P`_ifOLbtXxYwDAiPCA%df+h{6ZQlz?^3JaqP4+-B9A;3{U% z<Kh zGk08jO^n~>|B>>SFtS*4!X|XRk1zSX%Ikc6w3nEHe}MX%I#CovAcE^G5U;DX!Q^ z3T_$B``NS&`)^9v&vD*4rX9cEYl|L|t9o_*0T3gB;-FFi6h6U6Y~AnTRWfvfdxmE*lx8qJfTYH`VXpOx=lU$M~L*j6Rr^Cbi6 zg#vEvh@>!F9J?=}0~#qWFK=&eulsOQN$@wTk2P`o4Q5kOvy^k}Hn(4IE)-omPy$M} zc=4;w6{5eI1a=Xc4JY$k9LL0FXSx6^>yZWY#P?U7`hn!-CZB%>*Z$xP?)#nbaDnN}UH?Yk0&QD$~i+jIxKF_E5LsdW?{?s@#ZtXt>Vr9I@*6t$8Y5bC@(9 zyxPzp+MRp@ud1o7<$HRnT<_)Oz|J=M{ zMaG<#%4Q^f)W5c-#`*c+SaI)eEZzKMOTa01qqzJKiP%RhC->=dTeI25$E6v&Mb}mY zUU1!RKwlVZ8;g?m6f2gWZK+g~{osy40cWYHc`D4uem6{VRhi5;%;5e7?Mzpk(c#f=yUJYZl7CM*l<{o zw$eUgD7YlM@o;Z!)ksWuL!CC><(XK!LFgm1Y>11ozBFT-=-T$4V)G!x-A9q z=XMSeIWH&SCiXTr#_>RjwxDUH@Gm^#MOhp&6jKM(lpnKwH6fcA~(Grk;u dny|Otp*4g85}&QM`Ieu)zbHuf%ev3E{tY-Tq+$R7 diff --git a/client/public/images/formations/range.png b/client/public/images/formations/range.png deleted file mode 100644 index 9df137cb0eb556708b0a3841ff25c225470fefe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5057 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 diff --git a/client/public/images/formations/single.png b/client/public/images/formations/single.png deleted file mode 100644 index 2a92faee67cca47b4cecfd235283dbe3c53169c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmb_d4NMbP9PivF#(_FBGhndZs-RBWyK9TkgTe|eQfE;L8N_8~$K3%Z+y~c#7ATqx zN8E-~9s7t3iHdVB%a+aPB1BBwEAFHcWU@!2>8uVt^@{P9 zGYW_%^@{8m3u56@r~*2zT%a<`)3b>3LPAF>k`kc=2L=cjO2i=tQ^eXZhhE|5#egj> z!wSgnA{OcuQ%U7mHbW_#KtZu8R7oHR0>$c7I)WgyB&E}=h17^z4I>&D)hbafhQwlO zH8lMwKtO@a!>q>C>2P4CR}_dMkHN6rZdchgDo)6UQJqc)BWhT!Rss*Dt&A0Mhmy4| zpJ6akHbS6zk>*%PV#IT~5>c-J$xc*ZHRyC26g3%jS}kfY#pqJvVhnMy zDTW!Wkt0eNiWO(DWB{9t%!!rc!0;flkrL=qicA$a2J+X8(R1fwoRe=FOU{{#!89ip z2FbwE$<8|InI#|}$qYyrOakJkSfF?TNc)7c(+zISC9~0x<+wcBYhf?HAgk_c65Yjd zK@q{f^N%fQAByQ()*XJMcImNXb6bDA=D-(?`5C6BH6uMg-@bn3WMviY8+;P7?}_h- zys=0KI#qSm;F+4vG6Oq*aRNK*r~Ly?68s^iz|Mby@131u=B=AmH~0L+xuD}C6U{#s zon8F)x!iU2Wl*{ojgMHgBWcuIv1$2n?@31gM$!43zX_*`_DA1KXmq>U3Ew56xY_l6 zY0Ld0{eq;?(s;MgGazCOXY0GiR`yj!JBKhAX5 zlgoEJwSC!xs-r8sdwmgd;!MnjJYv^IPpPv8-GE(N-|siNDuY{HE;QAADtr8{ueZ1% zW<%HMTvu%kSh@5`g>%%m4go8P*9M68meve)WD2>|TO$FER#2WWIZ?Au_`GujULi3I zOpJV#VfB;@6>ii5km%m+8g7l+Q;{qg9+?y0HQKXgfT+p%Zg}g**=_BihnudxSm!zS z^{Un0{-&0f!lMSazIXBPLBMfj$nNZ(9DC0G?1gdP2a_zay1L{2rcfzfy7#psenXI3 zA3PllID+1pydxEjREG!c-Y2+~ZePy%uim=4(r+~2+Tgv53-{-p*g`!+ZYS%+=KL?O zj8!xDdqCV{r_(~C1``h!9s*J6ch}7WNgTMPjpUtcC$FS>4y#9fIS*brw6MCPr4C7K z3yo^<=-1$&FPWgk%49eg6uxN)1K}%@wuRjV?HKR7xR!T*>U}xQV|rrzo5yQi6W7uC z`MYYKFPmz8W7e;}-d|R30~zn!8VnGP7f!fW4PT4=(DVQ4E^t%+wdx;|?KHeLaLEE! j1G3LDL)(%bnJ?S2BqD77x87>$*Jn1R8$U~a_4Pjh6RrzR diff --git a/client/public/images/icons/bullseye-solid.svg b/client/public/images/icons/bullseye-solid.svg deleted file mode 100644 index c6400970..00000000 --- a/client/public/images/icons/bullseye-solid.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/icons/formation.png b/client/public/images/icons/formation.png deleted file mode 100644 index b140e9f63e07a795d4a22ccbb257607eb1c6dee6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19556 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 z 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 E0%|ysq5uE@ diff --git a/client/public/images/icons/square-check-regular.svg b/client/public/images/icons/square-check-regular.svg deleted file mode 100644 index 4ce0ff82..00000000 --- a/client/public/images/icons/square-check-regular.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/icons/trash-can-regular.svg b/client/public/images/icons/trash-can-regular.svg deleted file mode 100644 index 011e1a5e..00000000 --- a/client/public/images/icons/trash-can-regular.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/javascripts/leaflet.nauticscale.js b/client/public/javascripts/leaflet.nauticscale.js new file mode 100644 index 00000000..ccf19ac3 --- /dev/null +++ b/client/public/javascripts/leaflet.nauticscale.js @@ -0,0 +1,38 @@ +L.Control.ScaleNautic = L.Control.Scale.extend({ + options: { + nautic: false + }, + + _addScales: function(options, className, container) { + L.Control.Scale.prototype._addScales.call(this, options, className, container); + L.setOptions(options); + if (this.options.nautic) { + this._nScale = L.DomUtil.create('div', className, container); + } + }, + + _updateScales: function (maxMeters) { + L.Control.Scale.prototype._updateScales.call(this, maxMeters); + if (this.options.nautic && maxMeters) { + this._updateNautic(maxMeters); + } + }, + + _updateNautic: function (maxMeters) { + var scale = this._nScale, + maxNauticalMiles = maxMeters / 1852, nauticalMiles; + + if(maxMeters >= 1852) { + nauticalMiles = L.Control.Scale.prototype._getRoundNum.call(this, maxNauticalMiles); + } else { + nauticalMiles = maxNauticalMiles > 0.1 ? Math.round(maxNauticalMiles * 10) / 10 : Math.round(maxNauticalMiles * 100) / 100; + } + + scale.style.width = Math.round(this.options.maxWidth * (nauticalMiles / maxNauticalMiles)) - 10 + 'px'; + scale.innerHTML = nauticalMiles + ' nm'; + } +}); + +L.control.scalenautic = function (options) { + return new L.Control.ScaleNautic(options); +}; diff --git a/client/public/javascripts/svg-inject.js b/client/public/javascripts/svg-inject.js deleted file mode 100644 index 4e74af07..00000000 --- a/client/public/javascripts/svg-inject.js +++ /dev/null @@ -1,697 +0,0 @@ -/** - * SVGInject - Version 1.2.3 - * A tiny, intuitive, robust, caching solution for injecting SVG files inline into the DOM. - * - * https://github.com/iconfu/svg-inject - * - * Copyright (c) 2018 INCORS, the creators of iconfu.com - * @license MIT License - https://github.com/iconfu/svg-inject/blob/master/LICENSE - */ - -(function(window, document) { - // constants for better minification - var _CREATE_ELEMENT_ = 'createElement'; - var _GET_ELEMENTS_BY_TAG_NAME_ = 'getElementsByTagName'; - var _LENGTH_ = 'length'; - var _STYLE_ = 'style'; - var _TITLE_ = 'title'; - var _UNDEFINED_ = 'undefined'; - var _SET_ATTRIBUTE_ = 'setAttribute'; - var _GET_ATTRIBUTE_ = 'getAttribute'; - - var NULL = null; - - // constants - var __SVGINJECT = '__svgInject'; - var ID_SUFFIX = '--inject-'; - var ID_SUFFIX_REGEX = new RegExp(ID_SUFFIX + '\\d+', "g"); - var LOAD_FAIL = 'LOAD_FAIL'; - var SVG_NOT_SUPPORTED = 'SVG_NOT_SUPPORTED'; - var SVG_INVALID = 'SVG_INVALID'; - var ATTRIBUTE_EXCLUSION_NAMES = ['src', 'alt', 'onload', 'onerror']; - var A_ELEMENT = document[_CREATE_ELEMENT_]('a'); - var IS_SVG_SUPPORTED = typeof SVGRect != _UNDEFINED_; - var DEFAULT_OPTIONS = { - useCache: true, - copyAttributes: true, - makeIdsUnique: true - }; - // Map of IRI referenceable tag names to properties that can reference them. This is defined in - // https://www.w3.org/TR/SVG11/linking.html#processingIRI - var IRI_TAG_PROPERTIES_MAP = { - clipPath: ['clip-path'], - 'color-profile': NULL, - cursor: NULL, - filter: NULL, - linearGradient: ['fill', 'stroke'], - marker: ['marker', 'marker-end', 'marker-mid', 'marker-start'], - mask: NULL, - pattern: ['fill', 'stroke'], - radialGradient: ['fill', 'stroke'] - }; - var INJECTED = 1; - var FAIL = 2; - - var uniqueIdCounter = 1; - var xmlSerializer; - var domParser; - - - // creates an SVG document from an SVG string - function svgStringToSvgDoc(svgStr) { - domParser = domParser || new DOMParser(); - return domParser.parseFromString(svgStr, 'text/xml'); - } - - - // searializes an SVG element to an SVG string - function svgElemToSvgString(svgElement) { - xmlSerializer = xmlSerializer || new XMLSerializer(); - return xmlSerializer.serializeToString(svgElement); - } - - - // Returns the absolute url for the specified url - function getAbsoluteUrl(url) { - A_ELEMENT.href = url; - return A_ELEMENT.href; - } - - - // Load svg with an XHR request - function loadSvg(url, callback, errorCallback) { - if (url) { - var req = new XMLHttpRequest(); - req.onreadystatechange = function() { - if (req.readyState == 4) { - // readyState is DONE - var status = req.status; - if (status == 200) { - // request status is OK - callback(req.responseXML, req.responseText.trim()); - } else if (status >= 400) { - // request status is error (4xx or 5xx) - errorCallback(); - } else if (status == 0) { - // request status 0 can indicate a failed cross-domain call - errorCallback(); - } - } - }; - req.open('GET', url, true); - req.send(); - } - } - - - // Copy attributes from img element to svg element - function copyAttributes(imgElem, svgElem) { - var attribute; - var attributeName; - var attributeValue; - var attributes = imgElem.attributes; - for (var i = 0; i < attributes[_LENGTH_]; i++) { - attribute = attributes[i]; - attributeName = attribute.name; - // Only copy attributes not explicitly excluded from copying - if (ATTRIBUTE_EXCLUSION_NAMES.indexOf(attributeName) == -1) { - attributeValue = attribute.value; - // If img attribute is "title", insert a title element into SVG element - if (attributeName == _TITLE_) { - var titleElem; - var firstElementChild = svgElem.firstElementChild; - if (firstElementChild && firstElementChild.localName.toLowerCase() == _TITLE_) { - // If the SVG element's first child is a title element, keep it as the title element - titleElem = firstElementChild; - } else { - // If the SVG element's first child element is not a title element, create a new title - // ele,emt and set it as the first child - titleElem = document[_CREATE_ELEMENT_ + 'NS']('http://www.w3.org/2000/svg', _TITLE_); - svgElem.insertBefore(titleElem, firstElementChild); - } - // Set new title content - titleElem.textContent = attributeValue; - } else { - // Set img attribute to svg element - svgElem[_SET_ATTRIBUTE_](attributeName, attributeValue); - } - } - } - } - - - // This function appends a suffix to IDs of referenced elements in the in order to to avoid ID collision - // between multiple injected SVGs. The suffix has the form "--inject-X", where X is a running number which is - // incremented with each injection. References to the IDs are adjusted accordingly. - // We assume tha all IDs within the injected SVG are unique, therefore the same suffix can be used for all IDs of one - // injected SVG. - // If the onlyReferenced argument is set to true, only those IDs will be made unique that are referenced from within the SVG - function makeIdsUnique(svgElem, onlyReferenced) { - var idSuffix = ID_SUFFIX + uniqueIdCounter++; - // Regular expression for functional notations of an IRI references. This will find occurences in the form - // url(#anyId) or url("#anyId") (for Internet Explorer) and capture the referenced ID - var funcIriRegex = /url\("?#([a-zA-Z][\w:.-]*)"?\)/g; - // Get all elements with an ID. The SVG spec recommends to put referenced elements inside elements, but - // this is not a requirement, therefore we have to search for IDs in the whole SVG. - var idElements = svgElem.querySelectorAll('[id]'); - var idElem; - // An object containing referenced IDs as keys is used if only referenced IDs should be uniquified. - // If this object does not exist, all IDs will be uniquified. - var referencedIds = onlyReferenced ? [] : NULL; - var tagName; - var iriTagNames = {}; - var iriProperties = []; - var changed = false; - var i, j; - - if (idElements[_LENGTH_]) { - // Make all IDs unique by adding the ID suffix and collect all encountered tag names - // that are IRI referenceable from properities. - for (i = 0; i < idElements[_LENGTH_]; i++) { - tagName = idElements[i].localName; // Use non-namespaced tag name - // Make ID unique if tag name is IRI referenceable - if (tagName in IRI_TAG_PROPERTIES_MAP) { - iriTagNames[tagName] = 1; - } - } - // Get all properties that are mapped to the found IRI referenceable tags - for (tagName in iriTagNames) { - (IRI_TAG_PROPERTIES_MAP[tagName] || [tagName]).forEach(function (mappedProperty) { - // Add mapped properties to array of iri referencing properties. - // Use linear search here because the number of possible entries is very small (maximum 11) - if (iriProperties.indexOf(mappedProperty) < 0) { - iriProperties.push(mappedProperty); - } - }); - } - if (iriProperties[_LENGTH_]) { - // Add "style" to properties, because it may contain references in the form 'style="fill:url(#myFill)"' - iriProperties.push(_STYLE_); - } - // Run through all elements of the SVG and replace IDs in references. - // To get all descending elements, getElementsByTagName('*') seems to perform faster than querySelectorAll('*'). - // Since svgElem.getElementsByTagName('*') does not return the svg element itself, we have to handle it separately. - var descElements = svgElem[_GET_ELEMENTS_BY_TAG_NAME_]('*'); - var element = svgElem; - var propertyName; - var value; - var newValue; - for (i = -1; element != NULL;) { - if (element.localName == _STYLE_) { - // If element is a style element, replace IDs in all occurences of "url(#anyId)" in text content - value = element.textContent; - newValue = value && value.replace(funcIriRegex, function(match, id) { - if (referencedIds) { - referencedIds[id] = 1; - } - return 'url(#' + id + idSuffix + ')'; - }); - if (newValue !== value) { - element.textContent = newValue; - } - } else if (element.hasAttributes()) { - // Run through all property names for which IDs were found - for (j = 0; j < iriProperties[_LENGTH_]; j++) { - propertyName = iriProperties[j]; - value = element[_GET_ATTRIBUTE_](propertyName); - newValue = value && value.replace(funcIriRegex, function(match, id) { - if (referencedIds) { - referencedIds[id] = 1; - } - return 'url(#' + id + idSuffix + ')'; - }); - if (newValue !== value) { - element[_SET_ATTRIBUTE_](propertyName, newValue); - } - } - // Replace IDs in xlink:ref and href attributes - ['xlink:href', 'href'].forEach(function(refAttrName) { - var iri = element[_GET_ATTRIBUTE_](refAttrName); - if (/^\s*#/.test(iri)) { // Check if iri is non-null and internal reference - iri = iri.trim(); - element[_SET_ATTRIBUTE_](refAttrName, iri + idSuffix); - if (referencedIds) { - // Add ID to referenced IDs - referencedIds[iri.substring(1)] = 1; - } - } - }); - } - element = descElements[++i]; - } - for (i = 0; i < idElements[_LENGTH_]; i++) { - idElem = idElements[i]; - // If set of referenced IDs exists, make only referenced IDs unique, - // otherwise make all IDs unique. - if (!referencedIds || referencedIds[idElem.id]) { - // Add suffix to element's ID - idElem.id += idSuffix; - changed = true; - } - } - } - // return true if SVG element has changed - return changed; - } - - - // For cached SVGs the IDs are made unique by simply replacing the already inserted unique IDs with a - // higher ID counter. This is much more performant than a call to makeIdsUnique(). - function makeIdsUniqueCached(svgString) { - return svgString.replace(ID_SUFFIX_REGEX, ID_SUFFIX + uniqueIdCounter++); - } - - - // Inject SVG by replacing the img element with the SVG element in the DOM - function inject(imgElem, svgElem, absUrl, options) { - if (svgElem) { - svgElem[_SET_ATTRIBUTE_]('data-inject-url', absUrl); - var parentNode = imgElem.parentNode; - if (parentNode) { - if (options.copyAttributes) { - copyAttributes(imgElem, svgElem); - } - // Invoke beforeInject hook if set - var beforeInject = options.beforeInject; - var injectElem = (beforeInject && beforeInject(imgElem, svgElem)) || svgElem; - // Replace img element with new element. This is the actual injection. - parentNode.replaceChild(injectElem, imgElem); - // Mark img element as injected - imgElem[__SVGINJECT] = INJECTED; - removeOnLoadAttribute(imgElem); - // Invoke afterInject hook if set - var afterInject = options.afterInject; - if (afterInject) { - afterInject(imgElem, injectElem); - } - } - } else { - svgInvalid(imgElem, options); - } - } - - - // Merges any number of options objects into a new object - function mergeOptions() { - var mergedOptions = {}; - var args = arguments; - // Iterate over all specified options objects and add all properties to the new options object - for (var i = 0; i < args[_LENGTH_]; i++) { - var argument = args[i]; - for (var key in argument) { - if (argument.hasOwnProperty(key)) { - mergedOptions[key] = argument[key]; - } - } - } - return mergedOptions; - } - - - // Adds the specified CSS to the document's element - function addStyleToHead(css) { - var head = document[_GET_ELEMENTS_BY_TAG_NAME_]('head')[0]; - if (head) { - var style = document[_CREATE_ELEMENT_](_STYLE_); - style.type = 'text/css'; - style.appendChild(document.createTextNode(css)); - head.appendChild(style); - } - } - - - // Builds an SVG element from the specified SVG string - function buildSvgElement(svgStr, verify) { - if (verify) { - var svgDoc; - try { - // Parse the SVG string with DOMParser - svgDoc = svgStringToSvgDoc(svgStr); - } catch(e) { - return NULL; - } - if (svgDoc[_GET_ELEMENTS_BY_TAG_NAME_]('parsererror')[_LENGTH_]) { - // DOMParser does not throw an exception, but instead puts parsererror tags in the document - return NULL; - } - return svgDoc.documentElement; - } else { - var div = document.createElement('div'); - div.innerHTML = svgStr; - return div.firstElementChild; - } - } - - - function removeOnLoadAttribute(imgElem) { - // Remove the onload attribute. Should only be used to remove the unstyled image flash protection and - // make the element visible, not for removing the event listener. - imgElem.removeAttribute('onload'); - } - - - function errorMessage(msg) { - console.error('SVGInject: ' + msg); - } - - - function fail(imgElem, status, options) { - imgElem[__SVGINJECT] = FAIL; - if (options.onFail) { - options.onFail(imgElem, status); - } else { - errorMessage(status); - } - } - - - function svgInvalid(imgElem, options) { - removeOnLoadAttribute(imgElem); - fail(imgElem, SVG_INVALID, options); - } - - - function svgNotSupported(imgElem, options) { - removeOnLoadAttribute(imgElem); - fail(imgElem, SVG_NOT_SUPPORTED, options); - } - - - function loadFail(imgElem, options) { - fail(imgElem, LOAD_FAIL, options); - } - - - function removeEventListeners(imgElem) { - imgElem.onload = NULL; - imgElem.onerror = NULL; - } - - - function imgNotSet(msg) { - errorMessage('no img element'); - } - - - function createSVGInject(globalName, options) { - var defaultOptions = mergeOptions(DEFAULT_OPTIONS, options); - var svgLoadCache = {}; - - if (IS_SVG_SUPPORTED) { - // If the browser supports SVG, add a small stylesheet that hides the elements until - // injection is finished. This avoids showing the unstyled SVGs before style is applied. - addStyleToHead('img[onload^="' + globalName + '("]{visibility:hidden;}'); - } - - - /** - * SVGInject - * - * Injects the SVG specified in the `src` attribute of the specified `img` element or array of `img` - * elements. Returns a Promise object which resolves if all passed in `img` elements have either been - * injected or failed to inject (Only if a global Promise object is available like in all modern browsers - * or through a polyfill). - * - * Options: - * useCache: If set to `true` the SVG will be cached using the absolute URL. Default value is `true`. - * copyAttributes: If set to `true` the attributes will be copied from `img` to `svg`. Dfault value - * is `true`. - * makeIdsUnique: If set to `true` the ID of elements in the `` element that can be references by - * property values (for example 'clipPath') are made unique by appending "--inject-X", where X is a - * running number which increases with each injection. This is done to avoid duplicate IDs in the DOM. - * beforeLoad: Hook before SVG is loaded. The `img` element is passed as a parameter. If the hook returns - * a string it is used as the URL instead of the `img` element's `src` attribute. - * afterLoad: Hook after SVG is loaded. The loaded `svg` element and `svg` string are passed as a - * parameters. If caching is active this hook will only get called once for injected SVGs with the - * same absolute path. Changes to the `svg` element in this hook will be applied to all injected SVGs - * with the same absolute path. It's also possible to return an `svg` string or `svg` element which - * will then be used for the injection. - * beforeInject: Hook before SVG is injected. The `img` and `svg` elements are passed as parameters. If - * any html element is returned it gets injected instead of applying the default SVG injection. - * afterInject: Hook after SVG is injected. The `img` and `svg` elements are passed as parameters. - * onAllFinish: Hook after all `img` elements passed to an SVGInject() call have either been injected or - * failed to inject. - * onFail: Hook after injection fails. The `img` element and a `status` string are passed as an parameter. - * The `status` can be either `'SVG_NOT_SUPPORTED'` (the browser does not support SVG), - * `'SVG_INVALID'` (the SVG is not in a valid format) or `'LOAD_FAILED'` (loading of the SVG failed). - * - * @param {HTMLImageElement} img - an img element or an array of img elements - * @param {Object} [options] - optional parameter with [options](#options) for this injection. - */ - function SVGInject(img, options) { - options = mergeOptions(defaultOptions, options); - - var run = function(resolve) { - var allFinish = function() { - var onAllFinish = options.onAllFinish; - if (onAllFinish) { - onAllFinish(); - } - resolve && resolve(); - }; - - if (img && typeof img[_LENGTH_] != _UNDEFINED_) { - // an array like structure of img elements - var injectIndex = 0; - var injectCount = img[_LENGTH_]; - - if (injectCount == 0) { - allFinish(); - } else { - var finish = function() { - if (++injectIndex == injectCount) { - allFinish(); - } - }; - - for (var i = 0; i < injectCount; i++) { - SVGInjectElement(img[i], options, finish); - } - } - } else { - // only one img element - SVGInjectElement(img, options, allFinish); - } - }; - - // return a Promise object if globally available - return typeof Promise == _UNDEFINED_ ? run() : new Promise(run); - } - - - // Injects a single svg element. Options must be already merged with the default options. - function SVGInjectElement(imgElem, options, callback) { - if (imgElem) { - var svgInjectAttributeValue = imgElem[__SVGINJECT]; - if (!svgInjectAttributeValue) { - removeEventListeners(imgElem); - - if (!IS_SVG_SUPPORTED) { - svgNotSupported(imgElem, options); - callback(); - return; - } - // Invoke beforeLoad hook if set. If the beforeLoad returns a value use it as the src for the load - // URL path. Else use the imgElem's src attribute value. - var beforeLoad = options.beforeLoad; - var src = (beforeLoad && beforeLoad(imgElem)) || imgElem[_GET_ATTRIBUTE_]('src'); - - if (!src) { - // If no image src attribute is set do no injection. This can only be reached by using javascript - // because if no src attribute is set the onload and onerror events do not get called - if (src === '') { - loadFail(imgElem, options); - } - callback(); - return; - } - - // set array so later calls can register callbacks - var onFinishCallbacks = []; - imgElem[__SVGINJECT] = onFinishCallbacks; - - var onFinish = function() { - callback(); - onFinishCallbacks.forEach(function(onFinishCallback) { - onFinishCallback(); - }); - }; - - var absUrl = getAbsoluteUrl(src); - var useCacheOption = options.useCache; - var makeIdsUniqueOption = options.makeIdsUnique; - - var setSvgLoadCacheValue = function(val) { - if (useCacheOption) { - svgLoadCache[absUrl].forEach(function(svgLoad) { - svgLoad(val); - }); - svgLoadCache[absUrl] = val; - } - }; - - if (useCacheOption) { - var svgLoad = svgLoadCache[absUrl]; - - var handleLoadValue = function(loadValue) { - if (loadValue === LOAD_FAIL) { - loadFail(imgElem, options); - } else if (loadValue === SVG_INVALID) { - svgInvalid(imgElem, options); - } else { - var hasUniqueIds = loadValue[0]; - var svgString = loadValue[1]; - var uniqueIdsSvgString = loadValue[2]; - var svgElem; - - if (makeIdsUniqueOption) { - if (hasUniqueIds === NULL) { - // IDs for the SVG string have not been made unique before. This may happen if previous - // injection of a cached SVG have been run with the option makedIdsUnique set to false - svgElem = buildSvgElement(svgString, false); - hasUniqueIds = makeIdsUnique(svgElem, false); - - loadValue[0] = hasUniqueIds; - loadValue[2] = hasUniqueIds && svgElemToSvgString(svgElem); - } else if (hasUniqueIds) { - // Make IDs unique for already cached SVGs with better performance - svgString = makeIdsUniqueCached(uniqueIdsSvgString); - } - } - - svgElem = svgElem || buildSvgElement(svgString, false); - - inject(imgElem, svgElem, absUrl, options); - } - onFinish(); - }; - - if (typeof svgLoad != _UNDEFINED_) { - // Value for url exists in cache - if (svgLoad.isCallbackQueue) { - // Same url has been cached, but value has not been loaded yet, so add to callbacks - svgLoad.push(handleLoadValue); - } else { - handleLoadValue(svgLoad); - } - return; - } else { - var svgLoad = []; - // set property isCallbackQueue to Array to differentiate from array with cached loaded values - svgLoad.isCallbackQueue = true; - svgLoadCache[absUrl] = svgLoad; - } - } - - // Load the SVG because it is not cached or caching is disabled - loadSvg(absUrl, function(svgXml, svgString) { - // Use the XML from the XHR request if it is an instance of Document. Otherwise - // (for example of IE9), create the svg document from the svg string. - var svgElem = svgXml instanceof Document ? svgXml.documentElement : buildSvgElement(svgString, true); - - var afterLoad = options.afterLoad; - if (afterLoad) { - // Invoke afterLoad hook which may modify the SVG element. After load may also return a new - // svg element or svg string - var svgElemOrSvgString = afterLoad(svgElem, svgString) || svgElem; - if (svgElemOrSvgString) { - // Update svgElem and svgString because of modifications to the SVG element or SVG string in - // the afterLoad hook, so the modified SVG is also used for all later cached injections - var isString = typeof svgElemOrSvgString == 'string'; - svgString = isString ? svgElemOrSvgString : svgElemToSvgString(svgElem); - svgElem = isString ? buildSvgElement(svgElemOrSvgString, true) : svgElemOrSvgString; - } - } - - if (svgElem instanceof SVGElement) { - var hasUniqueIds = NULL; - if (makeIdsUniqueOption) { - hasUniqueIds = makeIdsUnique(svgElem, false); - } - - if (useCacheOption) { - var uniqueIdsSvgString = hasUniqueIds && svgElemToSvgString(svgElem); - // set an array with three entries to the load cache - setSvgLoadCacheValue([hasUniqueIds, svgString, uniqueIdsSvgString]); - } - - inject(imgElem, svgElem, absUrl, options); - } else { - svgInvalid(imgElem, options); - setSvgLoadCacheValue(SVG_INVALID); - } - onFinish(); - }, function() { - loadFail(imgElem, options); - setSvgLoadCacheValue(LOAD_FAIL); - onFinish(); - }); - } else { - if (Array.isArray(svgInjectAttributeValue)) { - // svgInjectAttributeValue is an array. Injection is not complete so register callback - svgInjectAttributeValue.push(callback); - } else { - callback(); - } - } - } else { - imgNotSet(); - } - } - - - /** - * Sets the default [options](#options) for SVGInject. - * - * @param {Object} [options] - default [options](#options) for an injection. - */ - SVGInject.setOptions = function(options) { - defaultOptions = mergeOptions(defaultOptions, options); - }; - - - // Create a new instance of SVGInject - SVGInject.create = createSVGInject; - - - /** - * Used in onerror Event of an `` element to handle cases when the loading the original src fails - * (for example if file is not found or if the browser does not support SVG). This triggers a call to the - * options onFail hook if available. The optional second parameter will be set as the new src attribute - * for the img element. - * - * @param {HTMLImageElement} img - an img element - * @param {String} [fallbackSrc] - optional parameter fallback src - */ - SVGInject.err = function(img, fallbackSrc) { - if (img) { - if (img[__SVGINJECT] != FAIL) { - removeEventListeners(img); - - if (!IS_SVG_SUPPORTED) { - svgNotSupported(img, defaultOptions); - } else { - removeOnLoadAttribute(img); - loadFail(img, defaultOptions); - } - if (fallbackSrc) { - removeOnLoadAttribute(img); - img.src = fallbackSrc; - } - } - } else { - imgNotSet(); - } - }; - - window[globalName] = SVGInject; - - return SVGInject; - } - - var SVGInjectInstance = createSVGInject('SVGInject'); - - if (typeof module == 'object' && typeof module.exports == 'object') { - module.exports = SVGInjectInstance; - } -})(window, document); \ No newline at end of file diff --git a/client/public/stylesheets/layout/layout.css b/client/public/stylesheets/layout/layout.css index dfa23432..91926b4b 100644 --- a/client/public/stylesheets/layout/layout.css +++ b/client/public/stylesheets/layout/layout.css @@ -7,240 +7,69 @@ #primary-toolbar { align-items: center; - display:flex; - position: absolute; + display: flex; left: 10px; + position: absolute; top: 10px; z-index: 1000; } -#olympus-toolbar-summary { +#toolbar-summary { background-image: url("/images/icon-round.png"); background-position: 20px 22px; background-repeat: no-repeat; background-size: 45px 45px; display: flex; flex-direction: column; - text-indent: 60px; padding: 20px; + text-indent: 60px; } -dl.ol-data-grid { - align-items: center; - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin: 0; - row-gap: 4px; -} - -dl.ol-data-grid dt { - width: 60%; -} - -dl.ol-data-grid dd { - width: 40%; -} - - -dl.ol-data-grid dt.icon { - text-indent: 10px; -} - -dl.ol-data-grid dt.icon::before { - content: url(/images/icons/speed.svg ); - display: inline-block; - filter: invert(100%); - width: 20px; - translate: -20px 2px; -} - - -dl.ol-data-grid dt.icon-speed::before { - content: url(/images/icons/speed.svg ); -} - - -dl.ol-data-grid dt.icon-altitude::before { - content: url(/images/icons/altitude.svg ); -} - -dl.ol-data-grid dd { - display: flex; - justify-content: flex-end; - margin-left: auto; -} - -.br-info::after { - content: attr(data-bearing) '\00B0 / ' attr(data-distance) attr(data-distance-units); -} - -.br-info[data-message]::after { - content: attr(data-message); -} - -.coordinates::after { - content: attr(data-dd) "\00b0 " attr(data-mm) "'" attr(data-ss) "." attr(data-sss) '"' attr(data-label); -} - -.ol-button-box { - column-gap: 6px; - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin: 5px 0; - row-gap: 5px; -} - -.ol-button-box button { - background-repeat: no-repeat; - ; - border: 1px solid var(--accent-light-blue); - color: var(--accent-light-blue); -} - -.ol-dialog { - align-self: center; - background-color: var(--background-slate-blue); - color: white; - justify-self: center; +#connection-status-panel { + bottom: 20px; + font-size: 12px; position: absolute; + right: 10px; + width: 160px; z-index: 1000; } -.ol-panel.ol-dialog { - padding: 24px 30px; -} - -.ol-dialog-close { - cursor: pointer; - font-size: 16px; - font-weight: var(--font-weight-bolder); +#mouse-info-panel { + bottom: 60px; + display: flex; + flex-direction: column; + height: fit-content; position: absolute; - right: 20px; - top: 10px; -} - -.ol-dialog-close::before { - content: "\d7"; -} - -.ol-dialog-header { - border-bottom: 1px solid var(--background-grey); - padding-bottom: 10px; -} - -.ol-dialog-content { - margin:4px 0; -} - -.ol-dialog-footer { - border-top: 1px solid var(--background-grey); - padding-top: 15px; - display: flex; + right: 10px; row-gap: 10px; + width: 160px; + z-index: 1000; } -.ol-dialog.scrollable .ol-dialog-content { - overflow-y: auto; +#unit-control-panel { + height: fit-content; + left: 10px; + position: absolute; + top: 80px; + width: 240px; + z-index: 1000; } -.ol-checkbox label { - align-items: center; - cursor: pointer; - display: flex; - flex-wrap: nowrap; - white-space: nowrap; +#unit-info-panel { + bottom: 20px; + font-size: 12px; + left: 10px; + position: absolute; + width: fit-content; + z-index: 1000; } -.ol-checkbox input[type="checkbox"] { - appearance: none; - background-color: transparent; - border: none; - margin: 0; -} - -.ol-checkbox input[type="checkbox"]::before { - align-self: center; - background-image: url("/images/icons/square-regular.svg"); - background-repeat: no-repeat; - content: ""; - filter: invert(100%); - display: flex; - height: 16px; - margin-right: 10px; - width: 16px; -} - -.ol-checkbox input[type="checkbox"]:checked::before { - background-image: url("/images/icons/square-check-solid.svg"); -} - -.ol-text-input input { - height: 32px; - border-radius: 5px; - color: var(--background-offwhite); - background-color: var(--background-grey); - border: 1px solid var(--background-grey); - border-radius: var(--border-radius-sm); - text-align: center; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); -} - -input[type=number] { - -moz-appearance: textfield; - appearance: textfield; - margin: 0; -} - -input[type=number]::-webkit-inner-spin-button, -input[type=number]::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; -} - -[class|="ol-button"] { - align-items: center; - background-repeat: no-repeat; - display: flex; - font-weight: normal; - padding: 8px 10px; - white-space: nowrap; -} - -[class|="ol-button"]::before { - margin-right: 8px; -} - -.ol-button-close { - background: transparent; - border: 1px solid white; -} - -.ol-button-close::before { - content: "\d7"; -} - -.ol-button-apply { - background: transparent; - border: 1px solid white; -} - -.ol-button-apply::before { - content: "\2713"; -} - -.ol-button-settings { - background-color: var(--background-slate-blue); -} - -.ol-button-settings::before { - background-image: url("/images/icons/gears-solid.svg"); - background-position: 0 50%; - background-size: 24px 24px; - content: ""; - display: flex; - filter: invert(100%); - height: 24px; - width: 24px; +#info-popup { + position: absolute; + width: fit-content; + height: fit-content; + top: 100px; + left: 50%; + translate: -50% 0%; + z-index: 9999; } \ No newline at end of file diff --git a/client/public/stylesheets/markers/airbase.css b/client/public/stylesheets/markers/airbase.css index fac5497b..a9640cf3 100644 --- a/client/public/stylesheets/markers/airbase.css +++ b/client/public/stylesheets/markers/airbase.css @@ -1,9 +1,4 @@ -:root { - --airbase-marker-height: 40px; - --airbase-marker-width: 40px; -} - -[data-object|="airbase"] { +.airbase-icon { align-items: center; cursor: pointer; display: flex; @@ -11,35 +6,15 @@ position: relative; } -[data-hide-airbase] #map-container [data-object|="airbase"] { - display: none; +.airbase-icon[data-coalition="red"] svg * { + stroke: var(--unit-background-red); } -/****************************** -Marker -******************************/ - -[data-object|="airbase"] .airbase { - background-color: transparent; - background-repeat: no-repeat; - background-size: cover; - position: absolute; - transform-origin: center; - z-index: 3; +.airbase-icon[data-coalition="blue"] svg * { + stroke: var(--unit-background-blue); } -/* Airbase */ -[data-object|="airbase"] .airbase-marker { - background-image: var(--airbase-marker-neutral-url); - background-size: contain; - height: var(--airbase-marker-height); - width: var(--airbase-marker-width); +.airbase-icon[data-coalition="neutral"] svg * { + stroke: var(--unit-background-neutral); } -[data-object|="airbase"][data-coalition="red"] .airbase-marker { - background-image: var(--airbase-marker-red-url); -} - -[data-object|="airbase"][data-coalition="blue"] .airbase-marker { - background-image: var(--airbase-marker-blue-url); -} \ No newline at end of file diff --git a/client/public/stylesheets/markers/bullseye.css b/client/public/stylesheets/markers/bullseye.css new file mode 100644 index 00000000..81663b09 --- /dev/null +++ b/client/public/stylesheets/markers/bullseye.css @@ -0,0 +1,22 @@ +.bullseye-icon { + align-items: center; + cursor: pointer; + display: flex; + justify-content: center; + position: relative; +} + +.bullseye-icon[data-coalition="red"] svg * { + stroke: var(--unit-background-red); + fill: var(--unit-background-red); +} + +.bullseye-icon[data-coalition="blue"] svg * { + stroke: var(--unit-background-blue); + fill: var(--unit-background-blue); +} + +.bullseye-icon[data-coalition="neutral"] svg * { + stroke: var(--unit-background-neutral); + fill: var(--unit-background-neutral); +} diff --git a/client/public/stylesheets/markers/units.css b/client/public/stylesheets/markers/units.css index 121a1059..056a92d3 100644 --- a/client/public/stylesheets/markers/units.css +++ b/client/public/stylesheets/markers/units.css @@ -9,9 +9,9 @@ align-items: center; cursor: pointer; display: flex; + height: 100%; justify-content: center; position: relative; - height: 100%; width: 100%; } @@ -20,10 +20,10 @@ background: var(--secondary-gunmetal-grey); display: flex; justify-self: center; - transform-origin: bottom; - translate: 0 -50%; padding-bottom: calc((var(--unit-aircraft-width) / 2) + var(--unit-stroke-width)); position: absolute; + transform-origin: bottom; + translate: 0 -50%; width: var(--unit-aircraft-vvi-width); } @@ -49,41 +49,41 @@ translate: -1px 1px; } -.unit-marker { +.unit-icon { + height: var(--unit-height); position: absolute; transform-origin: center; - height: var(--unit-height); width: var(--unit-width); } -[data-is-selected] .unit-marker::before { - content: ""; - height: 100%; - width: 100%; +[data-is-selected] .unit-icon::before { background-color: var(--unit-spotlight-fill); border-radius: 50%; + content: ""; + height: 100%; position: absolute; + width: 100%; z-index: -1; } /*** Basic colours ***/ -[data-coalition="blue"] .unit-marker svg>*:first-child { +[data-coalition="blue"] .unit-icon svg>*:first-child { fill: var(--unit-background-blue); } -[data-coalition="red"] .unit-marker svg>*:first-child { +[data-coalition="red"] .unit-icon svg>*:first-child { fill: var(--unit-background-red); } -[data-coalition="neutral"] .unit-marker svg>*:first-child { +[data-coalition="neutral"] .unit-icon svg>*:first-child { fill: var(--unit-background-neutral); } -[data-is-selected] .unit-marker svg>*:first-child { +[data-is-selected] .unit-icon svg>*:first-child { fill: white; } -[data-is-highlighted] .unit-marker svg>*:first-child { +[data-is-highlighted] .unit-icon svg>*:first-child { stroke: white; } @@ -140,15 +140,15 @@ /*** Unit summary ***/ [data-object|="unit"] .unit-summary { - pointer-events: none; - column-gap: 6px; color: white; + column-gap: 6px; display: flex; flex-wrap: wrap; font-size: 11px; font-weight: bold; justify-content: right; line-height: 12px; + pointer-events: none; position: absolute; row-gap: 1px; text-shadow: @@ -247,41 +247,41 @@ /*** Unit state ***/ [data-object|="unit"] .unit-state { background-repeat: no-repeat; - position: absolute; height: 20px; + position: absolute; width: 20px; } [data-object|="unit"][data-state="rtb"] .unit-state { - background-image: url("/theme/images/states/rtb.svg"); + background-image: url("/resources/theme/images/states/rtb.svg"); } [data-object|="unit"][data-state="land"] .unit-state { - background-image: url("/theme/images/states/rtb.svg"); + background-image: url("/resources/theme/images/states/rtb.svg"); } [data-object|="unit"][data-state="idle"] .unit-state { - background-image: url("/theme/images/states/idle.svg"); + background-image: url("/resources/theme/images/states/idle.svg"); } [data-object|="unit"][data-state="attack"] .unit-state { - background-image: url("/theme/images/states/attack.svg"); + background-image: url("/resources/theme/images/states/attack.svg"); } [data-object|="unit"][data-state="follow"] .unit-state { - background-image: url("/theme/images/states/follow.svg"); + background-image: url("/resources/theme/images/states/follow.svg"); } [data-object|="unit"][data-state="refuel"] .unit-state { - background-image: url("/theme/images/states/refuel.svg"); + background-image: url("/resources/theme/images/states/refuel.svg"); } [data-object|="unit"][data-state="human"] .unit-state { - background-image: url("/theme/images/states/human.svg"); + background-image: url("/resources/theme/images/states/human.svg"); } [data-object|="unit"][data-state="dcs"] .unit-state { - background-image: url("/theme/images/states/dcs.svg"); + background-image: url("/resources/theme/images/states/dcs.svg"); } /*** Dead unit ***/ diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index 413afbc1..d32ccc42 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -9,6 +9,7 @@ @import url("other/contextmenus.css"); @import url("other/popup.css"); @import url("markers/airbase.css"); +@import url("markers/bullseye.css"); @import url("markers/units.css"); * { @@ -88,8 +89,8 @@ form>div { .ol-scrollable::-webkit-scrollbar-track { background-color: transparent; - border-top-right-radius: 10px; border-bottom-right-radius: 10px; + border-top-right-radius: 10px; margin-top: 0px; } @@ -104,8 +105,8 @@ form>div { .ol-scrollable::-webkit-scrollbar-thumb { background-color: white; border-radius: 100px; - opacity: 0.8; margin-top: 10px; + opacity: 0.8; } .ol-panel { @@ -137,15 +138,15 @@ form>div { .ol-ellipsed { display: inline-block; - width: calc(100%); overflow: hidden; - text-overflow: ellipsis; text-align: left; + text-overflow: ellipsis; + width: calc(100%); } .ol-select { - position: relative; color: var(--nav-text); + position: relative; } .ol-select>.ol-select-value { @@ -154,10 +155,10 @@ form>div { cursor: pointer; display: flex; justify-content: left; + min-width: 0; text-align: center; white-space: nowrap; width: 100%; - min-width: 0; } .ol-select:not(.ol-select-image)>.ol-select-value { @@ -165,12 +166,12 @@ form>div { background-color: var(--background-grey); border-radius: var(--border-radius-sm); height: 32px; - padding-right: 30px; - padding-left: 20px; - - width: calc(100%); overflow: hidden; + padding-left: 20px; + padding-right: 30px; text-overflow: ellipsis; + + width: calc(100%); } .ol-select.narrow:not(.ol-select-image)>.ol-select-value { @@ -183,22 +184,22 @@ form>div { } .ol-select:not(.ol-select-image)>.ol-select-value:after { + content: url("/resources/theme/images/icons/chevron-down.svg"); position: absolute; - content: url("/themes/olympus/images/chevron-down.svg"); right: 10px; } .ol-select>.ol-select-options { border-radius: var(--border-radius-md); + max-height: 0; overflow: hidden; position: absolute; - max-height: 0; z-index: 1000; } .ol-select-options.scrollbar-visible { - border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; + border-top-right-radius: 0px !important; } .ol-select.ol-select-image>.ol-select-options { @@ -207,11 +208,11 @@ form>div { .ol-select.is-open>.ol-select-options { max-height: 382px; + min-width: 100%; overflow: visible; overflow-y: auto; - min-width: 100%; - z-index: 9999; translate: 0px 5px; + z-index: 9999; } .ol-select.is-open[data-position="top"]>.ol-select-options { @@ -247,16 +248,16 @@ form>div { background-color: transparent; border: none; border-radius: 0; + border-radius: var(--border-radius-sm); color: white; display: block; font-size: 12px; font-weight: normal; padding: 6px 2px; + padding: 5px; text-align: left; white-space: nowrap; width: 100%; - padding: 5px; - border-radius: var(--border-radius-sm); } .ol-select>.ol-select-options>div a:hover, @@ -368,13 +369,13 @@ nav.ol-panel> :last-child { } .ol-panel .ol-group { + align-items: center; border-radius: var(--border-radius-sm); column-gap: 10px; display: flex; flex-direction: row; flex-wrap: nowrap; row-gap: 4px; - align-items: center; } .ol-group-header { @@ -405,7 +406,7 @@ nav.ol-panel> :last-child { } .ol-panel .ol-group-button-toggle button::before { - background-image: url("/images/icons/square-check-solid.svg"); + background-image: url("/resources/theme/images/icons/square-check-solid.svg"); background-repeat: no-repeat; content: ""; filter: invert(100%); @@ -415,7 +416,7 @@ nav.ol-panel> :last-child { } .ol-panel .ol-group-button-toggle button.off::before { - background-image: url("/images/icons/square-regular.svg"); + background-image: url("/resources/theme/images/icons/square-regular.svg"); } .highlight-primary { @@ -470,9 +471,9 @@ nav.ol-panel> :last-child { } .icon-small { - width: 20px; - padding: 2px; filter: invert(100%); + padding: 2px; + width: 20px; } .ol-data-grid { @@ -485,17 +486,17 @@ nav.ol-panel> :last-child { } .slider { - width: 100%; -webkit-appearance: none; appearance: none; - height: 2px; background: #d3d3d3; - outline: none; + height: 2px; + margin-bottom: 10px; + margin-top: 10px; opacity: 0.7; + outline: none; -webkit-transition: .2s; transition: opacity .2s; - margin-top: 10px; - margin-bottom: 10px; + width: 100%; } .slider:hover { @@ -505,11 +506,11 @@ nav.ol-panel> :last-child { .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; - width: 20px; - height: 20px; background: gray; - cursor: pointer; border-radius: 999px; + cursor: pointer; + height: 20px; + width: 20px; } .active .slider::-webkit-slider-thumb { @@ -517,11 +518,11 @@ nav.ol-panel> :last-child { } .slider::-moz-range-thumb { - width: 20px; - height: 20px; background: gray; - cursor: pointer; border-radius: 999px; + cursor: pointer; + height: 20px; + width: 20px; } .active .slider::-moz-range-thumb { @@ -529,25 +530,25 @@ nav.ol-panel> :last-child { } .main-logo { - width: 40px; height: 40px; + width: 40px; } .ol-measure-box { - position: absolute; + background-color: var(--background-steel); + border-radius: 999px; + color: var(--primary-neutral); + font-size: 12px; + font-weight: var(--font-weight-bolder); + height: fit-content; + padding-bottom: 0.2em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.2em; - padding-bottom: 0.2em; - background-color: var(--background-steel); - border-radius: 999px; - width: fit-content; - height: fit-content; + position: absolute; text-align: center; - color: var(--primary-neutral); - font-size: 12px; + width: fit-content; z-index: 2000; - font-weight: var(--font-weight-bolder); } .ol-sortable .handle { @@ -575,7 +576,7 @@ nav.ol-panel> :last-child { width: 28px; } -#unit-selection #unit-identification [data-object|="unit"] .unit-marker { +#unit-selection #unit-identification [data-object|="unit"] .unit-icon { background-size: 28px 28px; height: 28px; width: 28px; @@ -588,13 +589,13 @@ nav.ol-panel> :last-child { #unit-visibility-control button { border: none; height: 32px; - width: 32px; padding: 0px; + width: 32px; } #unit-visibility-control button svg { - pointer-events: none; height: 16px; + pointer-events: none; width: 16px; } @@ -633,31 +634,27 @@ nav.ol-panel> :last-child { #roe-buttons-container button, #reaction-to-threat-buttons-container button, #emissions-countermeasures-buttons-container button { - display: flex; + align-items: center; background-color: transparent; border: 1px solid var(--accent-light-blue); + display: flex; height: 30px; - width: 30px; - align-items: center; justify-content: center; + width: 30px; } -#roe-buttons-container button.selected, -#reaction-to-threat-buttons-container button.selected, -#emissions-countermeasures-buttons-container button.selected { +#unit-control-panel .ol-option-button button.selected { background-color: white; border-color: white; } -#roe-buttons-container button.selected svg .foreground, -#reaction-to-threat-buttons-container button.selected svg .foreground, -#emissions-countermeasures-buttons-container button.selected svg .foreground { +#unit-control-panel .ol-option-button button.selected svg * { fill: var(--background-steel); } /****************************************************************************************/ #splash-screen { - background-image: url("/images/splash/splash_pic_ship.png"); + background-image: url("/resources/theme/images/splash/1.png"); background-position: 100% 50%; background-size: 60%; border-radius: var(--border-radius-lg); @@ -707,9 +704,9 @@ nav.ol-panel> :last-child { #splash-content #app-summary>* { height: fit-content; line-height: 25px; + padding: 2px; white-space: nowrap; width: fit-content; - padding: 2px; } #splash-content .app-version { @@ -721,8 +718,8 @@ nav.ol-panel> :last-child { } #splash-content #legal-stuff p { + color: #FFF7; font-size: 10px; - color:#FFF7; width: 120%; } @@ -735,34 +732,34 @@ nav.ol-panel> :last-child { } #gray-out { - position: fixed; - height: 100%; - width: 100%; - left: 0px; - top: 0px; - z-index: 9999; background-color: #000A; + height: 100%; + left: 0px; + position: fixed; + top: 0px; + width: 100%; + z-index: 9999; } #authentication-form { - display: flex; align-items: end; column-gap: 10px; - margin: 10px 0px; + display: flex; flex-direction: row; + margin: 10px 0px; } #authentication-form>div { - display: flex; align-items: start; - row-gap: 4px; + display: flex; flex-direction: column; + row-gap: 4px; } #authentication-form>div>input { - height: 35px; - border-radius: var(--border-radius-sm); border: 0px solid transparent; + border-radius: var(--border-radius-sm); + height: 35px; width: 200px; } @@ -776,13 +773,13 @@ nav.ol-panel> :last-child { } #connection-status[data-status="connecting"]::before { - content: "Connecting..."; animation: blinker 1s linear infinite; + content: "Connecting..."; } #connection-status[data-status="failed"]::before { - content: "Incorrect username/password!"; color: var(--primary-red); + content: "Incorrect username/password!"; } @keyframes blinker { @@ -792,31 +789,31 @@ nav.ol-panel> :last-child { } #hotgroup-panel { - position: absolute; bottom: 40px; + column-gap: 10px; + display: flex; left: 50%; + position: absolute; translate: -50%; z-index: 9999; - display: flex; - column-gap: 10px; } #hotgroup-panel>div { - width: 50px; - height: 50px; + align-items: center; background-color: var(--background-steel); + border: 0px solid transparent; border-radius: var(--border-radius-sm); color: white; display: flex; - align-items: center; - justify-content: center; font-weight: bold; - border: 0px solid transparent; + height: 50px; + justify-content: center; + width: 50px; } #hotgroup-panel>div:hover { - cursor: pointer; border: 2px solid white; + cursor: pointer; } .hotgroup-selector>.unit-hotgroup { @@ -825,13 +822,230 @@ nav.ol-panel> :last-child { } .ol-destination-preview-icon { - width: 52px; - height: 52px; background-color: var(--secondary-yellow); - pointer-events: none; border-radius: 999px; + height: 52px; + pointer-events: none; + width: 52px; } .ol-destination-preview { pointer-events: none; +} + +dl.ol-data-grid { + align-items: center; + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: 0; + row-gap: 4px; +} + +dl.ol-data-grid dt { + width: 60%; +} + +dl.ol-data-grid dd { + width: 40%; +} + +dl.ol-data-grid dt.icon { + text-indent: 10px; +} + +dl.ol-data-grid dt.icon::before { + content: url("/resources/theme/images/icons/speed.svg"); + display: inline-block; + filter: invert(100%); + translate: -20px 2px; + width: 20px; +} + +dl.ol-data-grid dt.icon-speed::before { + content: url("/images/icons/speed.svg"); +} + +dl.ol-data-grid dt.icon-altitude::before { + content: url("/images/icons/altitude.svg"); +} + +dl.ol-data-grid dd { + display: flex; + justify-content: flex-end; + margin-left: auto; +} + +.br-info::after { + content: attr(data-bearing) '\00B0 / ' attr(data-distance) attr(data-distance-units); +} + +.br-info[data-message]::after { + content: attr(data-message); +} + +.coordinates::after { + content: attr(data-dd) "\00b0 " attr(data-mm) "'" attr(data-ss) "." attr(data-sss) '"' attr(data-label); +} + +.ol-button-box { + column-gap: 6px; + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: 5px 0; + row-gap: 5px; +} + +.ol-button-box button { + background-repeat: no-repeat; + ; + border: 1px solid var(--accent-light-blue); + color: var(--accent-light-blue); +} + +.ol-dialog { + align-self: center; + background-color: var(--background-slate-blue); + color: white; + justify-self: center; + position: absolute; + z-index: 1000; +} + +.ol-panel.ol-dialog { + padding: 24px 30px; +} + +.ol-dialog-close { + cursor: pointer; + font-size: 16px; + font-weight: var(--font-weight-bolder); + position: absolute; + right: 20px; + top: 10px; +} + +.ol-dialog-close::before { + content: "\d7"; +} + +.ol-dialog-header { + border-bottom: 1px solid var(--background-grey); + padding-bottom: 10px; +} + +.ol-dialog-content { + margin: 4px 0; +} + +.ol-dialog-footer { + border-top: 1px solid var(--background-grey); + display: flex; + padding-top: 15px; + row-gap: 10px; +} + +.ol-dialog.scrollable .ol-dialog-content { + overflow-y: auto; +} + +.ol-checkbox label { + align-items: center; + cursor: pointer; + display: flex; + flex-wrap: nowrap; + white-space: nowrap; +} + +.ol-checkbox input[type="checkbox"] { + appearance: none; + background-color: transparent; + border: none; + margin: 0; +} + +.ol-checkbox input[type="checkbox"]::before { + align-self: center; + background-image: url("/resources/theme/images/icons/square-regular.svg"); + background-repeat: no-repeat; + content: ""; + display: flex; + filter: invert(100%); + height: 16px; + margin-right: 10px; + width: 16px; +} + +.ol-checkbox input[type="checkbox"]:checked::before { + background-image: url("/resources/theme/images/icons/square-check-solid.svg"); +} + +.ol-text-input input { + background-color: var(--background-grey); + border: 1px solid var(--background-grey); + border-radius: 5px; + border-radius: var(--border-radius-sm); + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + color: var(--background-offwhite); + height: 32px; + text-align: center; +} + +input[type=number] { + -moz-appearance: textfield; + appearance: textfield; + margin: 0; +} + +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +[class|="ol-button"] { + align-items: center; + background-repeat: no-repeat; + display: flex; + font-weight: normal; + padding: 8px 10px; + white-space: nowrap; +} + +[class|="ol-button"]::before { + margin-right: 8px; +} + +.ol-button-close { + background: transparent; + border: 1px solid white; +} + +.ol-button-close::before { + content: "\d7"; +} + +.ol-button-apply { + background: transparent; + border: 1px solid white; +} + +.ol-button-apply::before { + content: "\2713"; +} + +.ol-button-settings { + background-color: var(--background-slate-blue); +} + +.ol-button-settings::before { + background-image: url("/resources/theme/images/icons/gears-solid.svg"); + background-position: 0 50%; + background-size: 24px 24px; + content: ""; + display: flex; + filter: invert(100%); + height: 24px; + width: 24px; } \ No newline at end of file diff --git a/client/public/stylesheets/other/contextmenus.css b/client/public/stylesheets/other/contextmenus.css index 573bba4b..361a6a0b 100644 --- a/client/public/stylesheets/other/contextmenus.css +++ b/client/public/stylesheets/other/contextmenus.css @@ -17,23 +17,23 @@ } #active-coalition-label { - position: absolute; - top: -28px; border-radius: 999px; - width: fit-content; + color: var(--nav-text); + font-size: 12px; + font-weight: 600; height: fit-content; padding: 3px 10px; padding-bottom: 3px; - font-weight: 600; - color: var(--nav-text); - font-size: 12px; + position: absolute; + top: -28px; + width: fit-content; } #context-menu-switch { margin-right: 10px; } -#map-contextmenu>div:nth-child(2){ +#map-contextmenu>div:nth-child(2) { align-items: center; display: flex; flex-direction: row; @@ -41,22 +41,22 @@ padding-right: 0px; } -#map-contextmenu>ul{ +#map-contextmenu>ul { max-height: 200px; overflow-x: hidden; overflow-y: auto; } #map-contextmenu .ol-panel { - width: 100%; border-radius: var(--border-radius-sm); + width: 100%; } #map-contextmenu ul { margin: 0px; } -#map-contextmenu>div:nth-child(n+3){ +#map-contextmenu>div:nth-child(n+3) { align-items: center; display: flex; flex-direction: column; @@ -64,10 +64,10 @@ row-gap: 5px; } -#map-contextmenu .ol-select-container{ - width: 100%; - flex:0 0 auto; +#map-contextmenu .ol-select-container { align-self: stretch; + flex: 0 0 auto; + width: 100%; } #aircraft-spawn-menu .ol-select.is-open .ol-select-options { @@ -76,28 +76,28 @@ #aircraft-spawn-menu>button, #ground-unit-spawn-menu>button { - width: 100%; text-align: center; + width: 100%; } #aircraft-spawn-button { - background-image: var( --spawn-aircraft-url ); + background-image: url("/resources/theme/images/buttons/spawn/aircraft.svg"); background-size: 48px; } #ground-unit-spawn-button { - background-image: var( --spawn-groundunit-url ); + background-image: url("/resources/theme/images/buttons/spawn/ground.svg"); background-size: 48px; } #smoke-spawn-button { - background-image: var( --spawn-smoke-url ); + background-image: url("/resources/theme/images/buttons/spawn/smoke.svg"); background-size: 48px; } .unit-spawn-button { - border-radius: 0px; border: none; + border-radius: 0px; height: 48px; margin-bottom: -10px; margin-top: -10px; @@ -105,37 +105,34 @@ } .unit-spawn-button:last-of-type { - border-top-right-radius: var(--border-radius-sm); border-bottom-right-radius: var(--border-radius-sm); + border-top-right-radius: var(--border-radius-sm); } [data-active-coalition="blue"].toggle-fill, -[data-active-coalition="blue"].unit-spawn-button:hover, -[data-active-coalition="blue"].unit-spawn-button.is-open, +[data-active-coalition="blue"].unit-spawn-button:hover, +[data-active-coalition="blue"].unit-spawn-button.is-open, [data-active-coalition="blue"]#active-coalition-label, [data-active-coalition="blue"].deploy-unit-button, -[data-active-coalition="blue"]#spawn-airbase-aircraft-button -{ +[data-active-coalition="blue"]#spawn-airbase-aircraft-button { background-color: var(--primary-blue) } [data-active-coalition="red"].toggle-fill, -[data-active-coalition="red"].unit-spawn-button:hover, -[data-active-coalition="red"].unit-spawn-button.is-open, +[data-active-coalition="red"].unit-spawn-button:hover, +[data-active-coalition="red"].unit-spawn-button.is-open, [data-active-coalition="red"]#active-coalition-label, [data-active-coalition="red"].deploy-unit-button, -[data-active-coalition="red"]#spawn-airbase-aircraft-button -{ +[data-active-coalition="red"]#spawn-airbase-aircraft-button { background-color: var(--primary-red) } [data-active-coalition="neutral"].toggle-fill, -[data-active-coalition="neutral"].unit-spawn-button:hover, -[data-active-coalition="neutral"].unit-spawn-button.is-open, +[data-active-coalition="neutral"].unit-spawn-button:hover, +[data-active-coalition="neutral"].unit-spawn-button.is-open, [data-active-coalition="neutral"]#active-coalition-label, [data-active-coalition="neutral"].deploy-unit-button, -[data-active-coalition="neutral"]#spawn-airbase-aircraft-button -{ +[data-active-coalition="neutral"]#spawn-airbase-aircraft-button { background-color: var(--primary-neutral) } @@ -144,11 +141,13 @@ border: 1px solid var(--primary-blue); cursor: default; } + [data-active-coalition="red"].deploy-unit-button:disabled { background-color: transparent; border: 1px solid var(--primary-red); cursor: default; } + [data-active-coalition="neutral"].deploy-unit-button:disabled { background-color: transparent; border: 1px solid var(--primary-neutral); @@ -158,9 +157,11 @@ [data-active-coalition="blue"].toggle-fill::after { transform: translateX(0); } + [data-active-coalition="red"].toggle-fill::after { transform: translateX(var(--height)); } + [data-active-coalition="neutral"].toggle-fill::after { transform: translateX(calc(var(--height) / 2)); } @@ -168,182 +169,198 @@ [data-active-coalition="blue"]#active-coalition-label::after { content: "Create blue unit"; } + [data-active-coalition="red"]#active-coalition-label::after { content: "Create red unit"; } + [data-active-coalition="neutral"]#active-coalition-label::after { content: "Create neutral unit"; } #loadout-preview { - display: flex; - flex-direction: row; align-content: space-between; align-items: center; - width: 100%; column-gap: 20px; + display: flex; + flex-direction: row; + width: 100%; } #loadout-list { + align-content: center; display: flex; flex-direction: column; - align-content: center; height: 100%; } #unit-image { - width: 100px; - height: 100px; filter: invert(100%); - margin-top: 10px; + height: 100px; margin-bottom: 10px; + margin-top: 10px; + width: 100px; } #smoke-spawn-menu { + align-items: center; display: flex; flex-direction: column; - align-items: center; text-align: center; } #smoke-spawn-menu>button { - width: 100%; - text-align: left; - display: flex; - flex-wrap: wrap; align-items: center; column-gap: 10px; + display: flex; + flex-wrap: wrap; + text-align: left; + width: 100%; } #smoke-spawn-menu>button::before { - display: block; - width: 10px; - height: 10px; border-radius: 999px; content: ""; + display: block; + height: 10px; + width: 10px; } -[data-smoke-color="red"]::before{ background-color: red; } -[data-smoke-color="white"]::before{ background-color: white; } -[data-smoke-color="blue"]::before{ background-color: blue; } -[data-smoke-color="green"]::before{ background-color: green; } -[data-smoke-color="orange"]::before{ background-color: orange; } +[data-smoke-color="red"]::before { + background-color: red; +} + +[data-smoke-color="white"]::before { + background-color: white; +} + +[data-smoke-color="blue"]::before { + background-color: blue; +} + +[data-smoke-color="green"]::before { + background-color: green; +} + +[data-smoke-color="orange"]::before { + background-color: orange; +} /* Unit context menu */ #unit-contextmenu { display: flex; flex-direction: column; height: fit-content; - width: fit-content; + padding: 15px; position: absolute; row-gap: 5px; + width: fit-content; z-index: 1000; - padding: 15px; } #unit-contextmenu button { border: 1px solid var(--background-offwhite); border-radius: var(--border-radius-sm); - padding: 12px; font-weight: normal; + padding: 12px; } #unit-contextmenu div { + align-content: center; display: flex; flex-direction: row; - align-content: center; } #unit-contextmenu div:before { - display: inline-block; - filter: invert(100%); - height: 16px; - margin-right: 15px; - width: 16px; + display: inline-block; + filter: invert(100%); + height: 16px; + margin-right: 15px; + width: 16px; } #center-map::before { - content: url( /images/icons/arrows-to-eye-solid.svg ); + content: url("/resources/theme/images/icons/arrows-to-eye-solid.svg"); } #refuel::before { - content: url( /images/icons/fuel.svg ); + content: url("/resources/theme/images/icons/fuel.svg"); } #attack::before { - content: url( /images/icons/sword.svg ); + content: url("/resources/theme/images/icons/sword.svg"); } #follow::before { - content: url( /images/icons/follow.svg ); + content: url("/resources/theme/images/icons/follow.svg"); } #trail::before { - content: url( /images/icons/trail.svg ); + content: url("/resources/theme/images/icons/trail.svg"); } #echelon-lh::before { - content: url( /images/icons/echelon-lh.svg ); + content: url("/resources/theme/images/icons/echelon-lh.svg"); } #echelon-rh::before { - content: url( /images/icons/echelon-rh.svg ); + content: url("/resources/theme/images/icons/echelon-rh.svg"); } #line-abreast::before { - content: url( /images/icons/line-abreast.svg ); + content: url("/resources/theme/images/icons/line-abreast.svg"); } #front::before { - content: url( /images/icons/front.svg ); + content: url("/resources/theme/images/icons/front.svg"); } #custom::before { - content: url( /images/icons/custom.svg ); + content: url("/resources/theme/images/icons/custom.svg"); } #custom-formation-dialog { - width: 250px; + width: 250px; } -#custom-formation-dialog > .ol-dialog-content { - margin-top: 10px; - margin-bottom: 10px; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - row-gap: 10px; +#custom-formation-dialog>.ol-dialog-content { align-items: center; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + margin-bottom: 10px; + margin-top: 10px; + row-gap: 10px; } -#custom-formation-dialog > .ol-dialog-content > .ol-group { +#custom-formation-dialog>.ol-dialog-content>.ol-group { + justify-content: space-between; width: 100%; - justify-content: space-between; } #reference-system { - content: url( /images/reference-system.svg ); + content: url("/images/reference-system.svg"); display: inline-block; - filter: invert(100%); - width: 50px; - transform: translate(-50%, -50%); + filter: invert(100%); position: absolute; + transform: translate(-50%, -50%); + width: 50px; } .formation-position-clock { - position: relative; height: 100px; - width: 100px; margin: 15px; + position: relative; + width: 100px; } -.formation-position-clock > .clock-hand { - transform: translate(-50%, -50%); - display: flex; - position: absolute; - align-items: center; - justify-content: center; - height: 20px; +.formation-position-clock>.clock-hand { + align-items: center; + display: flex; + height: 20px; + justify-content: center; + position: absolute; + transform: translate(-50%, -50%); width: 20px; } @@ -362,9 +379,9 @@ --width: 40px; --height: calc(var(--width) / 2); --border-radius: calc(var(--height) / 2); + cursor: pointer; display: inline-block; - cursor: pointer; } .toggle-input { @@ -372,23 +389,22 @@ } .toggle-fill { - position: relative; - width: var(--width); - height: var(--height); border-radius: var(--border-radius); + height: var(--height); + position: relative; transition: background-color 0.2s; + width: var(--width); } .toggle-fill::after { + background-color: #ffffff; + border-radius: var(--border-radius); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.25); content: ""; + height: calc(var(--height) - 4px); + left: 2; position: absolute; top: 2; - left: 2; - height: calc(var(--height) - 4px); - width: calc(var(--height) - 4px); - background-color: #ffffff; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.25); - border-radius: var(--border-radius); transition: transform 0.2s; -} - + width: calc(var(--height) - 4px); +} \ No newline at end of file diff --git a/client/public/stylesheets/other/popup.css b/client/public/stylesheets/other/popup.css index fb514460..521e4cde 100644 --- a/client/public/stylesheets/other/popup.css +++ b/client/public/stylesheets/other/popup.css @@ -1,13 +1,3 @@ -#info-popup { - position: absolute; - width: fit-content; - height: fit-content; - top: 100px; - left: 50%; - translate: -50% 0%; - z-index: 9999; -} - .ol-popup > div { padding-left: 15px; padding-right: 15px; diff --git a/client/public/stylesheets/panels/connectionstatus.css b/client/public/stylesheets/panels/connectionstatus.css index 362657cf..2b7dcec4 100644 --- a/client/public/stylesheets/panels/connectionstatus.css +++ b/client/public/stylesheets/panels/connectionstatus.css @@ -1,12 +1,3 @@ -#connection-status-panel { - bottom: 20px; - font-size:12px; - position: absolute; - right: 10px; - width: 160px; - z-index: 1000; -} - #connection-status-panel dt::before { content: "No connection"; } @@ -15,15 +6,14 @@ border-radius: 50%; background: red; content: " "; - height:12px; - width:12px; + height: 12px; + width: 12px; } - #connection-status-panel[data-is-connected] dt::before { content: "Connected"; } #connection-status-panel[data-is-connected] dd::after { - background:var( --accent-green ); + background: var(--accent-green); } \ No newline at end of file diff --git a/client/public/stylesheets/panels/mouseinfo.css b/client/public/stylesheets/panels/mouseinfo.css index fe8030a3..cfbb70c6 100644 --- a/client/public/stylesheets/panels/mouseinfo.css +++ b/client/public/stylesheets/panels/mouseinfo.css @@ -1,91 +1,75 @@ -#mouse-info-panel { - bottom: 60px; - display:flex; - flex-direction: column; - height: fit-content; - position: absolute; - right: 10px; - row-gap: 10px; - width: 160px; - z-index: 1000; +#mouse-info-panel>* { + background-color: var(--background-grey); + border-radius: var(--border-radius-sm); + padding: 6px; } - -#mouse-info-panel > * { - background-color: var( --background-grey ); - border-radius: var( --border-radius-sm ); - padding:6px; -} - - #mouse-info-panel dl { - margin-bottom:4px; + margin-bottom: 4px; row-gap: 8px; } #mouse-info-panel dt { - height:20px; - width:30%; + height: 20px; + width: 30%; } #mouse-info-panel dt::after { align-items: center; background-color: white; - border-radius: var( --border-radius-sm ); - color: var( --background-steel ); - display:flex; - font-size:15.6px; + border-radius: var(--border-radius-sm); + color: var(--background-steel); + display: flex; + font-size: 15.6px; font-weight: bolder; - height:16px; + height: 16px; justify-content: center; line-height: 16px; - padding:4px; + padding: 4px; text-transform: uppercase; - width:16px; + width: 16px; } #mouse-info-panel dt#ref-unit-position::after { - background-image: url( "/images/icons/ruler.svg" ); + background-image: url("/resources/theme/images/icons/ruler.svg"); background-position: 50% 50%; background-repeat: no-repeat; - background-size:16px 16px; + background-size: 16px 16px; content: ""; } #mouse-info-panel dt#ref-measure-position::after { - background-image: url( "/images/pin.png" ); + background-image: url("/resources/theme/images/pin.png"); background-position: 50% 50%; background-repeat: no-repeat; - background-size:16px 16px; + background-size: 16px 16px; content: ""; } - #mouse-info-panel dt[data-label]::after { - content: attr( data-label ); + content: attr(data-label); } #mouse-info-panel dt[data-coalition="blue"]::after { - background-color: var( --primary-blue ); + background-color: var(--primary-blue); } #mouse-info-panel dt[data-coalition="red"]::after { - background-color: var( --primary-red ); + background-color: var(--primary-red); } - #mouse-info-panel dt[data-tooltip]:hover::before { - background-color: var( --background-grey ); + background-color: var(--background-grey); border-radius: 5px; - content: attr( data-tooltip ); - display:flex; + content: attr(data-tooltip); + display: flex; flex-wrap: nowrap; padding: 5px; position: absolute; - translate: calc( -100% - 15px ) 0; + translate: calc(-100% - 15px) 0; white-space: nowrap; } #mouse-info-panel dd { - width:70%; + width: 70%; } \ No newline at end of file diff --git a/client/public/stylesheets/panels/unitcontrol.css b/client/public/stylesheets/panels/unitcontrol.css index cb314504..521ec15f 100644 --- a/client/public/stylesheets/panels/unitcontrol.css +++ b/client/public/stylesheets/panels/unitcontrol.css @@ -2,16 +2,6 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { display: block !important; } - -#unit-control-panel { - height: fit-content; - left: 10px; - position: absolute; - top: 80px; - width: 240px; - z-index: 1000; -} - #unit-control-panel h3 { margin-bottom: 8px; } @@ -33,31 +23,31 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { display: flex; font-size: 11px; height: 32px; + margin-right: 5px; padding: 8px 0; position: relative; width: calc(100% - 5px); - margin-right: 5px; } #unit-control-panel #selected-units-container button::before { - background-color: var( --primary-neutral ); + background-color: var(--primary-neutral); border-radius: 999px; content: attr(data-short-label); + font-size: 10px; margin: 2px 4px; + max-width: 30px; + min-width: 20px; + overflow: hidden; padding: 4px 6px; + text-overflow: ellipsis; white-space: nowrap; width: fit-content; - min-width: 20px; - max-width: 30px; - text-overflow: ellipsis; - overflow: hidden; - font-size: 10px; } #unit-control-panel #selected-units-container button:hover::before { + background-color: black; max-width: 100%; text-overflow: unset; - background-color: black; } #unit-control-panel #selected-units-container button[data-coalition="blue"]::before { @@ -120,13 +110,12 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { display: none; } - #advanced-settings-dialog>.ol-dialog-content { - margin-top: 10px; - margin-bottom: 10px; display: flex; flex-direction: column; flex-wrap: nowrap; + margin-bottom: 10px; + margin-top: 10px; row-gap: 10px; } @@ -146,8 +135,8 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { } #advanced-settings-dialog hr { - margin-top: 15px; margin-bottom: 10px; + margin-top: 15px; } #general-settings-grid { diff --git a/client/public/stylesheets/panels/unitinfo.css b/client/public/stylesheets/panels/unitinfo.css index 1fa1e3ee..8e20e07d 100644 --- a/client/public/stylesheets/panels/unitinfo.css +++ b/client/public/stylesheets/panels/unitinfo.css @@ -1,119 +1,106 @@ - -#unit-info-panel { - bottom: 20px; - font-size:12px; - position: absolute; - left: 10px; - width: fit-content; - z-index: 1000; -} - - #unit-info-panel #unit-name { - padding:0px 0; - margin-bottom:4px; + padding: 0px 0; + margin-bottom: 4px; } #unit-info-panel #current-task { - border-radius: var( --border-radius-lg ); - margin-top:8px; - padding:6px 16px; + border-radius: var(--border-radius-lg); + margin-top: 8px; + padding: 6px 16px; } #unit-info-panel #current-task::after { - content: attr( data-current-task ); - display:block; + content: attr(data-current-task); + display: block; } - #loadout { - display:flex; + display: flex; overflow: visible; } #loadout-silhouette { align-items: center; - display:flex; + display: flex; justify-content: center; - width:100px; + width: 100px; } #loadout-silhouette::before { - background-image: var( --loadout-background-image ); + background-image: var(--loadout-background-image); background-repeat: no-repeat; - background-size:75px 75px; - content:""; - display:block; - filter: invert( 100% ); - height:75px; - translate:-10px 0; - width:75px; + background-size: 75px 75px; + content: ""; + display: block; + filter: invert(100%); + height: 75px; + translate: -10px 0; + width: 75px; } #loadout-items { align-self: center; - display:flex; + display: flex; flex-flow: column nowrap; row-gap: 8px; } -#loadout-items > * { +#loadout-items>* { align-items: center; column-gap: 8px; - display:flex; + display: flex; justify-content: flex-end; white-space: nowrap; } -#loadout-items > *::before { +#loadout-items>*::before { align-items: center; - background-color: var( --secondary-light-grey ); - border-radius: var( --border-radius-sm ); - content: attr( data-qty ); - display:flex; - font-weight: var( --font-weight-bolder ); - padding:1px 4px; + background-color: var(--secondary-light-grey); + border-radius: var(--border-radius-sm); + content: attr(data-qty); + display: flex; + font-weight: var(--font-weight-bolder); + padding: 1px 4px; } -#loadout-items > *::after { - content: attr( data-item ); +#loadout-items>*::after { + content: attr(data-item); overflow: hidden; - position:relative; + position: relative; text-overflow: ellipsis; - width:80px; + width: 80px; } #fuel-percentage { align-items: center; - display:flex; + display: flex; } #fuel-percentage::before { - content: url( /images/icons/fuel.svg ); - display:inline-block; - filter:invert(100%); - height:16px; - margin-right:6px; - width:16px; + content: url("/resources/theme/images/icons/fuel.svg"); + display: inline-block; + filter: invert(100%); + height: 16px; + margin-right: 6px; + width: 16px; } #fuel-percentage::after { - content: attr( data-percentage ) "%"; + content: attr(data-percentage) "%"; } #fuel-display { - background-color: var( --background-grey ); - border-radius: var( --border-radius-md ); - height:6px; - margin-top:4px; + background-color: var(--background-grey); + border-radius: var(--border-radius-md); + height: 6px; + margin-top: 4px; overflow: hidden; } #fuel-display #fuel-bar { - border-radius: var( --border-radius-md ); - height:100%; -} - + border-radius: var(--border-radius-md); + height: 100%; +} \ No newline at end of file diff --git a/client/public/themes/olympus/images/actions/180.svg b/client/public/themes/olympus/images/actions/180.svg deleted file mode 100644 index 2db2cb63..00000000 --- a/client/public/themes/olympus/images/actions/180.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/client/public/themes/olympus/images/actions/cancel.svg b/client/public/themes/olympus/images/actions/cancel.svg deleted file mode 100644 index dc3335a8..00000000 --- a/client/public/themes/olympus/images/actions/cancel.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/actions/gas.svg b/client/public/themes/olympus/images/actions/gas.svg deleted file mode 100644 index 14bbef19..00000000 --- a/client/public/themes/olympus/images/actions/gas.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/actions/nothing.svg b/client/public/themes/olympus/images/actions/nothing.svg deleted file mode 100644 index 1ea95812..00000000 --- a/client/public/themes/olympus/images/actions/nothing.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/actions/rtb.svg b/client/public/themes/olympus/images/actions/rtb.svg deleted file mode 100644 index 9147bcc5..00000000 --- a/client/public/themes/olympus/images/actions/rtb.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/actions/search.svg b/client/public/themes/olympus/images/actions/search.svg deleted file mode 100644 index 2ca59cbb..00000000 --- a/client/public/themes/olympus/images/actions/search.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/buttons/emissions/attack.svg b/client/public/themes/olympus/images/buttons/emissions/attack.svg new file mode 100644 index 00000000..0846e4e6 --- /dev/null +++ b/client/public/themes/olympus/images/buttons/emissions/attack.svg @@ -0,0 +1,44 @@ + + + + + + diff --git a/client/public/themes/olympus/images/buttons/emissions/defend.svg b/client/public/themes/olympus/images/buttons/emissions/defend.svg new file mode 100644 index 00000000..5c884188 --- /dev/null +++ b/client/public/themes/olympus/images/buttons/emissions/defend.svg @@ -0,0 +1,43 @@ + + + + + + diff --git a/client/public/themes/olympus/images/buttons/emissions/free.svg b/client/public/themes/olympus/images/buttons/emissions/free.svg new file mode 100644 index 00000000..f07b2db6 --- /dev/null +++ b/client/public/themes/olympus/images/buttons/emissions/free.svg @@ -0,0 +1,43 @@ + + + + + + diff --git a/client/public/themes/olympus/images/buttons/emissions/silent.svg b/client/public/themes/olympus/images/buttons/emissions/silent.svg new file mode 100644 index 00000000..f735bc21 --- /dev/null +++ b/client/public/themes/olympus/images/buttons/emissions/silent.svg @@ -0,0 +1,43 @@ + + + + + + diff --git a/client/public/themes/olympus/images/buttons/other/spawn_aircraft.svg b/client/public/themes/olympus/images/buttons/spawn/aircraft.svg similarity index 100% rename from client/public/themes/olympus/images/buttons/other/spawn_aircraft.svg rename to client/public/themes/olympus/images/buttons/spawn/aircraft.svg diff --git a/client/public/themes/olympus/images/buttons/other/spawn_ground.svg b/client/public/themes/olympus/images/buttons/spawn/ground.svg similarity index 100% rename from client/public/themes/olympus/images/buttons/other/spawn_ground.svg rename to client/public/themes/olympus/images/buttons/spawn/ground.svg diff --git a/client/public/themes/olympus/images/buttons/other/spawn_smoke.svg b/client/public/themes/olympus/images/buttons/spawn/smoke.svg similarity index 100% rename from client/public/themes/olympus/images/buttons/other/spawn_smoke.svg rename to client/public/themes/olympus/images/buttons/spawn/smoke.svg diff --git a/client/public/themes/olympus/images/buttons/threat/evade.svg b/client/public/themes/olympus/images/buttons/threat/evade.svg index 687f852e..54d7b49f 100644 --- a/client/public/themes/olympus/images/buttons/threat/evade.svg +++ b/client/public/themes/olympus/images/buttons/threat/evade.svg @@ -45,7 +45,8 @@ stroke="#5ca7ff" stroke-linecap="round" stroke-dasharray="2, 2" - id="path4" /> + id="path4" + style="fill:none" /> + + + + + + + diff --git a/client/public/images/marker-icon.png b/client/public/themes/olympus/images/markers/marker-icon.png similarity index 100% rename from client/public/images/marker-icon.png rename to client/public/themes/olympus/images/markers/marker-icon.png diff --git a/client/public/images/marker-shadow.png b/client/public/themes/olympus/images/markers/marker-shadow.png similarity index 100% rename from client/public/images/marker-shadow.png rename to client/public/themes/olympus/images/markers/marker-shadow.png diff --git a/client/public/images/icon-temporary.png b/client/public/themes/olympus/images/markers/temporary-icon.png similarity index 100% rename from client/public/images/icon-temporary.png rename to client/public/themes/olympus/images/markers/temporary-icon.png diff --git a/client/public/themes/olympus/images/other/icons_misc_brush_blue.svg b/client/public/themes/olympus/images/other/icons_misc_brush_blue.svg deleted file mode 100644 index 7ecf9816..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_brush_blue.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_brush_dark.svg b/client/public/themes/olympus/images/other/icons_misc_brush_dark.svg deleted file mode 100644 index ed925a5a..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_brush_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_brush_light.svg b/client/public/themes/olympus/images/other/icons_misc_brush_light.svg deleted file mode 100644 index 74d2a691..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_brush_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_gas_blue.svg b/client/public/themes/olympus/images/other/icons_misc_gas_blue.svg deleted file mode 100644 index 13afd5e5..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_gas_blue.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_gas_dark.svg b/client/public/themes/olympus/images/other/icons_misc_gas_dark.svg deleted file mode 100644 index 53bb4a3f..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_gas_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_gas_light.svg b/client/public/themes/olympus/images/other/icons_misc_gas_light.svg deleted file mode 100644 index 8530905f..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_gas_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_map_blue.svg b/client/public/themes/olympus/images/other/icons_misc_map_blue.svg deleted file mode 100644 index 3e233196..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_map_blue.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_map_dark.svg b/client/public/themes/olympus/images/other/icons_misc_map_dark.svg deleted file mode 100644 index 6b9a5219..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_map_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_map_light.svg b/client/public/themes/olympus/images/other/icons_misc_map_light.svg deleted file mode 100644 index 8bec4777..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_map_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_plane_blue.svg b/client/public/themes/olympus/images/other/icons_misc_plane_blue.svg deleted file mode 100644 index 7bf3bcd8..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_plane_blue.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_plane_dark.svg b/client/public/themes/olympus/images/other/icons_misc_plane_dark.svg deleted file mode 100644 index cec512c5..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_plane_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_plane_light.svg b/client/public/themes/olympus/images/other/icons_misc_plane_light.svg deleted file mode 100644 index cf34b9c8..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_plane_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_settings_blue.svg b/client/public/themes/olympus/images/other/icons_misc_settings_blue.svg deleted file mode 100644 index 2d7004c6..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_settings_blue.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_settings_dark.svg b/client/public/themes/olympus/images/other/icons_misc_settings_dark.svg deleted file mode 100644 index 04b375e4..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_settings_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_settings_light.svg b/client/public/themes/olympus/images/other/icons_misc_settings_light.svg deleted file mode 100644 index 19270b5c..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_settings_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_visible_blue.svg b/client/public/themes/olympus/images/other/icons_misc_visible_blue.svg deleted file mode 100644 index 66f1ae9a..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_visible_blue.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_visible_dark.svg b/client/public/themes/olympus/images/other/icons_misc_visible_dark.svg deleted file mode 100644 index 0023c2c1..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_visible_dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/themes/olympus/images/other/icons_misc_visible_light.svg b/client/public/themes/olympus/images/other/icons_misc_visible_light.svg deleted file mode 100644 index 46f1b080..00000000 --- a/client/public/themes/olympus/images/other/icons_misc_visible_light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/public/images/splash/splash_pic_ship.png b/client/public/themes/olympus/images/splash/1.png similarity index 100% rename from client/public/images/splash/splash_pic_ship.png rename to client/public/themes/olympus/images/splash/1.png diff --git a/client/src/@types/server.d.ts b/client/src/@types/server.d.ts index e46d5f8a..e1a9c3e9 100644 --- a/client/src/@types/server.d.ts +++ b/client/src/@types/server.d.ts @@ -8,7 +8,7 @@ interface AirbasesData { } interface BullseyesData { - bullseyes: {[key: string]: any}, + bullseyes: {[key: string]: {latitude: number, longitude: number, coalition: string}}, } interface LogData { diff --git a/client/src/controls/airbasecontextmenu.ts b/client/src/controls/airbasecontextmenu.ts index d94f17db..bb5e7f29 100644 --- a/client/src/controls/airbasecontextmenu.ts +++ b/client/src/controls/airbasecontextmenu.ts @@ -5,8 +5,7 @@ import { ContextMenu } from "./contextmenu"; export class AirbaseContextMenu extends ContextMenu { #airbase: Airbase | null = null; - constructor(id: string) - { + constructor(id: string) { super(id); document.addEventListener("contextMenuSpawnAirbase", (e: any) => { this.showSpawnMenu(); @@ -19,8 +18,7 @@ export class AirbaseContextMenu extends ContextMenu { }) } - setAirbase(airbase: Airbase) - { + setAirbase(airbase: Airbase) { this.#airbase = airbase; this.setName(airbase.getName()); this.setProperties(airbase.getProperties()); @@ -29,24 +27,21 @@ export class AirbaseContextMenu extends ContextMenu { this.enableLandButton(getUnitsManager().getSelectedUnitsType() === "Aircraft" && (getUnitsManager().getSelectedUnitsCoalition() === airbase.getCoalition() || airbase.getCoalition() === "neutral")) } - setName(airbaseName: string) - { + setName(airbaseName: string) { var nameDiv = this.getContainer()?.querySelector("#airbase-name"); if (nameDiv != null) - nameDiv.innerText = airbaseName; + nameDiv.innerText = airbaseName; } - setProperties(airbaseProperties: string[]) - { + setProperties(airbaseProperties: string[]) { this.getContainer()?.querySelector("#airbase-properties")?.replaceChildren(...airbaseProperties.map((property: string) => { var div = document.createElement("div"); div.innerText = property; return div; - }), ); + }),); } - setParkings(airbaseParkings: string[]) - { + setParkings(airbaseParkings: string[]) { this.getContainer()?.querySelector("#airbase-parking")?.replaceChildren(...airbaseParkings.map((parking: string) => { var div = document.createElement("div"); div.innerText = parking; @@ -54,22 +49,18 @@ export class AirbaseContextMenu extends ContextMenu { })); } - setCoalition(coalition: string) - { + setCoalition(coalition: string) { (this.getContainer()?.querySelector("#spawn-airbase-aircraft-button")).dataset.activeCoalition = coalition; } - enableLandButton(enableLandButton: boolean) - { + enableLandButton(enableLandButton: boolean) { this.getContainer()?.querySelector("#land-here-button")?.classList.toggle("hide", !enableLandButton); } - showSpawnMenu() - { - if (this.#airbase != null) - { + showSpawnMenu() { + if (this.#airbase != null) { setActiveCoalition(this.#airbase.getCoalition()); - getMap().showMapContextMenu({originalEvent: {x: this.getX(), y: this.getY(), latlng: this.getLatLng()}}); + getMap().showMapContextMenu({ originalEvent: { x: this.getX(), y: this.getY(), latlng: this.getLatLng() } }); getMap().getMapContextMenu().hideUpperBar(); getMap().getMapContextMenu().showSubMenu("aircraft"); getMap().getMapContextMenu().setAirbaseName(this.#airbase.getName()); diff --git a/client/src/controls/contextmenu.ts b/client/src/controls/contextmenu.ts index 9a19562f..58cf371f 100644 --- a/client/src/controls/contextmenu.ts +++ b/client/src/controls/contextmenu.ts @@ -23,28 +23,23 @@ export class ContextMenu { this.#container?.classList.toggle("hide", true); } - getContainer() - { + getContainer() { return this.#container; } - getLatLng() - { + getLatLng() { return this.#latlng; } - getX() - { + getX() { return this.#x; } - getY() - { + getY() { return this.#y; } - clip() - { + clip() { if (this.#container != null) { if (this.#x + this.#container.offsetWidth < window.innerWidth) this.#container.style.left = this.#x + "px"; diff --git a/client/src/controls/dropdown.ts b/client/src/controls/dropdown.ts index cb96e4c0..641c405f 100644 --- a/client/src/controls/dropdown.ts +++ b/client/src/controls/dropdown.ts @@ -7,17 +7,16 @@ export class Dropdown { #optionsList: string[] = []; #index: number = 0; - constructor(ID: string, callback: CallableFunction, options: string[] | null = null) - { - this.#element = document.getElementById(ID); - this.#options = this.#element.querySelector(".ol-select-options"); - this.#value = this.#element.querySelector(".ol-select-value"); + constructor(ID: string, callback: CallableFunction, options: string[] | null = null) { + this.#element = document.getElementById(ID); + this.#options = this.#element.querySelector(".ol-select-options"); + this.#value = this.#element.querySelector(".ol-select-value"); this.#defaultValue = this.#value.innerText; - this.#callback = callback; + this.#callback = callback; if (options != null) { this.setOptions(options); - } + } this.#value.addEventListener("click", (ev) => { this.#element.classList.toggle("is-open"); @@ -31,11 +30,10 @@ export class Dropdown { } }); - this.#options.classList.add( "ol-scrollable" ); + this.#options.classList.add("ol-scrollable"); } - setOptions(optionsList: string[]) - { + setOptions(optionsList: string[]) { this.#optionsList = optionsList; this.#options.replaceChildren(...optionsList.map((option: string, idx: number) => { var div = document.createElement("div"); @@ -48,7 +46,9 @@ export class Dropdown { button.addEventListener("click", (e: MouseEvent) => { e.stopPropagation(); - this.#value.innerHTML = `

${option}
`; + this.#value = document.createElement("div"); + this.#value.classList.add("ol-ellipsed"); + this.#value.innerText = option; this.#close(); this.#callback(option, e); this.#index = idx; @@ -57,19 +57,15 @@ export class Dropdown { })); } - selectText( text:string ) { - - const index = [].slice.call( this.#options.children ).findIndex( ( opt:Element ) => opt.querySelector( "button" )?.innerText === text ); - if ( index > -1 ) { - this.selectValue( index ); + selectText(text: string) { + const index = [].slice.call(this.#options.children).findIndex((opt: Element) => opt.querySelector("button")?.innerText === text); + if (index > -1) { + this.selectValue(index); } - } - selectValue(idx: number) - { - if (idx < this.#optionsList.length) - { + selectValue(idx: number) { + if (idx < this.#optionsList.length) { var option = this.#optionsList[idx]; this.#value.innerHTML = `
${option}
`; this.#index = idx; @@ -91,8 +87,8 @@ export class Dropdown { } setValue(value: string) { - var index = this.#optionsList.findIndex((option) => {return option === value}); - if (index > -1) + var index = this.#optionsList.findIndex((option) => { return option === value }); + if (index > -1) this.selectValue(index); } @@ -102,21 +98,21 @@ export class Dropdown { #clip() { const options = this.#options; - const bounds = options.getBoundingClientRect(); - this.#element.dataset.position = ( bounds.bottom > window.innerHeight ) ? "top" : ""; + const bounds = options.getBoundingClientRect(); + this.#element.dataset.position = (bounds.bottom > window.innerHeight) ? "top" : ""; } #close() { - this.#element.classList.remove( "is-open" ); + this.#element.classList.remove("is-open"); this.#element.dataset.position = ""; } #open() { - this.#element.classList.add( "is-open" ); + this.#element.classList.add("is-open"); } #toggle() { - if ( this.#element.classList.contains( "is-open" ) ) { + if (this.#element.classList.contains("is-open")) { this.#close(); } else { this.#open(); diff --git a/client/src/controls/mapcontextmenu.ts b/client/src/controls/mapcontextmenu.ts index 929dad05..c8c98b40 100644 --- a/client/src/controls/mapcontextmenu.ts +++ b/client/src/controls/mapcontextmenu.ts @@ -41,8 +41,7 @@ export class MapContextMenu extends ContextMenu { document.addEventListener("contextMenuDeployAircraft", () => { this.hide(); this.#spawnOptions.coalition = getActiveCoalition(); - if (this.#spawnOptions) - { + if (this.#spawnOptions) { getMap().addTemporaryMarker(this.#spawnOptions.latlng); spawnAircraft(this.#spawnOptions); } @@ -51,8 +50,7 @@ export class MapContextMenu extends ContextMenu { document.addEventListener("contextMenuDeployGroundUnit", () => { this.hide(); this.#spawnOptions.coalition = getActiveCoalition(); - if (this.#spawnOptions) - { + if (this.#spawnOptions) { getMap().addTemporaryMarker(this.#spawnOptions.latlng); spawnGroundUnit(this.#spawnOptions); } @@ -189,10 +187,10 @@ export class MapContextMenu extends ContextMenu { this.#spawnOptions.role = role; this.#resetGroundUnitType(); - const types = groundUnitsDatabase.getByRole(role).map((blueprint) => { return blueprint.label } ); + const types = groundUnitsDatabase.getByRole(role).map((blueprint) => { return blueprint.label }); types.sort(); - this.#groundUnitTypeDropdown.setOptions( types ); + this.#groundUnitTypeDropdown.setOptions(types); this.#groundUnitTypeDropdown.selectValue(0); this.clip(); } @@ -205,8 +203,8 @@ export class MapContextMenu extends ContextMenu { const roles = groundUnitsDatabase.getRoles(); roles.sort(); - - this.#groundUnitRoleDropdown.setOptions( roles ); + + this.#groundUnitRoleDropdown.setOptions(roles); this.clip(); } diff --git a/client/src/controls/slider.ts b/client/src/controls/slider.ts index 7cf185cc..7fab7782 100644 --- a/client/src/controls/slider.ts +++ b/client/src/controls/slider.ts @@ -23,8 +23,7 @@ export class Slider { if (this.#container != null) { this.#display = this.#container.style.display; this.#slider = this.#container.querySelector("input"); - if (this.#slider != null) - { + if (this.#slider != null) { this.#slider.addEventListener("input", (e: any) => this.#onInput()); this.#slider.addEventListener("mousedown", (e: any) => this.#onStart()); this.#slider.addEventListener("mouseup", (e: any) => this.#onFinalize()); @@ -33,93 +32,77 @@ export class Slider { } } - show() - { + show() { if (this.#container != null) this.#container.style.display = this.#display; } - hide() - { + hide() { if (this.#container != null) this.#container.style.display = 'none'; } - setActive(newActive: boolean) - { - if (this.#container && !this.#dragged) - { + setActive(newActive: boolean) { + if (this.#container && !this.#dragged) { this.#container.classList.toggle("active", newActive); if (!newActive && this.#valueText != null) this.#valueText.innerText = "Mixed values"; } } - setMinMax(newMinValue: number, newMaxValue: number) - { + setMinMax(newMinValue: number, newMaxValue: number) { this.#minValue = newMinValue; this.#maxValue = newMaxValue; this.#updateMax(); } - setIncrement(newIncrement: number) - { + setIncrement(newIncrement: number) { this.#increment = newIncrement; this.#updateMax(); } - setValue(newValue: number) - { + setValue(newValue: number) { // Disable value setting if the user is dragging the element - if (!this.#dragged) - { + if (!this.#dragged) { this.#value = newValue; if (this.#slider != null) - this.#slider.value = String((newValue - this.#minValue) / (this.#maxValue - this.#minValue) * parseFloat(this.#slider.max)); + this.#slider.value = String((newValue - this.#minValue) / (this.#maxValue - this.#minValue) * parseFloat(this.#slider.max)); this.#onValue() } } - getValue() - { + getValue() { return this.#value; } - getDragged() - { + getDragged() { return this.#dragged; } - #updateMax() - { + #updateMax() { var oldValue = this.getValue(); if (this.#slider != null) this.#slider.max = String((this.#maxValue - this.#minValue) / this.#increment); this.setValue(oldValue); } - #onValue() - { + #onValue() { if (this.#valueText != null && this.#slider != null) - this.#valueText.innerHTML = this.#minValue + Math.round(parseFloat(this.#slider.value) / parseFloat(this.#slider.max) * (this.#maxValue - this.#minValue)) + this.#unit + this.#valueText.innerHTML = this.#minValue + Math.round(parseFloat(this.#slider.value) / parseFloat(this.#slider.max) * (this.#maxValue - this.#minValue)) + this.#unit this.setActive(true); } - #onInput() - { + #onInput() { this.#onValue(); } - #onStart() - { + #onStart() { this.#dragged = true; } - #onFinalize() - { + #onFinalize() { this.#dragged = false; - if (this.#slider != null) - { + if (this.#slider != null) { this.#value = this.#minValue + parseFloat(this.#slider.value) / parseFloat(this.#slider.max) * (this.#maxValue - this.#minValue); this.#callback(this.getValue()); } diff --git a/client/src/controls/unitcontextmenu.ts b/client/src/controls/unitcontextmenu.ts index aaa1b205..86250e6d 100644 --- a/client/src/controls/unitcontextmenu.ts +++ b/client/src/controls/unitcontextmenu.ts @@ -1,4 +1,3 @@ -import { getUnitsManager } from ".."; import { deg2rad } from "../other/utils"; import { ContextMenu } from "./contextmenu"; @@ -10,21 +9,19 @@ export class UnitContextMenu extends ContextMenu { document.addEventListener("applyCustomFormation", () => { var dialog = document.getElementById("custom-formation-dialog"); - if (dialog) - { + if (dialog) { dialog.classList.add("hide"); var clock = 1; - while (clock < 8) - { - if (( dialog.querySelector(`#formation-${clock}`)).checked) + while (clock < 8) { + if ((dialog.querySelector(`#formation-${clock}`)).checked) break clock++; } var angleDeg = 360 - (clock - 1) * 45; var angleRad = deg2rad(angleDeg); - var distance = parseInt(( dialog.querySelector(`#distance`)?.querySelector("input")).value) * 0.3048; - var upDown = parseInt(( dialog.querySelector(`#up-down`)?.querySelector("input")).value) * 0.3048; - + var distance = parseInt((dialog.querySelector(`#distance`)?.querySelector("input")).value) * 0.3048; + var upDown = parseInt((dialog.querySelector(`#up-down`)?.querySelector("input")).value) * 0.3048; + // X: front-rear, positive front // Y: top-bottom, positive top // Z: left-right, positive right @@ -34,7 +31,7 @@ export class UnitContextMenu extends ContextMenu { var z = distance * Math.sin(angleRad); if (this.#customFormationCallback) - this.#customFormationCallback({"x": x, "y": y, "z": z}) + this.#customFormationCallback({ "x": x, "y": y, "z": z }) } }) } @@ -43,10 +40,8 @@ export class UnitContextMenu extends ContextMenu { this.#customFormationCallback = callback; } - setOptions(options: {[key: string]: string}, callback: CallableFunction) - { - this.getContainer()?.replaceChildren(...Object.keys(options).map((option: string, idx: number) => - { + setOptions(options: { [key: string]: string }, callback: CallableFunction) { + this.getContainer()?.replaceChildren(...Object.keys(options).map((option: string, idx: number) => { var button = document.createElement("button"); button.innerHTML = options[option]; button.addEventListener("click", () => callback(option)); diff --git a/client/src/features/featureswitches.ts b/client/src/features/featureswitches.ts index c5776683..ee237b01 100644 --- a/client/src/features/featureswitches.ts +++ b/client/src/features/featureswitches.ts @@ -23,13 +23,13 @@ class FeatureSwitch { userPreference; - constructor( config:FeatureSwitchInterface ) { + constructor(config: FeatureSwitchInterface) { this.defaultEnabled = config.defaultEnabled; - this.label = config.label; - this.masterSwitch = config.masterSwitch; - this.name = config.name; - this.onEnabled = config.onEnabled; + this.label = config.label; + this.masterSwitch = config.masterSwitch; + this.name = config.name; + this.onEnabled = config.onEnabled; this.userPreference = this.getUserPreference(); @@ -38,16 +38,16 @@ class FeatureSwitch { getUserPreference() { - let preferences = JSON.parse( localStorage.getItem( "featureSwitches" ) || "{}" ); + let preferences = JSON.parse(localStorage.getItem("featureSwitches") || "{}"); - return ( preferences.hasOwnProperty( this.name ) ) ? preferences[ this.name ] : this.defaultEnabled; + return (preferences.hasOwnProperty(this.name)) ? preferences[this.name] : this.defaultEnabled; } isEnabled() { - if ( !this.masterSwitch ) { + if (!this.masterSwitch) { return false; } @@ -58,7 +58,7 @@ class FeatureSwitch { export class FeatureSwitches { - #featureSwitches:FeatureSwitch[] = [ + #featureSwitches: FeatureSwitch[] = [ new FeatureSwitch({ "defaultEnabled": false, @@ -66,7 +66,7 @@ export class FeatureSwitches { "masterSwitch": true, "name": "aic" }), - + new FeatureSwitch({ "defaultEnabled": false, "label": "AI Formations", @@ -74,21 +74,21 @@ export class FeatureSwitches { "name": "ai-formations", "removeArtifactsIfDisabled": false }), - + new FeatureSwitch({ "defaultEnabled": false, "label": "ATC", "masterSwitch": true, "name": "atc" }), - + new FeatureSwitch({ "defaultEnabled": false, "label": "Force show unit control panel", "masterSwitch": true, "name": "forceShowUnitControlPanel" }), - + new FeatureSwitch({ "defaultEnabled": true, "label": "Show splash screen", @@ -108,41 +108,41 @@ export class FeatureSwitches { } - getSwitch( switchName:string ) { + getSwitch(switchName: string) { - return this.#featureSwitches.find( featureSwitch => featureSwitch.name === switchName ); + return this.#featureSwitches.find(featureSwitch => featureSwitch.name === switchName); } #testSwitches() { - for ( const featureSwitch of this.#featureSwitches ) { - if ( featureSwitch.isEnabled() ) { - if ( typeof featureSwitch.onEnabled === "function" ) { + for (const featureSwitch of this.#featureSwitches) { + if (featureSwitch.isEnabled()) { + if (typeof featureSwitch.onEnabled === "function") { featureSwitch.onEnabled(); } } else { - document.querySelectorAll( "[data-feature-switch='" + featureSwitch.name + "']" ).forEach( el => { - if ( featureSwitch.removeArtifactsIfDisabled === false ) { + document.querySelectorAll("[data-feature-switch='" + featureSwitch.name + "']").forEach(el => { + if (featureSwitch.removeArtifactsIfDisabled === false) { el.remove(); } else { - el.classList.add( "hide" ); + el.classList.add("hide"); } }); } - document.body.classList.toggle( "feature-" + featureSwitch.name, featureSwitch.isEnabled() ); + document.body.classList.toggle("feature-" + featureSwitch.name, featureSwitch.isEnabled()); } } savePreferences() { - let preferences:any = {}; + let preferences: any = {}; - for ( const featureSwitch of this.#featureSwitches ) { - preferences[ featureSwitch.name ] = featureSwitch.isEnabled(); + for (const featureSwitch of this.#featureSwitches) { + preferences[featureSwitch.name] = featureSwitch.isEnabled(); } - localStorage.setItem( "featureSwitches", JSON.stringify( preferences ) ); + localStorage.setItem("featureSwitches", JSON.stringify(preferences)); } diff --git a/client/src/features/toggleablefeature.ts b/client/src/features/toggleablefeature.ts index 5873fb6e..09f1723e 100644 --- a/client/src/features/toggleablefeature.ts +++ b/client/src/features/toggleablefeature.ts @@ -1,9 +1,9 @@ export abstract class ToggleableFeature { - #status:boolean = false; + #status: boolean = false; - constructor( defaultStatus:boolean ) { + constructor(defaultStatus: boolean) { this.#status = defaultStatus; @@ -12,17 +12,17 @@ export abstract class ToggleableFeature { } - getStatus() : boolean { + getStatus(): boolean { return this.#status; } - protected onStatusUpdate() {} + protected onStatusUpdate() { } - toggleStatus( force?:boolean ) : void { + toggleStatus(force?: boolean): void { - if ( force ) { + if (force) { this.#status = force; } else { this.#status = !this.#status; diff --git a/client/src/map/boxselect.ts b/client/src/map/boxselect.ts index b285c10a..2ea92fd8 100644 --- a/client/src/map/boxselect.ts +++ b/client/src/map/boxselect.ts @@ -1,10 +1,10 @@ import { Map } from 'leaflet'; -import { Handler} from 'leaflet'; +import { Handler } from 'leaflet'; import { Util } from 'leaflet'; import { DomUtil } from 'leaflet'; import { DomEvent } from 'leaflet'; import { LatLngBounds } from 'leaflet'; -import { Bounds } from 'leaflet'; +import { Bounds } from 'leaflet'; export var BoxSelect = Handler.extend({ initialize: function (map: Map) { @@ -82,12 +82,12 @@ export var BoxSelect = Handler.extend({ this._point = this._map.mouseEventToContainerPoint(e); var bounds = new Bounds(this._point, this._startPoint), - size = bounds.getSize(); + size = bounds.getSize(); if (bounds.min != undefined) DomUtil.setPosition(this._box, bounds.min); - this._box.style.width = size.x + 'px'; + this._box.style.width = size.x + 'px'; this._box.style.height = size.y + 'px'; }, @@ -113,7 +113,7 @@ export var BoxSelect = Handler.extend({ if ((e.which !== 1) && (e.button !== 0)) { return; } this._finish(); - + if (!this._moved) { return; } // Postpone to next JS tick so internal click event handling // still see it as "moved". @@ -121,8 +121,8 @@ export var BoxSelect = Handler.extend({ var bounds = new LatLngBounds( this._map.containerPointToLatLng(this._startPoint), this._map.containerPointToLatLng(this._point)); - - this._map.fire('selectionend', {selectionBounds: bounds}); + + this._map.fire('selectionend', { selectionBounds: bounds }); }, _onKeyDown: function (e: any) { diff --git a/client/src/map/clickableminimap.ts b/client/src/map/clickableminimap.ts new file mode 100644 index 00000000..00104f7e --- /dev/null +++ b/client/src/map/clickableminimap.ts @@ -0,0 +1,12 @@ +import { MiniMap, MiniMapOptions } from "leaflet-control-mini-map"; + +export class ClickableMiniMap extends MiniMap { + constructor(layer: L.TileLayer | L.LayerGroup, options?: MiniMapOptions) { + super(layer, options); + } + + getMap() { + //@ts-ignore needed to access not exported member. A bit of a hack, required to access click events //TODO: fix me + return this._miniMap; + } +} \ No newline at end of file diff --git a/client/src/map/custommarker.ts b/client/src/map/custommarker.ts new file mode 100644 index 00000000..41d79c14 --- /dev/null +++ b/client/src/map/custommarker.ts @@ -0,0 +1,24 @@ +import { Map, Marker } from "leaflet"; +import { MarkerOptions } from "leaflet"; +import { LatLngExpression } from "leaflet"; + +export class CustomMarker extends Marker { + constructor(latlng: LatLngExpression, options?: MarkerOptions) { + super(latlng, options); + } + + onAdd(map: Map): this { + super.onAdd(map); + this.createIcon(); + return this; + } + + onRemove(map: Map): this { + super.onRemove(map); + return this; + } + + createIcon() { + /* Overloaded by child classes */ + } +} \ No newline at end of file diff --git a/client/src/map/destinationpreviewmarker.ts b/client/src/map/destinationpreviewmarker.ts new file mode 100644 index 00000000..1146992d --- /dev/null +++ b/client/src/map/destinationpreviewmarker.ts @@ -0,0 +1,15 @@ +import { DivIcon } from "leaflet"; +import { CustomMarker } from "./custommarker"; + +export class DestinationPreviewMarker extends CustomMarker { + createIcon() { + this.setIcon(new DivIcon({ + iconSize: [52, 52], + iconAnchor: [26, 26], + className: "leaflet-destination-preview" + })); + var el = document.createElement("div"); + el.classList.add("ol-destination-preview-icon"); + this.getElement()?.appendChild(el); + } +} diff --git a/client/src/map/map.ts b/client/src/map/map.ts index f98a58c9..a36ae834 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -1,6 +1,4 @@ import * as L from "leaflet" -import { MiniMap, MiniMapOptions } from "leaflet-control-mini-map"; - import { getUnitsManager } from ".."; import { BoxSelect } from "./boxselect"; import { MapContextMenu, SpawnOptions } from "../controls/mapcontextmenu"; @@ -10,40 +8,20 @@ import { Dropdown } from "../controls/dropdown"; import { Airbase } from "../missionhandler/airbase"; import { Unit } from "../units/unit"; import { bearing } from "../other/utils"; - -// TODO a bit of a hack, this module is provided as pure javascript only -require("../../node_modules/leaflet.nauticscale/dist/leaflet.nauticscale.js") - -export const IDLE = "IDLE"; -export const MOVE_UNIT = "MOVE_UNIT"; +import { DestinationPreviewMarker } from "./destinationpreviewmarker"; +import { TemporaryUnitMarker } from "./temporaryunitmarker"; +import { ClickableMiniMap } from "./clickableminimap"; +import { SVGInjector } from '@tanem/svg-injector' L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); -var temporaryIcon = new L.Icon({ - iconUrl: 'images/icon-temporary.png', - iconSize: [52, 52], - iconAnchor: [26, 26] -}); +// TODO would be nice to convert to ts +require("../../public/javascripts/leaflet.nauticscale.js") -var destinationPreviewIcon = new L.DivIcon({ - html: `
`, - iconSize: [52, 52], - iconAnchor: [26, 26], - className: "ol-destination-preview" -}) - -const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"]; - -export class ClickableMiniMap extends MiniMap { - constructor(layer: L.TileLayer | L.LayerGroup, options?: MiniMapOptions) { - super(layer, options); - } - - getMap() { - //@ts-ignore needed to access not exported member. A bit of a hack, required to access click events - return this._miniMap; - } -} +/* Map constants */ +export const IDLE = "IDLE"; +export const MOVE_UNIT = "MOVE_UNIT"; +export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"]; export class Map extends L.Map { #state: string; @@ -107,19 +85,21 @@ export class Map extends L.Map { this.on('mousedown', (e: any) => this.#onMouseDown(e)); this.on('mouseup', (e: any) => this.#onMouseUp(e)); this.on('mousemove', (e: any) => this.#onMouseMove(e)); - this.on('keydown', (e: any) => this.#updateDestinationPreview(e)); - this.on('keyup', (e: any) => this.#updateDestinationPreview(e)); - + this.on('keydown', (e: any) => this.#updateDestinationPreview(e)); + this.on('keyup', (e: any) => this.#updateDestinationPreview(e)); + /* Event listeners */ document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => { - ev.detail._element.classList.toggle("off"); - document.body.toggleAttribute("data-hide-" + ev.detail.coalition); + const el = ev.detail._element; + el?.classList.toggle("off"); + getUnitsManager().setHiddenType(ev.detail.coalition, (el?.currentTarget as HTMLElement)?.classList.contains("off")); Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); }); document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => { - ev.detail._element.classList.toggle("off"); - document.body.toggleAttribute("data-hide-" + ev.detail.category); + const el = ev.detail._element; + el?.classList.toggle("off"); + getUnitsManager().setHiddenType(ev.detail.type, !el?.classList.contains("off")); Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility()); }); @@ -129,17 +109,14 @@ export class Map extends L.Map { }); /* Pan interval */ - this.#panInterval = window.setInterval(() => { - this.panBy(new L.Point( ((this.#panLeft? -1: 0) + (this.#panRight? 1: 0)) * this.#deafultPanDelta, - ((this.#panUp? -1: 0) + (this.#panDown? 1: 0)) * this.#deafultPanDelta)); + this.#panInterval = window.setInterval(() => { + this.panBy(new L.Point(((this.#panLeft ? -1 : 0) + (this.#panRight ? 1 : 0)) * this.#deafultPanDelta, + ((this.#panUp ? -1 : 0) + (this.#panDown ? 1 : 0)) * this.#deafultPanDelta)); }, 20); /* Option buttons */ this.#optionButtons["visibility"] = visibilityControls.map((option: string, index: number) => { - return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, "", (e: any) => { - getUnitsManager().setHiddenType(option, (e?.currentTarget as HTMLElement)?.classList.contains("off")); - (e?.currentTarget as HTMLElement)?.classList.toggle("off"); - }); + return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, "", "toggleUnitVisibility", `{"type": "${option}"}`); }); document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]); } @@ -217,10 +194,10 @@ export class Map extends L.Map { }) this.#destinationPreviewMarkers = []; - if (getUnitsManager().getSelectedUnits({excludeHumans: true}).length < 20) { + if (getUnitsManager().getSelectedUnits({ excludeHumans: true }).length < 20) { /* Create the unit destination preview markers */ - this.#destinationPreviewMarkers = getUnitsManager().getSelectedUnits({excludeHumans: true}).map((unit: Unit) => { - var marker = new L.Marker(this.getMouseCoordinates(), {icon: destinationPreviewIcon, interactive: false}); + this.#destinationPreviewMarkers = getUnitsManager().getSelectedUnits({ excludeHumans: true }).map((unit: Unit) => { + var marker = new DestinationPreviewMarker(this.getMouseCoordinates()); marker.addTo(this); return marker; }) @@ -352,7 +329,7 @@ export class Map extends L.Map { } handleMapPanning(e: any) { - if (e.type === "keyup"){ + if (e.type === "keyup") { switch (e.code) { case "KeyA": case "ArrowLeft": @@ -372,9 +349,8 @@ export class Map extends L.Map { break; } } - else { - switch (e.code) - { + else { + switch (e.code) { case 'KeyA': case 'ArrowLeft': this.#panLeft = true; @@ -396,7 +372,7 @@ export class Map extends L.Map { } addTemporaryMarker(latlng: L.LatLng) { - var marker = new L.Marker(latlng, {icon: temporaryIcon}); + var marker = new TemporaryUnitMarker(latlng); marker.addTo(this); this.#temporaryMarkers.push(marker); } @@ -413,8 +389,7 @@ export class Map extends L.Map { i = idx; } }); - if (closest) - { + if (closest) { this.removeLayer(closest); delete this.#temporaryMarkers[i]; } @@ -449,7 +424,7 @@ export class Map extends L.Map { if (!e.originalEvent.ctrlKey) { getUnitsManager().selectedUnitsClearDestinations(); } - getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null? this.#destinationRotationCenter: e.latlng, !e.originalEvent.shiftKey, this.#destinationGroupRotation) + getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, !e.originalEvent.shiftKey, this.#destinationGroupRotation) } } @@ -465,16 +440,14 @@ export class Map extends L.Map { #onMouseDown(e: any) { this.hideAllContextMenus(); - if (this.#state == MOVE_UNIT && e.originalEvent.button == 2) - { + if (this.#state == MOVE_UNIT && e.originalEvent.button == 2) { this.#computeDestinationRotation = true; this.#destinationRotationCenter = this.getMouseCoordinates(); } } #onMouseUp(e: any) { - if (this.#state == MOVE_UNIT) - { + if (this.#state == MOVE_UNIT) { this.#computeDestinationRotation = false; this.#destinationRotationCenter = null; this.#destinationGroupRotation = 0; @@ -488,7 +461,7 @@ export class Map extends L.Map { if (this.#computeDestinationRotation && this.#destinationRotationCenter != null) this.#destinationGroupRotation = -bearing(this.#destinationRotationCenter.lat, this.#destinationRotationCenter.lng, this.getMouseCoordinates().lat, this.getMouseCoordinates().lng); - this.#updateDestinationPreview(e); + this.#updateDestinationPreview(e); } #onZoom(e: any) { @@ -542,18 +515,23 @@ export class Map extends L.Map { } #updateDestinationPreview(e: any) { - Object.values(getUnitsManager().selectedUnitsComputeGroupDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null? this.#destinationRotationCenter: this.getMouseCoordinates(), this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => { + Object.values(getUnitsManager().selectedUnitsComputeGroupDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : this.getMouseCoordinates(), this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => { if (idx < this.#destinationPreviewMarkers.length) - this.#destinationPreviewMarkers[idx].setLatLng(!e.originalEvent.shiftKey? latlng: this.getMouseCoordinates()); - }) + this.#destinationPreviewMarkers[idx].setLatLng(!e.originalEvent.shiftKey ? latlng : this.getMouseCoordinates()); + }) } - #createOptionButton(value: string, url: string, title: string, callback: EventListenerOrEventListenerObject) { + #createOptionButton(value: string, url: string, title: string, callback: string, argument: string) { var button = document.createElement("button"); + const img = document.createElement("img"); + img.src = `/resources/theme/images/buttons/${url}`; + img.onload = () => SVGInjector(img); button.title = title; button.value = value; - button.innerHTML = `` - button.addEventListener("click", callback); + button.appendChild(img); + button.setAttribute("data-on-click", callback); + button.setAttribute("data-on-click-params", argument); return button; } } + diff --git a/client/src/map/temporaryunitmarker.ts b/client/src/map/temporaryunitmarker.ts new file mode 100644 index 00000000..904ee83d --- /dev/null +++ b/client/src/map/temporaryunitmarker.ts @@ -0,0 +1,13 @@ +import { Icon } from "leaflet"; +import { CustomMarker } from "./custommarker"; + +export class TemporaryUnitMarker extends CustomMarker { + createIcon() { + var icon = new Icon({ + iconUrl: '/resources/theme/images/markers/temporary-icon.png', + iconSize: [52, 52], + iconAnchor: [26, 26] + }); + this.setIcon(icon); + } +} \ No newline at end of file diff --git a/client/src/missionhandler/airbase.ts b/client/src/missionhandler/airbase.ts index a3ca42dc..4128001b 100644 --- a/client/src/missionhandler/airbase.ts +++ b/client/src/missionhandler/airbase.ts @@ -1,13 +1,14 @@ -import * as L from 'leaflet' +import { DivIcon } from 'leaflet'; +import { CustomMarker } from '../map/custommarker'; +import { SVGInjector } from '@tanem/svg-injector'; export interface AirbaseOptions { name: string, - position: L.LatLng, - src: string + position: L.LatLng } -export class Airbase extends L.Marker +export class Airbase extends CustomMarker { #name: string = ""; #coalition: string = ""; @@ -19,21 +20,30 @@ export class Airbase extends L.Marker super(options.position, { riseOnHover: true }); this.#name = options.name; - var icon = new L.DivIcon({ - html: `
-
-
`, + } + + createIcon() { + var icon = new DivIcon({ className: 'leaflet-airbase-marker', iconSize: [40, 40], iconAnchor: [20, 20] }); // Set the marker, className must be set to avoid white square this.setIcon(icon); + + var el = document.createElement("div"); + el.classList.add("airbase-icon"); + el.setAttribute("data-object", "airbase"); + var img = document.createElement("img"); + img.src = "/resources/theme/images/markers/airbase.svg"; + img.onload = () => SVGInjector(img); + el.appendChild(img); + this.getElement()?.appendChild(el); } setCoalition(coalition: string) { this.#coalition = coalition; - ( this.getElement()?.querySelector(".airbase")).dataset.coalition = this.#coalition; + ( this.getElement()?.querySelector(".airbase-icon")).dataset.coalition = this.#coalition; } getCoalition() diff --git a/client/src/missionhandler/bullseye.ts b/client/src/missionhandler/bullseye.ts new file mode 100644 index 00000000..b50b1a7b --- /dev/null +++ b/client/src/missionhandler/bullseye.ts @@ -0,0 +1,36 @@ +import { DivIcon } from "leaflet"; +import { CustomMarker } from "../map/custommarker"; +import { SVGInjector } from "@tanem/svg-injector"; + +export class Bullseye extends CustomMarker { + #coalition: string = ""; + + createIcon() { + var icon = new DivIcon({ + className: 'leaflet-bullseye-marker', + iconSize: [40, 40], + iconAnchor: [20, 20] + }); // Set the marker, className must be set to avoid white square + this.setIcon(icon); + + var el = document.createElement("div"); + el.classList.add("bullseye-icon"); + el.setAttribute("data-object", "bullseye"); + var img = document.createElement("img"); + img.src = "/resources/theme/images/markers/bullseye.svg"; + img.onload = () => SVGInjector(img); + el.appendChild(img); + this.getElement()?.appendChild(el); + } + + setCoalition(coalition: string) + { + this.#coalition = coalition; + ( this.getElement()?.querySelector(".bullseye-icon")).dataset.coalition = this.#coalition; + } + + getCoalition() + { + return this.#coalition; + } +} \ No newline at end of file diff --git a/client/src/missionhandler/missionhandler.ts b/client/src/missionhandler/missionhandler.ts index 66233f0a..93b13192 100644 --- a/client/src/missionhandler/missionhandler.ts +++ b/client/src/missionhandler/missionhandler.ts @@ -1,44 +1,58 @@ -import { Marker, LatLng, Icon } from "leaflet"; +import { LatLng } from "leaflet"; import { getInfoPopup, getMap } from ".."; import { Airbase } from "./airbase"; - -var bullseyeIcons = [ - new Icon({ iconUrl: 'images/bullseye0.png', iconAnchor: [30, 30]}), - new Icon({ iconUrl: 'images/bullseye1.png', iconAnchor: [30, 30]}), - new Icon({ iconUrl: 'images/bullseye2.png', iconAnchor: [30, 30]}) -] +import { Bullseye } from "./bullseye"; export class MissionHandler { - #bullseyes : any; //TODO declare interface - #bullseyeMarkers: any; - #airbases : any; //TODO declare interface - #airbasesMarkers: {[name: string]: Airbase}; + #bullseyes : {[name: string]: Bullseye} = {}; + #airbases : {[name: string]: Airbase} = {}; #theatre : string = ""; constructor() { - this.#bullseyes = undefined; - this.#bullseyeMarkers = [ - new Marker([0, 0], {icon: bullseyeIcons[0]}).addTo(getMap()), - new Marker([0, 0], {icon: bullseyeIcons[1]}).addTo(getMap()), - new Marker([0, 0], {icon: bullseyeIcons[2]}).addTo(getMap()) - ] - this.#airbasesMarkers = {}; + } update(data: BullseyesData | AirbasesData | any) { if ("bullseyes" in data) { - this.#bullseyes = data.bullseyes; - this.#drawBullseyes(); + for (let idx in data.bullseyes) + { + const bullseye = data.bullseyes[idx]; + if (!(idx in this.#bullseyes)) + this.#bullseyes[idx] = new Bullseye([0, 0]).addTo(getMap()); + + if (bullseye.latitude && bullseye.longitude && bullseye.coalition) + { + this.#bullseyes[idx].setLatLng(new LatLng(bullseye.latitude, bullseye.longitude)); + this.#bullseyes[idx].setCoalition(bullseye.coalition); + } + } } if ("airbases" in data) { - this.#airbases = data.airbases; - this.#drawAirbases(); + for (let idx in data.airbases) + { + var airbase = data.airbases[idx] + if (this.#airbases[idx] === undefined) + { + this.#airbases[idx] = new Airbase({ + position: new LatLng(airbase.latitude, airbase.longitude), + name: airbase.callsign + }).addTo(getMap()); + this.#airbases[idx].on('contextmenu', (e) => this.#onAirbaseClick(e)); + } + if (airbase.latitude && airbase.longitude && airbase.coalition) + { + this.#airbases[idx].setLatLng(new LatLng(airbase.latitude, airbase.longitude)); + this.#airbases[idx].setCoalition(airbase.coalition); + } + //this.#airbases[idx].setProperties(["Runway 1: 31L / 13R", "Runway 2: 31R / 13L", "TCN: 17X", "ILS: ---" ]); + //this.#airbases[idx].setParkings(["2x big", "5x small"]); + } } if ("mission" in data) @@ -58,38 +72,6 @@ export class MissionHandler return this.#bullseyes; } - #drawBullseyes() - { - for (let idx in this.#bullseyes) - { - var bullseye = this.#bullseyes[idx]; - this.#bullseyeMarkers[idx].setLatLng(new LatLng(bullseye.latitude, bullseye.longitude)); - } - } - - #drawAirbases() - { - for (let idx in this.#airbases) - { - var airbase = this.#airbases[idx] - if (this.#airbasesMarkers[idx] === undefined) - { - this.#airbasesMarkers[idx] = new Airbase({ - position: new LatLng(airbase.latitude, airbase.longitude), - name: airbase.callsign, - src: "images/airbase.png"}).addTo(getMap()); - this.#airbasesMarkers[idx].on('contextmenu', (e) => this.#onAirbaseClick(e)); - } - else - { - this.#airbasesMarkers[idx].setLatLng(new LatLng(airbase.latitude, airbase.longitude)); - this.#airbasesMarkers[idx].setCoalition(airbase.coalition); - //this.#airbasesMarkers[idx].setProperties(["Runway 1: 31L / 13R", "Runway 2: 31R / 13L", "TCN: 17X", "ILS: ---" ]); - //this.#airbasesMarkers[idx].setParkings(["2x big", "5x small"]); - } - } - } - #onAirbaseClick(e: any) { getMap().showAirbaseContextMenu(e, e.sourceTarget); diff --git a/client/src/other/utils.ts b/client/src/other/utils.ts index b3899d41..ce1ecc1f 100644 --- a/client/src/other/utils.ts +++ b/client/src/other/utils.ts @@ -154,4 +154,10 @@ export function mercatorToLatLng(x: number, y: number) { lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180.0)) - Math.PI / 2.0); return { lng: lng, lat: lat }; +} + +export function createDivWithClass(className: string) { + var el = document.createElement("div"); + el.classList.add(className); + return el; } \ No newline at end of file diff --git a/client/src/panels/mouseinfopanel.ts b/client/src/panels/mouseinfopanel.ts index 7cfdd710..bdd38fb3 100644 --- a/client/src/panels/mouseinfopanel.ts +++ b/client/src/panels/mouseinfopanel.ts @@ -37,8 +37,8 @@ export class MouseInfoPanel extends Panel { if ( el != null ) { - var dist = distance(bullseyes[idx].latitude, bullseyes[idx].longitude, mousePosition.lat, mousePosition.lng); - var bear = bearing(bullseyes[idx].latitude, bullseyes[idx].longitude, mousePosition.lat, mousePosition.lng); + var dist = distance(bullseyes[idx].getLatLng().lat, bullseyes[idx].getLatLng().lng, mousePosition.lat, mousePosition.lng); + var bear = bearing(bullseyes[idx].getLatLng().lat, bullseyes[idx].getLatLng().lng, mousePosition.lat, mousePosition.lng); let bng = zeroAppend(Math.floor(bear), 3); diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index 9f6ef22e..7b1967d4 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -346,7 +346,7 @@ export class UnitControlPanel extends Panel { var button = document.createElement("button"); button.title = title; button.value = value; - button.innerHTML = `` + button.innerHTML = `` button.addEventListener("click", callback); return button; } diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index a7a7ec09..3338c095 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -4,14 +4,16 @@ import { rad2deg } from '../other/utils'; import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, getUnits, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures } from '../server/server'; import { aircraftDatabase } from './aircraftdatabase'; import { groundUnitsDatabase } from './groundunitsdatabase'; +import { CustomMarker } from '../map/custommarker'; +import { SVGInjector } from '@tanem/svg-injector'; var pathIcon = new Icon({ - iconUrl: 'images/marker-icon.png', - shadowUrl: 'images/marker-shadow.png', + iconUrl: '/resources/theme/images/markers/marker-icon.png', + shadowUrl: '/resources/theme/images/markers/marker-shadow.png', iconAnchor: [13, 41] }); -export class Unit extends Marker { +export class Unit extends CustomMarker { ID: number; #data: UnitData = { @@ -114,22 +116,7 @@ export class Unit extends Marker { /* Set the unit data */ this.setData(data); - /* Set the icon */ - var icon = new DivIcon({ - html: this.getMarkerHTML(), - className: 'leaflet-unit-marker', - iconAnchor: [25, 25], - iconSize: [50, 50], - }); - this.setIcon(icon); - } - - getMarkerHTML() { - return `
-
-
-
-
` + } getMarkerCategory() { @@ -137,6 +124,20 @@ export class Unit extends Marker { return ""; } + getActiveMarkerElements() { + // Default values + return { + state: false, + vvi: false, + hotgroup: false, + unitIcon: true, + shortLabel: false, + fuel: false, + ammo: false, + summary: false + } + } + setSelected(selected: boolean) { /* Only alive units can be selected. Some units are not selectable (weapons) */ if ((this.getBaseData().alive || !selected) && this.getSelectable() && this.getSelected() != selected) { @@ -285,6 +286,104 @@ export class Unit extends Marker { return this.getData().optionsData; } + /********************** Icon *************************/ + createIcon(): void { + /* Set the icon */ + var icon = new DivIcon({ + className: 'leaflet-unit-icon', + iconAnchor: [25, 25], + iconSize: [50, 50], + }); + this.setIcon(icon); + + var el = document.createElement("div"); + el.setAttribute("data-object", `unit-${this.getMarkerCategory()}`); + el.setAttribute("data-coalition", this.getMissionData().coalition); + + // Generate and append elements depending on active options + // State icon + if (this.getActiveMarkerElements().state){ + var state = document.createElement("div"); + state.classList.add("unit-state"); + el.appendChild(state); + } + + // Velocity vector + if (this.getActiveMarkerElements().vvi) { + var vvi = document.createElement("div"); + vvi.classList.add("unit-vvi"); + vvi.toggleAttribute("data-rotate-to-heading"); + el.append(vvi); + } + + // Hotgroup indicator + if (this.getActiveMarkerElements().hotgroup) { + var hotgroup = document.createElement("div"); + hotgroup.classList.add("unit-hotgroup"); + var hotgroupId = document.createElement("div"); + hotgroupId.classList.add("unit-hotgroup-id"); + hotgroup.appendChild(hotgroupId); + el.append(hotgroup); + } + + // Main icon + if (this.getActiveMarkerElements().unitIcon) { + var unitIcon = document.createElement("div"); + unitIcon.classList.add("unit-icon"); + var img = document.createElement("img"); + img.src = `/resources/theme/images/units/${this.getMarkerCategory()}.svg`; + img.onload = () => SVGInjector(img); + unitIcon.appendChild(img); + el.append(unitIcon); + } + + // Short label + if (this.getActiveMarkerElements().shortLabel) { + var shortLabel = document.createElement("div"); + shortLabel.classList.add("unit-short-label"); + shortLabel.innerText = aircraftDatabase.getByName(this.getBaseData().name)?.shortLabel || ""; //TODO: fix, use correct database + el.append(shortLabel); + } + + // Fuel indicator + if (this.getActiveMarkerElements().fuel) { + var fuelIndicator = document.createElement("div"); + fuelIndicator.classList.add("unit-fuel"); + var fuelLevel = document.createElement("div"); + fuelLevel.classList.add("unit-fuel-level"); + fuelIndicator.appendChild(fuelLevel); + el.append(fuelIndicator); + } + + // Ammo indicator + if (this.getActiveMarkerElements().ammo){ + var ammoIndicator = document.createElement("div"); + ammoIndicator.classList.add("unit-ammo"); + for (let i = 0; i <= 3; i++) + ammoIndicator.appendChild(document.createElement("div")); + el.append(ammoIndicator); + } + + // Unit summary + if (this.getActiveMarkerElements().summary) { + var summary = document.createElement("div"); + summary.classList.add("unit-summary"); + var callsign = document.createElement("div"); + callsign.classList.add("unit-callsign"); + callsign.innerText = this.getBaseData().unitName; + var altitude = document.createElement("div"); + altitude.classList.add("unit-altitude"); + var speed = document.createElement("div"); + speed.classList.add("unit-speed"); + summary.appendChild(callsign); + summary.appendChild(altitude); + summary.appendChild(speed); + el.appendChild(summary); + } + + this.getElement()?.appendChild(el); + } + /********************** Visibility *************************/ updateVisibility() { var hidden = false; @@ -295,7 +394,9 @@ export class Unit extends Marker { hidden = true; else if (hiddenUnits.includes(this.getMarkerCategory())) hidden = true; - this.setHidden(document.body.getAttribute(`data-hide-${this.getMissionData().coalition}`) != null || hidden || !this.getBaseData().alive); + else if (hiddenUnits.includes(this.getMissionData().coalition)) + hidden = true; + this.setHidden(hidden || !this.getBaseData().alive); } setHidden(hidden: boolean) { @@ -576,7 +677,7 @@ export class Unit extends Marker { el.setAttribute("style", currentStyle + `transform:rotate(${headingDeg}deg);`); }); - /* Turn on ordnance indicators */ + /* Turn on ammo indicators */ var hasFox1 = element.querySelector(".unit")?.hasAttribute("data-has-fox-1"); var hasFox2 = element.querySelector(".unit")?.hasAttribute("data-has-fox-2"); var hasFox3 = element.querySelector(".unit")?.hasAttribute("data-has-fox-3"); @@ -690,7 +791,18 @@ export class Unit extends Marker { } export class AirUnit extends Unit { - + getActiveMarkerElements() { + return { + state: true, + vvi: true, + hotgroup: true, + unitIcon: true, + shortLabel: true, + fuel: true, + ammo: true, + summary: true + }; + } } export class Aircraft extends AirUnit { @@ -698,30 +810,6 @@ export class Aircraft extends AirUnit { super(ID, data); } - getMarkerHTML() { - return `
-
-
-
-
-
${aircraftDatabase.getByName(this.getBaseData().name)?.shortLabel || ""}
-
-
-
-
-
-
-
-
-
-
-
${this.getBaseData().unitName}
-
-
-
-
` - } - getMarkerCategory() { return "aircraft"; } @@ -732,7 +820,7 @@ export class Helicopter extends AirUnit { super(ID, data); } - getVisibilityCategory() { + getMarkerCategory() { return "helicopter"; } } @@ -742,15 +830,17 @@ export class GroundUnit extends Unit { super(ID, data); } - getMarkerHTML() { - var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0]; - return `
-
-
${role?.substring(0, 1)?.toUpperCase() || ""}
-
-
-
-
` + getActiveMarkerElements() { + return { + state: true, + vvi: false, + hotgroup: true, + unitIcon: true, + shortLabel: true, + fuel: false, + ammo: false, + summary: false + }; } getMarkerCategory() { @@ -766,6 +856,19 @@ export class NavyUnit extends Unit { super(ID, data); } + getActiveMarkerElements() { + return { + state: true, + vvi: false, + hotgroup: true, + unitIcon: true, + shortLabel: true, + fuel: false, + ammo: false, + summary: false + }; + } + getMarkerCategory() { return "navyunit"; } @@ -776,14 +879,6 @@ export class Weapon extends Unit { super(ID, data); this.setSelectable(false); } - - getMarkerHTML(): string { - return `
-
-
-
` - } - } export class Missile extends Weapon { diff --git a/client/views/index.ejs b/client/views/index.ejs index 863572aa..558d6b67 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -9,9 +9,7 @@ - - - + diff --git a/client/views/panels/navbar.ejs b/client/views/panels/navbar.ejs index 06aeeeb9..3ae2453a 100644 --- a/client/views/panels/navbar.ejs +++ b/client/views/panels/navbar.ejs @@ -4,7 +4,7 @@
-
+

DCS Olympus

version v0.2.1
diff --git a/client/views/panels/unitcontrol.ejs b/client/views/panels/unitcontrol.ejs index d27223f5..fe67082c 100644 --- a/client/views/panels/unitcontrol.ejs +++ b/client/views/panels/unitcontrol.ejs @@ -40,21 +40,21 @@

Rules of engagement

-
+

Reaction to threat

-
+

Radar & ECM

-
+
diff --git a/client/views/uikit/uikit.ejs b/client/views/uikit/uikit.ejs index 9bcc7e2c..e4c0a2f4 100644 --- a/client/views/uikit/uikit.ejs +++ b/client/views/uikit/uikit.ejs @@ -2,7 +2,7 @@ Olympus UI Kit - + @@ -172,7 +172,7 @@
-
+
Z
@@ -184,7 +184,7 @@
-
+
Y
@@ -196,7 +196,7 @@
-
+
X
@@ -218,7 +218,7 @@
-
+
Z
@@ -230,7 +230,7 @@
-
+
Y
@@ -242,7 +242,7 @@
-
+
X
@@ -263,7 +263,7 @@
-
+
Z
@@ -275,7 +275,7 @@
-
+
Y
@@ -287,7 +287,7 @@
-
+
X
@@ -308,7 +308,7 @@
-
+
J
@@ -320,7 +320,7 @@
-
+
K
@@ -332,7 +332,7 @@
-
+
L
@@ -360,7 +360,7 @@
4
-
+
18
@@ -384,7 +384,7 @@
4
-
+
18
@@ -407,7 +407,7 @@
4
-
+
18
@@ -430,7 +430,7 @@
4
-
+
18
@@ -453,7 +453,7 @@
4
-
+
18
@@ -476,7 +476,7 @@
4
-
+
18
@@ -509,7 +509,7 @@
4
-
+
18
@@ -539,7 +539,7 @@
4
-
+
18
@@ -568,7 +568,7 @@
4
-
+
18
@@ -598,7 +598,7 @@
4
-
+
18
@@ -628,7 +628,7 @@
4
-
+
18
@@ -657,7 +657,7 @@
4
-
+
18
@@ -695,7 +695,7 @@
4
-
+
18
@@ -725,7 +725,7 @@
4
-
+
18
@@ -754,7 +754,7 @@
4
-
+
18
@@ -791,7 +791,7 @@
-
+
@@ -800,7 +800,7 @@
-
+
@@ -808,7 +808,7 @@
-
+
@@ -1183,19 +1183,19 @@
Actions
- + icons_actions_gas
- + icons_actions_nothing
- + icons_actions_rtb
- + icons_actions_search
@@ -1205,19 +1205,19 @@
RoE
- + icons_roe_free
- + icons_roe_return
- + icons_roe_stop
- + icons_roe_target
@@ -1227,11 +1227,11 @@
Threat
- + icons_threat_protect
- + icons_threat_retreat