Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,16 @@ static void OnGUI(IMGUIContainer container)
try
{
var badgeColor = new Color(0,0,0,.3f);
if (_editorAPI?.BeamCli.CurrentRealm?.IsProduction ?? false)
if (!_editorAPI?.BeamCli?.IsLoggedOut ?? true)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, I lowkey hate this syntax. I suppose it is necessary because the value of _editorAPI?.BeamCli?.IsLoggedOut ends up being null if any of the question-marked ones is null?

No need to change it, just grumping about C# syntax.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🫂

{
badgeColor = new Color(1, 0, 0, .5f);
}
else if (_editorAPI?.BeamCli.CurrentRealm?.IsStaging ?? false)
{
badgeColor = new Color(1, .5f, 0, .5f);
if (_editorAPI?.BeamCli.CurrentRealm?.IsProduction ?? false)
{
badgeColor = new Color(1, 0, 0, .5f);
}
else if (_editorAPI?.BeamCli.CurrentRealm?.IsStaging ?? false)
{
badgeColor = new Color(1, .5f, 0, .5f);
}
}

var realmDisplay = _editorAPI?.BeamCli.CurrentRealm?.DisplayName ?? "<no realm>";
Expand All @@ -107,11 +110,11 @@ static void OnGUI(IMGUIContainer container)
versionDisplay = "nightly";
}

var loggedOutText = _editorAPI?.BeamCli?.IsLoggedOut ?? false
? "[Logged out] "
: "";
var titleBaseText = _editorAPI?.BeamCli?.IsLoggedOut ?? false
? "[Logged out]"
: realmDisplay;

var titleContent = new GUIContent(loggedOutText + realmDisplay + " (" + versionDisplay + ")");
var titleContent = new GUIContent(titleBaseText + " (" + versionDisplay + ")");

GUI.enabled = _editorAPI != null;
var didClick = GUILayout.Button(titleContent, new GUIStyle(EditorStyles.toolbarButton)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ public enum Env
envMap[Env.Custom],
};

[Serializable]
public class SavedCredentials
{
public string CidOrAlias;
public string Email;
}

[Serializable]
class SavedCredentialsArray
{
public SavedCredentials[] items;
}

public string GetHostString()
{
switch (env)
Expand All @@ -55,6 +68,30 @@ public string GetHostString()
}
}

List<SavedCredentials> EditorSavedCredentials
{
get
{
try
{
var savedValue = EditorUserSettings.GetConfigValue("Beamable.SavedCredentials");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have "Beamable.SavedCredentials" as a const string variable.

return JsonUtility.FromJson<SavedCredentialsArray>(
string.IsNullOrWhiteSpace(savedValue) ? "{}" : savedValue).items.ToList();
}
catch
{
return new List<SavedCredentials>();
}
}
set
{
var vv = JsonUtility.ToJson(new SavedCredentialsArray{items = value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not thrilled about vv as a variable name; I suppose its only use is right next to it, so it is not actually all that unclear, and value is a keyword. Were it my code, I would likely name it credsValue or something. Verbosity in hopes of clarity.

No real need to change, just a statement of code style preference: I would rather see longer, more descriptive variable names.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIxed

.GroupBy(c => (c.CidOrAlias, c.Email))
.Select(g => g.First()).ToArray()});
EditorUserSettings.SetConfigValue("Beamable.SavedCredentials", vv);
}
}

