Sign in to T5DE's hub from Settings
Settings > T5DE gets a T5DE Hub section to sign in (showing the code and opening the hub's page) or out, through T5DE's proxy, which keeps the sign-in. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
959a454007
commit
1a2c85126e
2 files changed
+166
-1
No files matched your search
@@ -89,7 +89,11 @@ modern stack.
|
||||
The proxy also serves community products from local packs (`%APPDATA%\T5DE\packs`, `T5DE_PACKS`; t5de-proxy's
|
||||
README, t5de-api's `docs/pack.md`); the client needs no patch for it. To test one: `drive.py url
|
||||
"imvu:PutOn?productId=<local ID>"` (local IDs from 2,000,000,000, in `%APPDATA%\T5DE\proxy\products.json`), and
|
||||
Dress Up for outfit saves.
|
||||
Dress Up for outfit saves. The proxy also gets T5 products from the hub's catalogs into the person's library
|
||||
and the client's inventory, and answers `http://t5de-proxy.local/` (its own control address, needing its token):
|
||||
the `t5de-hub` patch's Settings > T5DE > T5DE Hub section signs in and out through it
|
||||
(`SettingsGeckoListener.handle_t5deHub`). `t5de build` installs the pinned proxy; to test an unreleased one, copy
|
||||
t5de-proxy's `dist/t5de-proxy.exe` into `build/IMVUClient/` after building.
|
||||
|
||||
## Verified facts (client 554.8)
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: dhkatz <[email protected]>
|
||||
Date: Thu, 29 Oct 2026 19:20:16 -0700
|
||||
Subject: [PATCH] Sign in to T5DE's hub from Settings
|
||||
|
||||
Settings > T5DE gets a T5DE Hub section: sign in (it shows a code and opens the hub's page for it in the
|
||||
browser) or out, and who's signed in. T5DE's proxy keeps the sign-in and answers the page at
|
||||
http://t5de-proxy.local/; signing in or out takes effect at once.
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
||||
T5de-Id: t5de-hub
|
||||
T5de-Name: T5DE Hub
|
||||
T5de-Group: general
|
||||
T5de-Depends: t5de-proxy, t5de-renderer
|
||||
---
|
||||
imvuContent/settings/index.html | 12 ++++++++
|
||||
imvuContent/settings/style.css | 9 ++++++
|
||||
imvuContent/settings/t5de-hub.js | 47 +++++++++++++++++++++++++++++++
|
||||
library/imvu/mode/SettingsMode.py | 20 +++++++++++++
|
||||
4 files changed, 88 insertions(+)
|
||||
create mode 100644 imvuContent/settings/t5de-hub.js
|
||||
|
||||
diff --git a/imvuContent/settings/index.html b/imvuContent/settings/index.html
|
||||
index 72afd50a1c2ac86ced5d3df19db690df0e82bad4..045ac3e815fcc62e987b119003f7009d7c680ed0 100644
|
||||
--- a/imvuContent/settings/index.html
|
||||
+++ b/imvuContent/settings/index.html
|
||||
@@ -29,6 +29,7 @@
|
||||
<script src="BlockActionSettings.js"></script>
|
||||
<script src="t5de.js"></script>
|
||||
<script src="t5de-graphics.js"></script>
|
||||
+ <script src="t5de-hub.js"></script>
|
||||
|
||||
<script src="../widgets/button/imvuButton.js"></script>
|
||||
</head><body class="yui-skin-sam">
|
||||
@@ -121,6 +122,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="page" imvu:page="t5de" id="t5de-page">
|
||||
+ <div class="subsection" id="t5de-hub">
|
||||
+ <h1>T5DE Hub</h1>
|
||||
+ <div id="t5de-hub-status"> </div>
|
||||
+ <div id="t5de-hub-code" class="hidden"></div>
|
||||
+ <div class="t5de-hub-buttons">
|
||||
+ <button id="t5de-hub-signin">Sign In</button>
|
||||
+ <button id="t5de-hub-signout" class="hidden">Sign Out</button>
|
||||
+ </div>
|
||||
+ <div class="info t5de-info">Your T5DE account: community products, your library, and who's online.</div>
|
||||
+ </div>
|
||||
<div class="subsection" id="t5de-graphics">
|
||||
<h1>Graphics</h1>
|
||||
<div><span class="choice_desc">Frame Rate</span>
|
||||
@@ -249,6 +260,7 @@
|
||||
var tb = new ToolBar(imvu.call);
|
||||
t5deSettings(imvu);
|
||||
t5deGraphicsSettings(imvu);
|
||||
+ t5deHubSettings(imvu);
|
||||
}
|
||||
</script>
|
||||
</body></html>
|
||||
\ No newline at end of file
|
||||
diff --git a/imvuContent/settings/style.css b/imvuContent/settings/style.css
|
||||
index 76187e882716ca5bcccf71952ba8657a739495c0..c846b5ef0772ff8b8fb5e1643bc45b55285bb984 100644
|
||||
--- a/imvuContent/settings/style.css
|
||||
+++ b/imvuContent/settings/style.css
|
||||
@@ -480,3 +480,12 @@ ul li {
|
||||
.t5de-info {
|
||||
margin-top: 10px;
|
||||
}
|
||||
+#t5de-hub-code {
|
||||
+ margin-top: 6px;
|
||||
+ font-size: 16px;
|
||||
+ font-weight: bold;
|
||||
+ letter-spacing: 2px;
|
||||
+}
|
||||
+.t5de-hub-buttons {
|
||||
+ margin-top: 8px;
|
||||
+}
|
||||
diff --git a/imvuContent/settings/t5de-hub.js b/imvuContent/settings/t5de-hub.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2cb97c2d76e8429a3cd36372a34e28324a731137
|
||||
--- /dev/null
|
||||
+++ b/imvuContent/settings/t5de-hub.js
|
||||
@@ -0,0 +1,47 @@
|
||||
+// Signing in to T5DE's hub (the T5DE Hub patch), through T5DE's proxy, which keeps the sign-in
|
||||
+// (SettingsMode.py: handle_t5deHub). Signing in opens the hub's page in the browser for the code shown here.
|
||||
+function t5deHubSettings(imvu) {
|
||||
+ var status = document.getElementById('t5de-hub-status');
|
||||
+ var code = document.getElementById('t5de-hub-code');
|
||||
+ var signin = document.getElementById('t5de-hub-signin');
|
||||
+ var signout = document.getElementById('t5de-hub-signout');
|
||||
+ var timer = null;
|
||||
+
|
||||
+ function call(action) {
|
||||
+ try {
|
||||
+ return JSON.parse(imvu.call('t5deHub', action));
|
||||
+ } catch (e) {
|
||||
+ return {error: 'proxy'};
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ function show(s) {
|
||||
+ $(code).addClass('hidden');
|
||||
+ $(signin).toggleClass('hidden', !!s.signedIn);
|
||||
+ $(signout).toggleClass('hidden', !s.signedIn);
|
||||
+ if (s.error === 'proxy') {
|
||||
+ status.textContent = "T5DE's proxy isn't running.";
|
||||
+ $(signin).addClass('hidden');
|
||||
+ } else if (s.signedIn) {
|
||||
+ status.textContent = s.username ? 'Signed in as ' + s.username + '.' : 'Signed in.';
|
||||
+ } else if (s.signingIn) {
|
||||
+ status.textContent = s.code ? 'Enter this code on the page that opened:' : 'Getting a code...';
|
||||
+ if (s.code) {
|
||||
+ code.textContent = s.code.slice(0, 4) + '-' + s.code.slice(4);
|
||||
+ $(code).removeClass('hidden');
|
||||
+ }
|
||||
+ } else if (s.error) {
|
||||
+ status.textContent = "Couldn't sign in: " + s.error;
|
||||
+ } else {
|
||||
+ status.textContent = 'Not signed in.';
|
||||
+ }
|
||||
+ clearTimeout(timer);
|
||||
+ if (s.signingIn || (s.signedIn && !s.username)) {
|
||||
+ timer = setTimeout(function () { show(call('status')); }, 1500);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ signin.addEventListener('click', function () { show(call('signin')); }, false);
|
||||
+ signout.addEventListener('click', function () { show(call('signout')); }, false);
|
||||
+ show(call('status'));
|
||||
+}
|
||||
diff --git a/library/imvu/mode/SettingsMode.py b/library/imvu/mode/SettingsMode.py
|
||||
index 69a1ca1d6ca6ca2818c3d96cdd11c63939243c9f..27ef0499f542c9f7e558d94fcc82b34fdb98f185 100644
|
||||
--- a/library/imvu/mode/SettingsMode.py
|
||||
+++ b/library/imvu/mode/SettingsMode.py
|
||||
@@ -65,6 +65,26 @@ class SettingsGeckoListener(object):
|
||||
_winreg.SetValueEx(key, 'FrameRate', 0, _winreg.REG_DWORD, int(rate))
|
||||
finally:
|
||||
key.Close()
|
||||
+
|
||||
+ def handle_t5deHub(self, context, action):
|
||||
+ """T5DE's hub sign-in, kept by T5DE's proxy, which answers at http://t5de-proxy.local/: action 'status',
|
||||
+ 'signin' or 'signout'. The proxy's answer as JSON text, or {"error": "proxy"} if it isn't running."""
|
||||
+ import httplib, json
|
||||
+ from main.client import t5deProxy, t5deProxyAuthorization
|
||||
+ proxy = t5deProxy()
|
||||
+ if proxy is None:
|
||||
+ return json.dumps({'error': 'proxy'})
|
||||
+ host, port, token = proxy
|
||||
+ method, path = {'status': ('GET', '/hub'), 'signin': ('POST', '/hub/signin'), 'signout': ('POST', '/hub/signout')}[action]
|
||||
+ conn = httplib.HTTPConnection(host, port, timeout=10)
|
||||
+ try:
|
||||
+ conn.request(method, 'http://t5de-proxy.local' + path, '', {'Proxy-Authorization': t5deProxyAuthorization(token)})
|
||||
+ response = conn.getresponse()
|
||||
+ return response.read() if response.status == 200 else json.dumps({'error': 'proxy'})
|
||||
+ except Exception:
|
||||
+ return json.dumps({'error': 'proxy'})
|
||||
+ finally:
|
||||
+ conn.close()
|
||||
def handle_registerSettingsListeners(self, context, prefList):
|
||||
for pref in prefList:
|
||||
self.__serviceProvider.eventBus.register(self.__serviceProvider.prefService, 'PrefChanged-%s' % (pref,), self.__prefListener)
|
||||
Reference in new issue
Block a user