-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System; | ||
using UnityEngine; | ||
|
||
namespace ClusterVR.CreatorKit.Editor.Api.ExternalCall | ||
{ | ||
[Serializable] | ||
public sealed class GetWebRPCURLResponse | ||
{ | ||
[SerializeField] string url; | ||
|
||
public string Url => url; | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System; | ||
using UnityEngine; | ||
|
||
namespace ClusterVR.CreatorKit.Editor.Api.ExternalCall | ||
{ | ||
[Serializable] | ||
public sealed class RegisterWebRPCURLPayload | ||
{ | ||
[SerializeField] string url; | ||
|
||
public RegisterWebRPCURLPayload(string url) | ||
{ | ||
this.url = url; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using UnityEngine; | ||
|
||
namespace ClusterVR.CreatorKit.Editor.Api.ExternalCall | ||
{ | ||
[Serializable] | ||
public class RegisterWebRPCURLResponse | ||
{ | ||
[SerializeField] string url; | ||
[SerializeField] string verifyToken; | ||
|
||
public string Url => url; | ||
public string VerifyToken => verifyToken; | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="/UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> | ||
<ui:VisualElement name="base-container"> | ||
<ui:VisualElement name="url-view"> | ||
<ui:Label name="current-url-title-label" text="登録中のURL" style="-unity-font-style: bold;" /> | ||
<ui:Label name="current-url-label" /> | ||
<ui:VisualElement style="height: 20px;" /> | ||
<ui:Label name="update-url-title-label" text="URLの登録" style="-unity-font-style: bold;" /> | ||
<ui:TextField name="update-url-field" /> | ||
<ui:Button name="update-button" text="登録" /> | ||
<ui:Button name="delete-button" text="削除" /> | ||
</ui:VisualElement> | ||
<ui:VisualElement style="height: 20px;" /> | ||
<ui:VisualElement name="token-view"> | ||
<ui:Label text="verify用トークン" style="-unity-font-style: bold;" /> | ||
<ui:TextField name="token-field" readonly="true" /> | ||
<ui:Label text="* このトークンは一度しか表示されません。紛失した場合は URL を登録し直して下さい。" style="white-space: normal;" /> | ||
</ui:VisualElement> | ||
</ui:VisualElement> | ||
</ui:UXML> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ClusterVR.CreatorKit.Editor.Api.ExternalCall; | ||
using ClusterVR.CreatorKit.Editor.Api.RPC; | ||
using ClusterVR.CreatorKit.Editor.Api.User; | ||
using UnityEditor; | ||
using UnityEngine; | ||
using UnityEngine.UIElements; | ||
|
||
namespace ClusterVR.CreatorKit.Editor.Window.View | ||
{ | ||
public sealed class ExternalCallUrlView : IRequireTokenAuthMainView, IDisposable | ||
{ | ||
const string MainTemplatePath = "Packages/mu.cluster.cluster-creator-kit/Editor/Window/Uxml/ExternalCallUrlView.uxml"; | ||
|
||
UserInfo userInfo; | ||
Label currentUrlLabel; | ||
TextField updateUrlTextField; | ||
Button updateButton; | ||
Button deleteButton; | ||
VisualElement tokenView; | ||
TextField tokenField; | ||
readonly CancellationTokenSource cancellationTokenSource = new(); | ||
|
||
public VisualElement LoginAndCreateView(UserInfo userInfo) | ||
{ | ||
this.userInfo = userInfo; | ||
|
||
var mainView = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(MainTemplatePath).CloneTree(); | ||
currentUrlLabel = mainView.Q<Label>("current-url-label"); | ||
updateUrlTextField = mainView.Q<TextField>("update-url-field"); | ||
|
||
updateButton = mainView.Q<Button>("update-button"); | ||
deleteButton = mainView.Q<Button>("delete-button"); | ||
|
||
tokenView = mainView.Q<VisualElement>("token-view"); | ||
tokenField = mainView.Q<TextField>("token-field"); | ||
|
||
updateButton.clicked += OnUpdateClicked; | ||
deleteButton.clicked += OnDeleteClicked; | ||
|
||
_ = InitializeAsync(cancellationTokenSource.Token); | ||
return mainView; | ||
} | ||
|
||
void OnUpdateClicked() | ||
{ | ||
if (EditorUtility.DisplayDialog("確認", "URLを更新しますか?", "OK", "キャンセル")) | ||
{ | ||
_ = UpdateWebRPCUrlAsync(cancellationTokenSource.Token); | ||
} | ||
} | ||
|
||
void OnDeleteClicked() | ||
{ | ||
if (EditorUtility.DisplayDialog("確認", "URLを削除しますか?", "OK", "キャンセル")) | ||
{ | ||
_ = DeleteWebRPCUrlAsync(cancellationTokenSource.Token); | ||
} | ||
} | ||
|
||
async Task InitializeAsync(CancellationToken cancellationToken) | ||
{ | ||
tokenView.visible = false; | ||
var currentUrl = await GetWebRPCUrlAsync(cancellationToken); | ||
SetCurrentURL(currentUrl); | ||
} | ||
|
||
void SetCurrentURL(string url) | ||
{ | ||
if (string.IsNullOrEmpty(url)) | ||
{ | ||
currentUrlLabel.text = "未登録"; | ||
deleteButton.SetEnabled(false); | ||
} | ||
else | ||
{ | ||
currentUrlLabel.text = url; | ||
deleteButton.SetEnabled(true); | ||
} | ||
} | ||
|
||
async Task<string> GetWebRPCUrlAsync(CancellationToken cancellationToken) | ||
{ | ||
try | ||
{ | ||
var res = await APIServiceClient.GetWebRPCURLAsync(userInfo.VerifiedToken, cancellationToken); | ||
return res.Url; | ||
} | ||
catch (Failure e) when (e.StatusCode == 404) | ||
{ | ||
return null; | ||
} | ||
catch (Exception e) when (e is not OperationCanceledException) | ||
{ | ||
Debug.LogException(e); | ||
throw; | ||
} | ||
} | ||
|
||
async Task UpdateWebRPCUrlAsync(CancellationToken cancellationToken) | ||
{ | ||
var url = updateUrlTextField.value; | ||
if (string.IsNullOrEmpty(url)) return; | ||
|
||
try | ||
{ | ||
var res = await APIServiceClient.RegisterWebRPCURLAsync(new RegisterWebRPCURLPayload(url), userInfo.VerifiedToken, cancellationToken); | ||
SetCurrentURL(res.Url); | ||
tokenView.visible = true; | ||
tokenField.value = res.VerifyToken; | ||
} | ||
catch (Failure e) when (e.StatusCode == 400) | ||
{ | ||
EditorUtility.DisplayDialog("エラー", e.Error.Detail, "OK"); | ||
throw; | ||
} | ||
catch (Exception e) when (e is not OperationCanceledException) | ||
{ | ||
Debug.LogException(e); | ||
throw; | ||
} | ||
} | ||
|
||
async Task DeleteWebRPCUrlAsync(CancellationToken cancellationToken) | ||
{ | ||
try | ||
{ | ||
await APIServiceClient.DeleteUserWebRPCURLAsync(userInfo.VerifiedToken, cancellationToken); | ||
SetCurrentURL(null); | ||
tokenView.visible = false; | ||
tokenField.value = null; | ||
} | ||
catch (Exception e) when (e is not OperationCanceledException) | ||
{ | ||
Debug.LogException(e); | ||
throw; | ||
} | ||
} | ||
|
||
public void Logout() | ||
{ | ||
SetCurrentURL(null); | ||
tokenField.visible = false; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
cancellationTokenSource.Cancel(); | ||
cancellationTokenSource.Dispose(); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using UnityEditor; | ||
using UnityEngine; | ||
using UnityEngine.UIElements; | ||
|
||
namespace ClusterVR.CreatorKit.Editor.Window.View | ||
{ | ||
public sealed class ExternalCallUrlWindow : EditorWindow | ||
{ | ||
readonly ExternalCallUrlView externalCallUrlView = new(); | ||
RequireTokenAuthView tokenAuthView; | ||
|
||
[MenuItem("Cluster/外部通信(callExternal)接続先URL", priority = 305)] | ||
public static void Open() | ||
{ | ||
var window = GetWindow<ExternalCallUrlWindow>(); | ||
window.titleContent = new GUIContent("外部通信(callExternal)接続先URL"); | ||
} | ||
|
||
void OnEnable() | ||
{ | ||
var view = CreateView(); | ||
rootVisualElement.Add(view); | ||
} | ||
|
||
void OnDisable() | ||
{ | ||
rootVisualElement.Clear(); | ||
if (tokenAuthView != null) | ||
{ | ||
tokenAuthView.Dispose(); | ||
tokenAuthView = null; | ||
} | ||
} | ||
|
||
void OnDestroy() | ||
{ | ||
externalCallUrlView.Dispose(); | ||
} | ||
|
||
VisualElement CreateView() | ||
{ | ||
tokenAuthView = new RequireTokenAuthView(externalCallUrlView); | ||
var authView = tokenAuthView.CreateView(); | ||
authView.SetEnabled(true); | ||
|
||
return authView; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.