public string GetPortalUriString()
{
switch (env)
Expand All @@ -80,7 +117,7 @@ public string GetPortalUriString()
private GUIStyle _textboxStyle;
private GUIStyle _textboxPlaceholderStyle;
private GUIStyle _placeholderStyle;

public void Draw_SignIn()
{
EditorGUILayout.BeginVertical(new GUIStyle
Expand Down Expand Up @@ -181,8 +218,16 @@ public void Draw_SignIn()
}

rect = GUILayoutUtility.GetRect(GUIContent.none, _textboxStyle);
cidOrAlias = BeamGUI.PlaceholderTextField(rect, cidOrAlias, "Enter Organization Alias", _textboxStyle, _placeholderStyle);

cidOrAlias = BeamGUI.DropdownTextField(rect, cidOrAlias, "Enter Organization Alias", EditorSavedCredentials.Select(cred => $"{cred.CidOrAlias} - {cred.Email}").ToArray(),
newValue =>
{
var splited = newValue.Split(" - ");
EditorGUIUtility.editingTextField = false;
cidOrAlias = splited[0];
email = splited[1];
password = string.Empty;
}, _textboxStyle, _placeholderStyle);

// EditorGUILayout.Space(2);

var clickedCreateOrg = BeamGUI.SoftRightLinkButton(new GUIContent("Create a new organization"));
Expand Down Expand Up @@ -267,6 +312,9 @@ public void Draw_SignIn()
_loginPromise = context.Login(GetHostString(), cidOrAlias, email, password);
_loginPromise.Then(_ =>
{
var saved = EditorSavedCredentials;
saved.Add(new SavedCredentials{CidOrAlias = cidOrAlias, Email = email});
EditorSavedCredentials = saved;
if (cli.latestGames?.VisibleGames.Length > 1) // if there is only one game, there is no reason to make a selection
{
needsGameSelection = true;
Expand All @@ -291,7 +339,6 @@ public void Draw_SignIn()
}

EditorGUILayout.EndVertical();

}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
Expand All @@ -7,9 +9,12 @@ namespace Beamable.Editor.Util
public partial class BeamGUI
{
private static GUIStyle placeholderStyle;


public static string PlaceholderPasswordField(Rect rect, string text, string placeholder, GUIStyle styles, GUIStyle labelStyle=null)

public static string PlaceholderPasswordField(Rect rect,
string text,
string placeholder,
GUIStyle styles,
GUIStyle labelStyle = null)
{
var topRect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
var nextText = EditorGUI.PasswordField(rect, text, styles);
Expand All @@ -22,17 +27,23 @@ public static string PlaceholderPasswordField(Rect rect, string text, string pla
padding = new RectOffset(4, 0, 0, 0),
normal = new GUIStyleState
{
textColor = Color.Lerp(EditorStyles.label.normal.textColor, new Color(1, 1, 1, 0f), .5f)
textColor = Color.Lerp(EditorStyles.label.normal.textColor, new Color(1, 1, 1, 0f),
.5f)
}
};
}

EditorGUI.LabelField(topRect, placeholder, labelStyle ?? placeholderStyle);
}

return nextText;
}

public static string PlaceholderTextField(Rect rect, string text, string placeholder, GUIStyle styles, GUIStyle labelStyle=null)

public static string PlaceholderTextField(Rect rect,
string text,
string placeholder,
GUIStyle styles,
GUIStyle labelStyle = null)
{
var topRect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
var nextText = EditorGUI.TextField(rect, text, styles);
Expand All @@ -45,17 +56,103 @@ public static string PlaceholderTextField(Rect rect, string text, string placeho
padding = new RectOffset(4, 0, 0, 0),
normal = new GUIStyleState
{
textColor = Color.Lerp(EditorStyles.label.normal.textColor, new Color(1, 1, 1, 0f), .5f)
textColor = Color.Lerp(EditorStyles.label.normal.textColor, new Color(1, 1, 1, 0f),
.5f)
}
};
}

EditorGUI.LabelField(topRect, placeholder, labelStyle ?? placeholderStyle);
}

return nextText;
}

public static string LayoutPlaceholderTextField(string text, string placeholder, GUIStyle styles, params GUILayoutOption[] options)
/// <summary>
/// Event-based overload. Subscribe to <paramref name="onOptionSelected"/>
/// to receive the value the user picks from the dropdown.
/// The return value reflects live typing only.
/// </summary>
public static string DropdownTextField(
Rect rect,
string text,
string placeholder,
string[] options,
System.Action<string> onOptionSelected,
GUIStyle fieldStyle = null,
GUIStyle labelStyle = null)
{
fieldStyle ??= EditorStyles.textField;

const float buttonWidth = 25f;
const float spacing = 2f;

var fieldWidth = options != null && options.Length > 0 ? rect.width - buttonWidth - spacing : rect.width;
var fieldRect = new Rect(rect.x, rect.y, fieldWidth, rect.height);
var buttonRect = new Rect(fieldRect.xMax + spacing, rect.y, buttonWidth, EditorGUIUtility.singleLineHeight);

// ── Text field ──────────────────────────────────────────────────
var nextText = EditorGUI.TextField(fieldRect, text, fieldStyle);

// ── Placeholder ─────────────────────────────────────────────────
if (string.IsNullOrEmpty(text))
{
if (placeholderStyle == null)
{
placeholderStyle = new GUIStyle(EditorStyles.label)
{
padding = new RectOffset(4, 0, 0, 0),
normal = new GUIStyleState
{
textColor = Color.Lerp(
EditorStyles.label.normal.textColor,
new Color(1, 1, 1, 0f),
0.5f)
}
};
}

var placeholderRect = new Rect(fieldRect.x, fieldRect.y, fieldRect.width, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(placeholderRect, placeholder, labelStyle ?? placeholderStyle);
}

var buttonStyle = EditorStyles.miniButton;
buttonStyle.stretchHeight = true;
buttonStyle.fixedHeight = rect.height;
// ── Dropdown button ─────────────────────────────────────────────
if (options != null && options.Length > 0 && GUI.Button(buttonRect, "▼", buttonStyle))
{
var menuContent = new GUIContent[options.Length];
var selected = -1;

for (int i = 0; i < options.Length; i++)
{
menuContent[i] = new GUIContent(options[i]);
if (options[i] == text)
{
selected = i;
}
}

EditorUtility.DisplayCustomMenu(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if possible, I would vote we re-use the existing beam editor dropdown window stuff we use in other parts of the editor; rather than use the right-click visual style. I think we could control the UI a little better to even group accounts by their alias and such.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went this way because the IMGUI with dropdown had issues with depth sorting, but I am open for other approach, more consistent with the rest of the UI

new Rect(buttonRect.x, buttonRect.yMax, 0, 0),
menuContent,
selected,
(userData, opts, index) =>
{
var callback = (System.Action<string>)userData;
callback?.Invoke(opts[index]);
},
onOptionSelected,
false);
}

return nextText;
}

public static string LayoutPlaceholderTextField(string text,
string placeholder,
GUIStyle styles,
params GUILayoutOption[] options)
{
var rect = GUILayoutUtility.GetRect(new GUIContent(text), styles, options);
return PlaceholderTextField(rect, text, placeholder, styles);
Expand Down
Loading