From 3939d4631f888cca78ab337f5878300d295e8dc0 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:50:46 -0400 Subject: [PATCH] FlyAvatar 2.0 This PR add the support of a flying Avatar per Avatar Bookmark. Instead to have a flying avatar defined for all avatar and all the time, this version will let you define a flying avatar for each bookmark where you need one. You can then have also some avatar without flying avatar linked to it if you want. or have very different flying avatar depending the avatar used. --- applications/flyAvatar/app-flyAvatar.js | 79 ++++++-- applications/flyAvatar/flyAvatar.html | 247 ++++++++++++++++++++++-- 2 files changed, 292 insertions(+), 34 deletions(-) diff --git a/applications/flyAvatar/app-flyAvatar.js b/applications/flyAvatar/app-flyAvatar.js index 9acad99..a2ecb42 100644 --- a/applications/flyAvatar/app-flyAvatar.js +++ b/applications/flyAvatar/app-flyAvatar.js @@ -25,10 +25,11 @@ var timestamp = 0; var INTERCALL_DELAY = 200; //0.3 sec var FLY_AVATAR_SETTING_KEY = "overte.application.more.flyAvatar.avatarUrl"; + var FLY_AVATAR_SETTING_KEY_2 = "overte.application.more.flyAvatar.avatarUrl.2"; var FLY_AVATAR_SWITCH_SETTING_KEY = "overte.application.more.flyAvatar.switch"; var FLY_AVATAR_ORIGINAL_AVATAR_SETTING_KEY = "overte.application.more.flyAvatar.originalAvatarUrl"; var flyAvatarSwitch = true; - var flyAvatarUrl = ""; + var flyAvatarUrl = []; //must be an array of {"avatarUrl": "", "flyAvatarUrl": ""} var originalAvatarUrl = ""; var isFlying = false; var UPDATE_TIMER_INTERVAL = 500; // 5 sec @@ -54,7 +55,6 @@ colorCaption = ICON_CAPTION_COLOR; appStatus = false; }else{ - //Launching the Application UI. tablet.gotoWebScreen(APP_URL); tablet.webEventReceived.connect(onAppWebEventReceived); colorCaption = "#000000"; @@ -69,23 +69,18 @@ button.clicked.connect(clicked); - //This recieved the message from the UI(html) for a specific actions function onAppWebEventReceived(message) { if (typeof message === "string") { var d = new Date(); var n = d.getTime(); var instruction = JSON.parse(message); if (instruction.channel === channel) { - if (instruction.action === "HUMAN_CALLED_ACTION_NAME" && (n - timestamp) > INTERCALL_DELAY) { //<== Use this for action trigger by a human (button or any ui control). The delay prevent multiple call to destabilize everything. - d = new Date(); - timestamp = d.getTime(); - //Call a function to do something here - } else if (instruction.action === "REQUEST_INITIAL_DATA") { + if (instruction.action === "REQUEST_INITIAL_DATA") { sendCurrentFlyAvatarUrlToUI(); } else if (instruction.action === "UPDATE_URL") { flyAvatarUrl = instruction.url; flyAvatarSwitch = instruction.mainSwitch; - Settings.setValue( FLY_AVATAR_SETTING_KEY, flyAvatarUrl); + Settings.setValue( FLY_AVATAR_SETTING_KEY_2, flyAvatarUrl); Settings.setValue( FLY_AVATAR_SWITCH_SETTING_KEY, flyAvatarSwitch); updateAvatar(); if (flyAvatarSwitch) { @@ -94,7 +89,7 @@ inactiveIcon = APP_ICON_INACTIVE_OFF; } button.editProperties({icon: inactiveIcon}); - } else if (instruction.action === "SELF_UNINSTALL" && (n - timestamp) > INTERCALL_DELAY) { //<== This is a good practice to add a "Uninstall this app" button for rarely used app. (toolbar has a limit in size) + } else if (instruction.action === "SELF_UNINSTALL" && (n - timestamp) > INTERCALL_DELAY) { d = new Date(); timestamp = d.getTime(); ScriptDiscoveryService.stopScript(Script.resolvePath(''), false); @@ -102,19 +97,51 @@ } } } - + + function getFlyAvatarOfAvatar(avatarUrl) { + let i; + let url = ""; + if (flyAvatarUrl.length > 0) { + for (i = 0; i < flyAvatarUrl.length; i++) { + if (flyAvatarUrl[i].avatarUrl === avatarUrl) { + url = flyAvatarUrl[i].flyAvatarUrl; + break; + } + } + } + return url; + } + + function getIndexOfFlyAvatar(urlOfFlyAvatar) { + let i; + let index = -1; + if (flyAvatarUrl.length > 0) { + for (i = 0; i < flyAvatarUrl.length; i++) { + if (flyAvatarUrl[i].flyAvatarUrl === urlOfFlyAvatar) { + index = i; + break; + } + } + } + return index; + } + function updateAvatar() { if (MyAvatar.isFlying() && flyAvatarSwitch) { - MyAvatar.useFullAvatarURL(flyAvatarUrl); + let replacement = getFlyAvatarOfAvatar(originalAvatarUrl); + if (replacement !== "") { + MyAvatar.useFullAvatarURL(replacement); + } } else { - if (MyAvatar.skeletonModelURL === flyAvatarUrl) { - MyAvatar.useFullAvatarURL(originalAvatarUrl); + let index = getIndexOfFlyAvatar(MyAvatar.skeletonModelURL); + if (index !== -1) { + MyAvatar.useFullAvatarURL(flyAvatarUrl[index].avatarUrl); } } } MyAvatar.skeletonModelURLChanged.connect(function () { - if (!MyAvatar.isFlying() && MyAvatar.skeletonModelURL !== flyAvatarUrl) { + if (!MyAvatar.isFlying() && getIndexOfFlyAvatar(MyAvatar.skeletonModelURL) === -1) { originalAvatarUrl = MyAvatar.skeletonModelURL; Settings.setValue( FLY_AVATAR_ORIGINAL_AVATAR_SETTING_KEY, originalAvatarUrl); } @@ -139,6 +166,7 @@ "channel": channel, "action": "FLY-AVATAR-URL", "url": flyAvatarUrl, + "bookmarks": AvatarBookmarks.getBookmarks(), "mainSwitch": flyAvatarSwitch }; tablet.emitScriptEvent(JSON.stringify(message)); @@ -159,6 +187,20 @@ }); } + function isFlyAvatar(url) { + let i; + let isFlyAv = false; + if (flyAvatarUrl.length > 0) { + for (i = 0; i < flyAvatarUrl.length; i++) { + if (flyAvatarUrl[i].flyAvatarUrl === url) { + isFlyAv = true; + break; + } + } + } + return isFlyAv; + } + function cleanup() { if (appStatus) { @@ -173,9 +215,12 @@ Script.scriptEnding.connect(cleanup); originalAvatarUrl = MyAvatar.skeletonModelURL; - flyAvatarUrl = Settings.getValue( FLY_AVATAR_SETTING_KEY, "" ); + if (Settings.getValue( FLY_AVATAR_SETTING_KEY, "" ) !== "") { //Clear Old Settings if present + Settings.setValue( FLY_AVATAR_SETTING_KEY, ""); + } + flyAvatarUrl = Settings.getValue( FLY_AVATAR_SETTING_KEY_2, "" ); flyAvatarSwitch = Settings.getValue( FLY_AVATAR_SWITCH_SETTING_KEY, true ); - if (originalAvatarUrl === flyAvatarUrl) { + if (isFlyAvatar(originalAvatarUrl)) { var lastRecordedOriginalAvatar = Settings.getValue( FLY_AVATAR_ORIGINAL_AVATAR_SETTING_KEY, "" ); if (lastRecordedOriginalAvatar !== "") { originalAvatarUrl = lastRecordedOriginalAvatar; diff --git a/applications/flyAvatar/flyAvatar.html b/applications/flyAvatar/flyAvatar.html index 099f235..2d22fbc 100644 --- a/applications/flyAvatar/flyAvatar.html +++ b/applications/flyAvatar/flyAvatar.html @@ -20,7 +20,8 @@ var thisPageName = "flyAvatar.html"; var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname; var ROOTPATH = currentPath.replace(thisPageName, ""); - var flyAvatarUrl = ""; + var flyAvatarUrl = []; + var bookmarks = []; var flyAvatarSwitch = true; EventBridge.scriptEventReceived.connect(function(message){ @@ -28,9 +29,11 @@ if (messageObj.channel === channel) { if (messageObj.action === "FLY-AVATAR-URL") { flyAvatarUrl = messageObj.url; + bookmarks = messageObj.bookmarks; flyAvatarSwitch = messageObj.mainSwitch; document.getElementById("mainSwitch").checked = flyAvatarSwitch; - document.getElementById("avatarUrl").value = flyAvatarUrl; + genBookmarkMenu(); + genAvatarList(); } } }); @@ -86,7 +89,12 @@ } #avatarUrl { - width: 98%; + width: 75%; + font-size: 11px; + font-family: FiraSans-SemiBold; + background-color: #222222; + color: #bbbbbb; + border: 1px solid #bbbbbb; } #avatarUrl:focus { @@ -94,29 +102,142 @@ } #formContainer { width: 100%; - height: 590px; + } + #bookmarkPanel { + height: 690px; + width: 100%; + position: fixed; + z-index: 1; + top: 0px; + left: 0px; + background-color: #cccccc; + overflow-x: hidden; + overflow-y: auto; + transition: 0.5s; + display: none; + } + button.menuItem { + border: 0px; + border-bottom: 1px solid #222222; + text-align: left; + color: #000000; + width: 100%; + background-color: #bbbbbb; + font-size: 12px; + font-family: FiraSans-SemiBold; + } + button.menuItem:hover { + width: 100%; + background-color: #333333; + color: #bbbbbb; + } + #closeMenuBtn { + text-align: right; + width:100%; + color: #000000; + font-size: 18px; + font-family: FiraSans-SemiBold; + border-bottom: 1px solid #222222; + } + input:focus { + outline: none; + } + button:focus { + outline: none; + } + #bookmarks { + font-family: FiraSans-SemiBold; + background-color: #222222; + font-size: 11px; + color: #cccccc; + border-radius: 5px; + border: 0px solid #000000; + transition-duration: 0.2s; + padding: 3px 10px 3px 10px; + margin-top: 3px; + margin-bottom: 3px; + } + #bookmarks:hover { + background-color: #111111; + color: #ffffff; + } + #avatarList { + height: 470px; + width: 100%; + background-color: #222222; + overflow-x: hidden; + overflow-y: auto; + color: #bbbbbb; + font-size: 8px; + font-family: FiraSans-Regular; + margin-bottom: 5px; + } + #addContainer { + border: 1px solid #bbbbbb; + width: 97%; + padding: 5px; + } + font.formTitle { + font-size: 14px; + font-family: FiraSans-SemiBold; + } + #addBtn { + font-family: FiraSans-SemiBold; + background-color: #0066ff; + background-image: linear-gradient(to bottom, #0066ff, #0020a1); + font-size: 11px; + color: #cccccc; + border-radius: 5px; + border: 0px solid #000000; + transition-duration: 0.2s; + padding: 3px 17px 3px 17px; + margin-top: 5px; + } + #addBtn:hover { + background-color: #26a1ff; + background-image: linear-gradient(to bottom, #26a1ff, #0060d6); + color: #ffffff; + } + span.removeBtn { + font-family: FiraSans-SemiBold; + font-size: 16px; + color: #c27a7a; + } + table.grid { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + } + td { + border: 1px solid #888888; + color: #bbbbbb; + font-size: 10px; + font-family: FiraSans-Regular; + word-wrap: break-word; + padding: 3px; + } + tr { + vertical-align: top; }
- +