From 52ed9a8848db2e986bb95a23842085ac492302cc Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 7 Sep 2026 23:42:29 +0800 Subject: [PATCH] Optimize login user layout --- resources/web/homepage/css/dark.css | 33 +- resources/web/homepage/css/home.css | 440 ++++++++++++++------- resources/web/homepage/img/c.jpg | Bin 38788 -> 0 bytes resources/web/homepage/index.html | 91 +++-- resources/web/homepage/js/home.js | 229 ++++++----- src/slic3r/Utils/OrcaCloudServiceAgent.cpp | 8 +- 6 files changed, 508 insertions(+), 293 deletions(-) delete mode 100644 resources/web/homepage/img/c.jpg diff --git a/resources/web/homepage/css/dark.css b/resources/web/homepage/css/dark.css index d4950c9c80..9e72c4c2b7 100644 --- a/resources/web/homepage/css/dark.css +++ b/resources/web/homepage/css/dark.css @@ -39,7 +39,7 @@ body .BtnItem:hover { color: #efeff0; - background-color: #223C3C; + background-color: var(--row-hover); } .BtnItem:hover .LeftIcon @@ -50,7 +50,7 @@ body .BtnItemSelected { color: #efeff0; - background-color: #223C3C; + background-color: var(--row-hover); } .BtnItemSelected .LeftIcon @@ -129,12 +129,23 @@ body border: 1px solid rgba(129, 129, 131, 0.64); } -/*--- Account Sections ---*/ -.AccountSectionLabel { color: #818183; } -.OrcaAccountText { color: #efeff0; } -.AccountStatusText { color: #818183; } - -/*--- Bambu Cloud Section ---*/ -#BambuCloudHeader { color: #818183; } -#BambuCloudHeader:hover { color: #efeff0; } -.bambu-chevron svg path { stroke: currentColor; } +/*--- Account rows and account menu ---*/ +:root +{ + --row-hover : #223C3C; + --warn-color : #F07E4A; + --account-avatar-bg : #3A3A40; + --account-avatar-glyph : #7E8785; + --account-surface : #36363B; + --account-name : #EFEFF0; + --account-meta : #949494; + --account-border : #4A4A51; + --account-divider : #3A3A42; + --account-action : #26A69A; + --account-danger : #FF6A6A; + --account-danger-bg : rgba(225, 71, 71, 0.16); + --account-warn-bg : rgba(240, 126, 74, 0.16); /*----var(--warn-color) at 16%----*/ + --account-dot-off : #5A5A62; + --account-dot-on : #4CAF50; + --account-menu-shadow : 0 10px 28px rgba(0, 0, 0, 0.45); +} diff --git a/resources/web/homepage/css/home.css b/resources/web/homepage/css/home.css index e99d22ec64..2cf5742747 100644 --- a/resources/web/homepage/css/home.css +++ b/resources/web/homepage/css/home.css @@ -41,7 +41,7 @@ html, body { .RedFont { font-size:12px; - color: #F07E4A; + color: var(--warn-color); } .LinkBtn @@ -78,129 +78,267 @@ body height: 100%; } -#LoginArea +/*------Account rows and account menu------*/ + +/*----These shadow similar tokens in global.css on purpose: global.css themes on the OS + via prefers-color-scheme, while this page themes on the dark.css link that + SwitchDarkMode() injects from the app theme, so the two can disagree.----*/ +:root { - display: flex; - flex-direction: column; - align-items: center; - flex-wrap: nowrap; - position: relative; - width:262px; + --row-hover : #BFE1DE; + --warn-color : #F07E4A; + --account-avatar-bg : #E6EBEA; + --account-avatar-glyph : #9AA5A3; + --account-surface : #FFFFFF; + --account-name : #262E30; + --account-meta : #7C8282; + --account-border : #DBDBDB; + --account-divider : #E2E4E4; + --account-action : #00796B; + --account-danger : #D33B3B; + --account-danger-bg : rgba(211, 59, 59, 0.10); + --account-warn-bg : rgba(240, 126, 74, 0.12); /*----var(--warn-color) at 12%----*/ + --account-dot-off : #C4CBCA; + --account-dot-on : #34A853; + --account-menu-shadow : 0 10px 28px rgba(20, 30, 28, 0.18); + + --glyph-account: + url('data:image/svg+xml;utf8,'); + --glyph-logout: + url('data:image/svg+xml;utf8,'); } -.AccountSectionLabel +#LoginArea +{ + position: relative; + padding: 10px 8px; + box-sizing: border-box; + width: 262px; + border-bottom: 1px solid var(--account-divider); +} + +.AccountRow { display: flex; align-items: center; gap: 8px; - font-size: 13px; - font-weight: 600; - color: var(--fg-color-text); - padding: 16px 20px 6px; - width: 262px; - box-sizing: border-box; -} - -.AccountSectionIcon -{ - width: 18px; - height: 18px; - flex: 0 0 auto; -} - -.AccountStatusText -{ - font-size: 12px; - color: #A8A8A8; - margin-top: 8px; -} - -.OrcaAccountText -{ - font-weight: bold; -} - -#OrcaLoginSection -{ - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; -} - -#OrcaLogin1 -{ - display: flex; - flex-direction: column; /*ORCA*/ - align-items: center; /*Allow icon centered vertically*/ - justify-content: center; /*and use login button in new line*/ + padding: 8px 10px 8px 14px; /*----label column lines up with the navigation below----*/ + border-radius: 8px; + cursor: pointer; user-select: none; - padding: 10px 0; } -#OrcaLogin2 +.AccountRow:hover +{ + background-color: var(--row-hover); +} + +.AccountRow:focus-visible +{ + outline: 2px solid var(--account-action); + outline-offset: -2px; +} + +.AccountRow.Disabled +{ + cursor: default; + opacity: 0.5; +} + +.AccountRow.Disabled:hover +{ + background-color: transparent; +} + +.AccountRow.Disabled .AccountSignIn { display: none; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - padding: 14px 0 16px; - box-sizing: border-box; - width: 262px; } -/* --- Bambu Cloud Section --- */ +/*----Avatar----*/ +.AccountAvatar +{ + position: relative; + flex: 0 0 auto; + width: 36px; + height: 36px; + border-radius: 50%; + background-color: var(--account-avatar-bg); +} + +.AccountAvatar::before /* placeholder shown until an avatar image loads */ +{ + content: ""; + position: absolute; + inset: 0; + -webkit-mask-image: var(--glyph-account); + mask-image: var(--glyph-account); + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + background-color: var(--account-avatar-glyph); +} + +.AccountAvatarImg +{ + position: absolute; + inset: 0; + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; + display: block; +} + +.AccountAvatarImg:not([src]) +{ + display: none; +} + +/*----Row labels----*/ +.AccountText +{ + display: flex; + flex-direction: column; + justify-content: center; + flex: 1 1 auto; + min-width: 0; +} + +.AccountName, +.AccountSecondary /*----the provider name, or the sign-in state where the row has no name yet----*/ +{ + font-size: 15px; + line-height: 20px; + color: var(--account-name); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.AccountName +{ + display: none; + font-weight: 600; +} + +.AccountSignIn +{ + flex: 0 0 auto; + font-size: 12px; + font-weight: 600; + color: var(--account-action); +} + +.AccountChevron +{ + display: none; + flex: 0 0 auto; + width: 12px; + height: 12px; + color: var(--account-meta); + transition: transform 0.15s ease; +} + +.AccountRow.SignedIn .AccountName { display: block; } +.AccountRow.SignedIn .AccountChevron { display: block; } +.AccountRow.SignedIn .AccountSignIn { display: none; } +.AccountRow.SignedIn .AccountSecondary +{ + font-size: 11px; + line-height: 14px; + color: var(--account-meta); +} + +.AccountRow.MenuOpen .AccountChevron { transform: rotate(180deg); } + +#NoPluginTip +{ + display: none; + margin: 4px 0 2px; + padding: 8px 10px; + border-radius: 6px; + background-color: var(--account-warn-bg); +} + +#NoPluginText +{ + line-height: 16px; +} + +#NoPluginTip .LinkBtn +{ + color: var(--warn-color); + text-decoration: underline; +} + +/*----Bambu Cloud, folded under the main account----*/ #BambuCloudSection { display: none; /* shown by cloud_providers_info from backend */ - border-top: 1px solid; - width: 262px; + margin-top: 8px; + padding-top: 6px; + border-top: 1px solid var(--account-divider); } #BambuCloudHeader { - height: 40px; display: flex; align-items: center; - padding: 0 20px; - cursor: pointer; - font-size: 13px; - color: #A8A8A8; gap: 8px; + height: 28px; + padding: 0 10px 0 14px; + border-radius: 6px; + font-size: 12px; + color: var(--account-meta); + cursor: pointer; + user-select: none; } #BambuCloudHeader:hover { - color: inherit; + color: var(--account-name); } -.bambu-chevron +#BambuCloudHeader:focus-visible { + outline: 2px solid var(--account-action); + outline-offset: -2px; +} + +.SectionChevron +{ + flex: 0 0 auto; width: 12px; height: 12px; transition: transform 0.2s ease; - transform: rotate(0deg); } -.bambu-chevron.expanded +#BambuCloudHeader.Expanded .SectionChevron { transform: rotate(90deg); } -.bambu-status-dot +.SectionLabel { - width: 8px; - height: 8px; - border-radius: 50%; - background-color: #A8A8A8; - margin-left: auto; + flex: 1 1 auto; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } -.bambu-status-dot.online +#BambuStatusDot { - background-color: #4CAF50; + flex: 0 0 auto; + width: 7px; + height: 7px; + border-radius: 50%; + background-color: var(--account-dot-off); +} + +#BambuStatusDot.Online +{ + background-color: var(--account-dot-on); } #BambuCloudBody @@ -208,99 +346,125 @@ body max-height: 0; overflow: hidden; transition: max-height 0.25s ease; - display: flex; - flex-direction: column; - align-items: center; } -#BambuCloudBody.expanded +#BambuCloudBody.Expanded { max-height: 200px; + padding-bottom: 2px; } -#NoPluginTip +.AccountRowCompact { - position: static; - display: none; - flex-direction: column; - padding: 5px 10px; - z-index: auto; + padding: 6px 10px 6px 24px; } -#BambuLogin1 +.AccountRowCompact .AccountAvatar { - padding: 10px 0; + width: 26px; + height: 26px; } -#BambuLogin2 +.AccountRowCompact .AccountName, +.AccountRowCompact .AccountSecondary { - display: none; - flex-direction: column; - align-items: center; - text-align: center; - padding: 8px 0; - width: 262px; -} - -#BambuAvatarIcon -{ - height: 40px; - border-radius: 50%; -} - -#BambuUserName -{ - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - width: 80%; - text-align: center; font-size: 13px; + line-height: 17px; } - -#DownloadBtn +.AccountRowCompact .AccountSecondary { - color:#00ffd9; + color: var(--account-meta); } - -#Icon1 +.AccountRowCompact.SignedIn .AccountSecondary /*----the section header already names this provider----*/ { - margin-right: 10px; + display: none; } -#BBLIcon +/*----Account menu----*/ +#AccountMenu { - height:96px; /*ORCA use bigger icon to fit logo size*/ + display: none; + position: absolute; + left: 8px; + right: 8px; + z-index: 20; + padding: 4px; + border-radius: 10px; + border: 1px solid var(--account-border); + background-color: var(--account-surface); + box-shadow: var(--account-menu-shadow); } -#UserAvatarIcon +#AccountMenu.Open { - width: 64px; - height: 64px; display: block; - margin: 2px auto 10px; - object-fit: cover; - border-radius: 50%; + animation: AccountMenuIn 0.12s ease-out; } -#UserName +@keyframes AccountMenuIn { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: none; } +} + +@media (prefers-reduced-motion: reduce) +{ + #AccountMenu.Open { animation: none; } + .AccountChevron, + .SectionChevron, + #BambuCloudBody { transition: none; } +} + +#AccountMenuHandle +{ + display: none; + padding: 9px 10px; + border-bottom: 1px solid var(--account-border); + font-size: 12px; + line-height: 16px; + color: var(--account-meta); white-space: nowrap; + overflow: hidden; text-overflow: ellipsis; - text-align: center; - overflow: hidden; - width: 80%; - max-width: 190px; - line-height: 22px; } -#LogoutBtn +#AccountMenuLogout { - margin-top: 8px; + display: flex; + align-items: center; + gap: 8px; + height: 34px; + padding: 0 10px; + border-radius: 6px; + font-size: 13px; + color: var(--account-name); + cursor: pointer; } +#AccountMenuLogout:hover +{ + background-color: var(--account-danger-bg); + color: var(--account-danger); +} + +#AccountMenuLogout:focus-visible +{ + outline: 2px solid var(--account-action); + outline-offset: -2px; +} + +#AccountMenuLogoutIcon +{ + width: 15px; + height: 15px; + -webkit-mask: var(--glyph-logout) center / contain no-repeat; + mask: var(--glyph-logout) center / contain no-repeat; + background-color: currentColor; +} + + /*------------------*/ #BtnArea { @@ -320,12 +484,12 @@ body .BtnItem:hover { - background-color: #BFE1DE; /*ORCA color with %25 opacity*/ + background-color: var(--row-hover); } .BtnItemSelected { - background-color: #BFE1DE; /*ORCA color with %25 opacity*/ + background-color: var(--row-hover); } .BtnIcon diff --git a/resources/web/homepage/img/c.jpg b/resources/web/homepage/img/c.jpg deleted file mode 100644 index 50c5883ca05fdf86fb59b6d78ac787b349c99a8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38788 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 diff --git a/resources/web/homepage/index.html b/resources/web/homepage/index.html index 24eb8285a7..bc5f83311b 100644 --- a/resources/web/homepage/index.html +++ b/resources/web/homepage/index.html @@ -23,56 +23,65 @@

- -
- - Orca Cloud -
- -
-
-
-
login / register
-
Not signed in
-
- -
-
- -
-
-
log out
-
-
- - -
-
- - + + -
-
-
login
+ +
diff --git a/resources/web/homepage/js/home.js b/resources/web/homepage/js/home.js index f522c44bed..f07c6f10f5 100644 --- a/resources/web/homepage/js/home.js +++ b/resources/web/homepage/js/home.js @@ -1,7 +1,6 @@ //var TestData={"sequence_id":"0","command":"get_recent_projects","response":[{"path":"D:\\work\\Models\\Toy\\3d-puzzle-cube-model_files\\3d-puzzle-cube.3mf","time":"2022\/3\/24 20:33:10"},{"path":"D:\\work\\Models\\Art\\Carved Stone Vase - remeshed+drainage\\Carved Stone Vase.3mf","time":"2022\/3\/24 17:11:51"},{"path":"D:\\work\\Models\\Art\\Kity & Cat\\Cat.3mf","time":"2022\/3\/24 17:07:55"},{"path":"D:\\work\\Models\\Toy\\鐩村墤.3mf","time":"2022\/3\/24 17:06:02"},{"path":"D:\\work\\Models\\Toy\\minimalistic-dual-tone-whistle-model_files\\minimalistic-dual-tone-whistle.3mf","time":"2022\/3\/22 21:12:22"},{"path":"D:\\work\\Models\\Toy\\spiral-city-model_files\\spiral-city.3mf","time":"2022\/3\/22 18:58:37"},{"path":"D:\\work\\Models\\Toy\\impossible-dovetail-puzzle-box-model_files\\impossible-dovetail-puzzle-box.3mf","time":"2022\/3\/22 20:08:40"}]}; var m_HotModelList=null; -var bambuSectionExpanded = false; function OnInit() { @@ -12,6 +11,8 @@ function OnInit() SendMsg_GetBambuLoginInfo(); SendMsg_GetRecentFile(); SendMsg_GetStaffPick(); + + Set_AccountMenu_Event(); } //------最佳打开文件的右键菜单功能---------- @@ -89,7 +90,7 @@ function HandleStudio( pVal ) if (strCmd == "get_recent_projects") { ShowRecentFileList(pVal["response"]); } else if (strCmd == "orca_userlogin") { - SetOrcaLoginInfo(pVal["data"]["avatar"], pVal["data"]["name"]); + SetOrcaLoginInfo(pVal["data"]["avatar"], pVal["data"]["name"], pVal["data"]["account"]); } else if (strCmd == "orca_useroffline") { SetOrcaUserOffline(); } else if (strCmd == "studio_bambu_userlogin") { @@ -118,21 +119,12 @@ function HandleStudio( pVal ) $("#LeftBoard").hide(); } } else if (strCmd == "network_plugin_installtip") { - let nShow = pVal["show"] * 1; + // Bambu Cloud is unreachable without the network plugin, so its row only carries the tip. + let bMissing = pVal["show"] * 1 == 1; - if (nShow == 1) { - // Auto-expand Bambu section to show the tip - if (!bambuSectionExpanded) ToggleBambuSection(); - $("#BambuLogin1").hide(); - $("#NoPluginTip").show(); - $("#NoPluginTip").css("display", "flex"); - } else { - $("#NoPluginTip").hide(); - // Only restore login button if not already logged in - if ($("#BambuLogin2").is(":hidden")) { - $("#BambuLogin1").show(); - } - } + $("#NoPluginTip").css("display", bMissing ? "block" : "none"); + $("#BambuAccount").toggleClass("Disabled", bMissing).attr("aria-disabled", bMissing ? "true" : null); + if (bMissing) SetBambuSectionExpanded(true, false); } else if (strCmd == "modelmall_model_advise_get") { //alert('hot'); if (m_HotModelList != null) { @@ -170,34 +162,128 @@ function GotoMenu( strMenu ) } } -function SetOrcaLoginInfo( strAvatar, strName ) -{ - $("#OrcaLogin1").hide(); - $("#OrcaStatusText").hide(); +/*------Account rows------*/ - $("#UserName").text(strName); +/*----Everything that differs between the two cloud providers lives here----*/ +var AccountRows = { + orca: { row: "#OrcaAccount", name: "#UserName", avatar: "#UserAvatarIcon", dot: null, + loginCmd: "homepage_orca_login_or_register", logoutCmd: "homepage_orca_logout" }, + bambu: { row: "#BambuAccount", name: "#BambuUserName", avatar: "#BambuAvatarIcon", dot: "#BambuStatusDot", + loginCmd: "homepage_bambu_login_or_register", logoutCmd: "homepage_bambu_logout" } +}; - let OriginAvatar=$("#UserAvatarIcon").prop("src"); - if(strAvatar != null && strAvatar.trim() !== '' && strAvatar!=OriginAvatar) - $("#UserAvatarIcon").prop("src",strAvatar); - else - { - //alert('Avatar is Same'); - } +var BAMBU_FOLD_KEY = "OrcaHome_BambuCloudExpanded"; - $("#OrcaLogin2").show(); - $("#OrcaLogin2").css("display","flex"); +var m_OpenAccountMenu = null; + +function SetAccountAvatar(selector, strAvatar) { + if (strAvatar != null && strAvatar.trim() !== '') { + if ($(selector).attr("src") !== strAvatar) $(selector).attr("src", strAvatar); + } else { + $(selector).removeAttr("src"); + } } -function SetOrcaUserOffline() -{ - $("#UserAvatarIcon").prop("src","img/c.jpg"); - $("#UserName").text(''); - $("#OrcaLogin2").hide(); +function OnAvatarLoadError(img) { + img.removeAttribute("src"); // fall back to the placeholder glyph +} - $("#OrcaLogin1").show(); - $("#OrcaLogin1").css("display","flex"); - $("#OrcaStatusText").show(); +function SetAccountSignedIn(strProvider, strAvatar, strName, strHandle) { + var account = AccountRows[strProvider]; + + $(account.name).text(strName).attr("title", strName); /*----long names are ellipsized----*/ + SetAccountAvatar(account.avatar, strAvatar); + /*----the handle is the one thing the row does not already show----*/ + $(account.row).addClass("SignedIn").data("handle", strHandle !== strName ? strHandle : null); + $(account.dot).addClass("Online"); + + if (m_OpenAccountMenu === strProvider) OpenAccountMenu(strProvider); +} + +function SetAccountSignedOut(strProvider) { + var account = AccountRows[strProvider]; + + if (m_OpenAccountMenu === strProvider) CloseAccountMenu(); + $(account.name).text('').removeAttr("title"); + SetAccountAvatar(account.avatar, null); + $(account.row).removeClass("SignedIn").removeData("handle"); + $(account.dot).removeClass("Online"); +} + +function OnAccountRowClick(strProvider) { + var account = AccountRows[strProvider]; + var row = $(account.row); + if (row.hasClass("Disabled")) return; + + if (!row.hasClass("SignedIn")) { + CloseAccountMenu(); + SendSimpleCommand(account.loginCmd); + } else if (m_OpenAccountMenu === strProvider) { + CloseAccountMenu(); + } else { + OpenAccountMenu(strProvider); + } +} + +function OpenAccountMenu(strProvider) { + var account = AccountRows[strProvider]; + var row = $(account.row); + var top = row[0].offsetTop + row[0].offsetHeight + 6; /*----read the geometry before writing----*/ + var strHandle = row.data("handle") || ""; + + $("#AccountMenuHandle").text(strHandle).css("display", strHandle === "" ? "none" : "block"); + $("#AccountMenu").css("top", top + "px").addClass("Open"); + $(".AccountRow").removeClass("MenuOpen").attr("aria-expanded", "false"); + row.addClass("MenuOpen").attr("aria-expanded", "true"); + m_OpenAccountMenu = strProvider; +} + +function CloseAccountMenu() { + $("#AccountMenu").removeClass("Open"); + $(".AccountRow").removeClass("MenuOpen").attr("aria-expanded", "false"); + m_OpenAccountMenu = null; +} + +function OnAccountMenuLogout() { + var account = AccountRows[m_OpenAccountMenu]; + CloseAccountMenu(); + if (account) SendSimpleCommand(account.logoutCmd); +} + +/*----Bambu Cloud is secondary, so its account folds away under the main one----*/ +function SetBambuSectionExpanded(bExpanded, bPersist) { + $("#BambuCloudBody").toggleClass("Expanded", bExpanded); + $("#BambuAccount").attr("tabindex", bExpanded ? "0" : "-1"); /*----keep the folded row out of the tab order----*/ + $("#BambuCloudHeader").toggleClass("Expanded", bExpanded).attr("aria-expanded", bExpanded ? "true" : "false"); + if (!bExpanded && m_OpenAccountMenu === "bambu") CloseAccountMenu(); + // Best effort: the fold is a per-machine convenience, not a synced preference. + if (bPersist) { try { localStorage.setItem(BAMBU_FOLD_KEY, bExpanded ? "1" : "0"); } catch (e) {} } +} + +function ToggleBambuSection() { + SetBambuSectionExpanded(!$("#BambuCloudBody").hasClass("Expanded"), true); +} + +function Set_AccountMenu_Event() { + var bExpanded = false; + try { bExpanded = localStorage.getItem(BAMBU_FOLD_KEY) === "1"; } catch (e) {} + SetBambuSectionExpanded(bExpanded, false); + + $(document).mousedown(function (e) { + if (m_OpenAccountMenu === null) return; + if ($(e.target).closest("#AccountMenu, .AccountRow").length === 0) CloseAccountMenu(); + }); + + $(document).keydown(function (e) { + if (m_OpenAccountMenu !== null && e.key === "Escape") CloseAccountMenu(); + }); + + /*----Enter and Space activate the div-based buttons of this panel----*/ + $(document).on("keydown", "#LoginArea [role=button], #LoginArea [role=menuitem]", function (e) { + if (e.key !== "Enter" && e.key !== " " && e.key !== "Spacebar") return; + e.preventDefault(); + this.click(); + }); } function SetMallUrl( strUrl ) @@ -279,8 +365,6 @@ function SendSimpleCommand(command) { SendWXMessage(JSON.stringify(tSend)); } -function OnOrcaLoginOrRegister() { SendSimpleCommand("homepage_orca_login_or_register"); } -function OnOrcaLogOut() { SendSimpleCommand("homepage_orca_logout"); } function SendMsg_GetOrcaLoginInfo() { SendSimpleCommand("get_orca_login_info"); } @@ -294,15 +378,6 @@ function SendMsg_GetRecentFile() } -function OnLoginOrRegister() -{ - var tSend={}; - tSend['sequence_id']=Math.round(new Date() / 1000); - tSend['command']="homepage_login_or_register"; - - SendWXMessage( JSON.stringify(tSend) ); -} - function OnClickModelDepot() { var tSend={}; @@ -405,59 +480,13 @@ function OnExploreRecentFile( ) $("#recnet_context_menu").hide(); } -function OnLogOut() -{ - var tSend={}; - tSend['sequence_id']=Math.round(new Date() / 1000); - tSend['command']="homepage_logout"; +// --- Cloud providers --- - SendWXMessage( JSON.stringify(tSend) ); -} +function SetOrcaLoginInfo(strAvatar, strName, strAccount) { SetAccountSignedIn("orca", strAvatar, strName, strAccount); } +function SetOrcaUserOffline() { SetAccountSignedOut("orca"); } +function SetBambuLoginInfo(strAvatar, strName) { SetAccountSignedIn("bambu", strAvatar, strName, null); } +function SetBambuUserOffline() { SetAccountSignedOut("bambu"); } -// --- Bambu Cloud Section --- - -function ToggleBambuSection() { - var body = document.getElementById('BambuCloudBody'); - var chevron = document.querySelector('.bambu-chevron'); - if (!body || !chevron) return; - bambuSectionExpanded = !bambuSectionExpanded; - if (bambuSectionExpanded) { - body.classList.add('expanded'); - chevron.classList.add('expanded'); - } else { - body.classList.remove('expanded'); - chevron.classList.remove('expanded'); - } -} - -function SetBambuLoginInfo(strAvatar, strName) { - $("#BambuLogin1").hide(); - $("#BambuUserName").text(strName); - if (strAvatar && strAvatar.trim() !== '') { - $("#BambuAvatarIcon").prop("src", strAvatar); - } - $("#BambuLogin2").show(); - $("#BambuLogin2").css("display", "flex"); - $(".bambu-status-dot").addClass("online"); - $("#BambuStatusText").text("Connected"); - $("#BambuStatusText").attr("tid", "orca11"); -} - -function SetBambuUserOffline() { - $("#BambuAvatarIcon").prop("src", "img/c.jpg"); - $("#BambuUserName").text(''); - $("#BambuLogin2").hide(); - if ($("#NoPluginTip").is(":hidden")) { - $("#BambuLogin1").show(); - $("#BambuLogin1").css("display", "flex"); - } - $(".bambu-status-dot").removeClass("online"); - $("#BambuStatusText").text("Not connected"); - $("#BambuStatusText").attr("tid", "orca10"); -} - -function OnBambuLoginOrRegister() { SendSimpleCommand("homepage_bambu_login_or_register"); } -function OnBambuLogOut() { SendSimpleCommand("homepage_bambu_logout"); } function SendMsg_GetBambuLoginInfo() { SendSimpleCommand("get_bambu_login_info"); } function BeginDownloadNetworkPlugin() diff --git a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp index 4419395b4d..4bfe429cd3 100644 --- a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp +++ b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp @@ -859,9 +859,11 @@ std::string OrcaCloudServiceAgent::build_login_cmd() display_name = "unknown name"; } json cmd; - cmd["command"] = "orca_userlogin"; - cmd["data"]["name"] = display_name; - cmd["data"]["avatar"] = get_user_avatar(); + cmd["command"] = "orca_userlogin"; + cmd["data"]["name"] = display_name; + cmd["data"]["avatar"] = get_user_avatar(); + // The unique handle, shown under the display name in the homepage account menu. + cmd["data"]["account"] = get_user_name(); return cmd.dump(); }