Skip to content

Commit

Permalink
Merge pull request #6169 from decentraland/feat/cr-allow-opt-out-for-…
Browse files Browse the repository at this point in the history
…vrm-export

feat: cr allow opt out for vrm export
  • Loading branch information
AlejandroAlvarezMelucciDCL committed Apr 19, 2024
2 parents 9d51a6e + 2683635 commit 481ffa9
Show file tree
Hide file tree
Showing 20 changed files with 2,747 additions and 318 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public static string GetShortenedUrn(string urnReceived)
{
int lastIndex = urnReceived.LastIndexOf(':');

return lastIndex != -1 && urnReceived.Split(':').Length > QUANTITY_OF_PARTS_ON_SHORTENED_ITEMS_URN
return lastIndex != -1 && IsExtendedUrn(urnReceived)
? urnReceived.Substring(0, lastIndex)
: urnReceived;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public WearableItem.Representation ToWearableRepresentation(string contentUrl, D
public string[] hides;
public string[] tags;
public Representation[] representations;
public bool blockVrmExport;

public WearableItem.Data ToWearableData(string contentUrl, Dictionary<string, string> hashes)
{
Expand All @@ -81,6 +82,7 @@ public WearableItem.Data ToWearableData(string contentUrl, Dictionary<string, st

// TODO: builder api does not include this information
removesDefaultHiding = Array.Empty<string>(),
blockVrmExport = blockVrmExport,
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public class DataDto
public string[] replaces;
public string[] hides;
public string[] removesDefaultHiding;
public bool blockVrmExport;
}

public DataDto data;
Expand Down Expand Up @@ -120,6 +121,7 @@ public WearableItem ToWearableItem(string contentBaseUrl, string bundlesBaseUrl,
replaces = metadata.data.replaces,
tags = metadata.data.tags,
removesDefaultHiding = metadata.data.removesDefaultHiding,
blockVrmExport = metadata.data.blockVrmExport,
},
baseUrl = contentBaseUrl,
baseUrlBundles = bundlesBaseUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ namespace DCL.Backpack
public class BackpackEditorHUDController
{
private const string NEW_TOS_AND_EMAIL_SUBSCRIPTION_FF = "new_terms_of_service_and_email_subscription";
private const string EMOTE_ID = "wave";
private const string NOT_LOADED = "NOT_LOADED";

private readonly IBackpackEditorHUDView view;
private readonly DataStore dataStore;
Expand Down Expand Up @@ -54,6 +56,8 @@ public class BackpackEditorHUDController
{WearableLiterals.Categories.EYES, "urn:decentraland:off-chain:base-avatars:eyes_00"},
}}
};
private readonly BackpackEditorHUDModel model = new ();
private readonly HashSet<string> vrmBlockingWearablesList;

private string currentSlotSelected;
private bool avatarIsDirty;
Expand All @@ -70,10 +74,10 @@ public class BackpackEditorHUDController

private UserProfile ownUserProfile => userProfileBridge.GetOwn();

private readonly BackpackEditorHUDModel model = new ();

private int currentAnimationIndexShown;
private bool shouldRequestOutfits = true;

private bool vrmWarningEnabled;
private CancellationTokenSource vrmExportCts;

public BackpackEditorHUDController(
Expand Down Expand Up @@ -140,9 +144,13 @@ public BackpackEditorHUDController(

view.SetOutfitsEnabled(dataStore.featureFlags.flags.Get().IsFeatureEnabled("outfits"));
SetVisibility(dataStore.HUDs.avatarEditorVisible.Get(), saveAvatar: false);
view.SetVRMButtonActive(this.dataStore.featureFlags.flags.Get().IsFeatureEnabled("vrm_export"));
view.SetVRMButtonEnabled(true);
bool vrmFeatureEnabled = this.dataStore.featureFlags.flags.Get().IsFeatureEnabled("vrm_export");
view.SetVRMButtonActive(vrmFeatureEnabled);
view.SetVRMButtonEnabled(vrmFeatureEnabled);
view.SetVRMSuccessToastActive(false);

vrmBlockingWearablesList = new ();
UpdateVRMExportWarning();
}

private void OnOutfitEquipped(OutfitItem outfit)
Expand All @@ -169,7 +177,7 @@ private async UniTaskVoid LoadAndEquipOutfitWearables(OutfitItem outfit, Cancell
if (wearablesCatalogService.WearablesCatalog.ContainsKey(ExtendedUrnParser.GetShortenedUrn(outfitWearable))) continue;

try { await wearablesCatalogService.RequestWearableAsync(outfitWearable, cancellationToken); }
catch (Exception e) { Debug.LogWarning($"Cannot resolve the wearable {outfitWearable} for the outfit {outfit.slot}"); }
catch (Exception e) { Debug.LogWarning($"Cannot resolve the wearable {outfitWearable} for the outfit {outfit.slot.ToString()}"); }
}

EquipWearable(outfit.outfit.bodyShape, EquipWearableSource.Outfit, setAsDirty: false, updateAvatarPreview: false);
Expand Down Expand Up @@ -225,6 +233,8 @@ public void Dispose()
view.OnSignUpBackClicked -= OnSignUpBack;
outfitsController.OnOutfitEquipped -= OnOutfitEquipped;
view.Dispose();

vrmBlockingWearablesList.Clear();
}

private void UpdateOverrideHides(string category, bool toggleOn) =>
Expand Down Expand Up @@ -339,38 +349,41 @@ private void LoadUserProfile(UserProfile userProfile)
return;
}

async UniTaskVoid LoadUserProfileAsync(UserProfile userProfile, CancellationToken cancellationToken)
async UniTaskVoid LoadUserAvatarAsync(AvatarModel avatar, CancellationToken cancellationToken)
{
try
{
foreach (string w in userProfile.avatar.wearables)
if (ExtendedUrnParser.IsExtendedUrn(w))
extendedWearableUrns[ExtendedUrnParser.GetShortenedUrn(w)] = w;

foreach (AvatarModel.AvatarEmoteEntry emote in userProfile.avatar.emotes)
if (ExtendedUrnParser.IsExtendedUrn(emote.urn))
extendedWearableUrns[ExtendedUrnParser.GetShortenedUrn(emote.urn)] = emote.urn;
foreach (AvatarModel.AvatarEmoteEntry emote in avatar.emotes)
{
string shortenedEmotedUrn = ExtendedUrnParser.GetShortenedUrn(emote.urn);
if (!emote.urn.Equals(shortenedEmotedUrn))
extendedWearableUrns[shortenedEmotedUrn] = emote.urn;
}

wearablesCatalogService.WearablesCatalog.TryGetValue(userProfile.avatar.bodyShape, out var bodyShape);
bodyShape ??= await wearablesCatalogService.RequestWearableAsync(userProfile.avatar.bodyShape, cancellationToken);
wearablesCatalogService.WearablesCatalog.TryGetValue(avatar.bodyShape, out var bodyShape);
bodyShape ??= await wearablesCatalogService.RequestWearableAsync(avatar.bodyShape, cancellationToken);

UnEquipCurrentBodyShape(false);
EquipBodyShape(bodyShape, false);

model.skinColor = userProfile.avatar.skinColor;
model.hairColor = userProfile.avatar.hairColor;
model.eyesColor = userProfile.avatar.eyeColor;
model.forceRender = new HashSet<string>(userProfile.avatar.forceRender);
model.skinColor = avatar.skinColor;
model.hairColor = avatar.hairColor;
model.eyesColor = avatar.eyeColor;
model.forceRender = new HashSet<string>(avatar.forceRender);
model.wearables.Clear();
previewEquippedWearables.Clear();

int wearablesCount = userProfile.avatar.wearables.Count;
int wearablesCount = avatar.wearables.Count;

for (var i = 0; i < wearablesCount; i++)
{
string wearableId = userProfile.avatar.wearables[i];
string wearableId = avatar.wearables[i];
string shortenedWearableId = ExtendedUrnParser.GetShortenedUrn(wearableId);

if (!wearableId.Equals(shortenedWearableId))
extendedWearableUrns[shortenedWearableId] = wearableId;


if (!wearablesCatalogService.WearablesCatalog.TryGetValue(shortenedWearableId, out WearableItem wearable))
{
try { wearable = await wearablesCatalogService.RequestWearableAsync(shortenedWearableId, cancellationToken); }
Expand Down Expand Up @@ -400,7 +413,7 @@ async UniTaskVoid LoadUserProfileAsync(UserProfile userProfile, CancellationToke
}

loadProfileCancellationToken = loadProfileCancellationToken.SafeRestart();
LoadUserProfileAsync(userProfile, loadProfileCancellationToken.Token).Forget();
LoadUserAvatarAsync(userProfile.avatar, loadProfileCancellationToken.Token).Forget();
}

private void UpdateAvatarPreview()
Expand Down Expand Up @@ -457,7 +470,7 @@ private void SaveAvatarAndContinueSignupProcess()
dataStore.HUDs.signupVisible.Set(true);
view.SetSignUpStage(SignUpStage.SetNameAndEmail);
view.SetAvatarPreviewFocus(PreviewCameraFocus.FaceEditing);
view.PlayPreviewEmote("wave");
view.PlayPreviewEmote(EMOTE_ID);
backpackAnalyticsService.SendAvatarEditSuccessNuxAnalytic();
}

Expand Down Expand Up @@ -520,8 +533,8 @@ private void SaveAvatar(Texture2D face256Snapshot, Texture2D bodySnapshot)
{
string shortenedUrn = avatarModel.wearables[i];

if (extendedWearableUrns.ContainsKey(shortenedUrn))
avatarModel.wearables[i] = extendedWearableUrns[shortenedUrn];
if (extendedWearableUrns.TryGetValue(shortenedUrn, out string urn))
avatarModel.wearables[i] = urn;
}

// Add the equipped emotes to the avatar model
Expand All @@ -537,8 +550,8 @@ private void SaveAvatar(Texture2D face256Snapshot, Texture2D bodySnapshot)

string id = equippedEmote.id;

if (extendedWearableUrns.ContainsKey(id))
id = extendedWearableUrns[id];
if (extendedWearableUrns.TryGetValue(id, out string urn))
id = urn;
else if (emotesCatalogService.TryGetOwnedUrn(id, out string extendedUrn))
if (!string.IsNullOrEmpty(extendedUrn))
id = extendedUrn;
Expand Down Expand Up @@ -665,6 +678,12 @@ private void EquipWearable(
UpdateAvatarModel(model.ToAvatarModel());
categoryPendingToPlayEmote = wearable.data.category;
}

if (wearable.data.blockVrmExport)
{
vrmBlockingWearablesList.Add(shortenWearableId);
UpdateVRMExportWarning();
}
}

private void ReplaceIncompatibleWearablesWithDefaultWearables()
Expand Down Expand Up @@ -699,7 +718,7 @@ private void ReplaceIncompatibleWearablesWithDefaultWearables()

private void UnEquipCurrentBodyShape(bool setAsDirty = true)
{
if (model.bodyShape.id == "NOT_LOADED") return;
if (model.bodyShape.id == NOT_LOADED) return;

if (!wearablesCatalogService.WearablesCatalog.TryGetValue(model.bodyShape.id, out WearableItem wearable))
{
Expand Down Expand Up @@ -743,6 +762,18 @@ private void UnEquipWearable(WearableItem wearable,

if (updateAvatarPreview)
UpdateAvatarModel(model.ToAvatarModel());

if (wearable.data.blockVrmExport)
{
vrmBlockingWearablesList.Remove(shortenedWearableId);
UpdateVRMExportWarning();
}
}

private void UpdateVRMExportWarning()
{
vrmWarningEnabled = vrmBlockingWearablesList.Count > 0;
view.SetVRMExportWarning(vrmWarningEnabled);
}

private void ResetOverridesOfAffectedCategories(WearableItem wearable, bool setAsDirty = true)
Expand Down Expand Up @@ -863,7 +894,7 @@ private string GetEquipEmoteByCategory(string category)
private string GetRandomizedName(string baseString, int limit)
{
currentAnimationIndexShown = (currentAnimationIndexShown + 1) % limit;
return baseString + (currentAnimationIndexShown + 1);
return $"{baseString}{(currentAnimationIndexShown + 1).ToString()}";
}

private void OnVrmExport()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,15 @@ public class BackpackEditorHUDV2ComponentView : BaseComponentView<BackpackEditor
[SerializeField] internal GameObject outfitSection;
[SerializeField] internal Button outfitButton;
[SerializeField] internal Image outfitButtonIcon;
[SerializeField] internal Button vrmExportButton;
[SerializeField] internal RectTransform vrmExportedToast;
[SerializeField] internal GameObject background;
[SerializeField] internal GameObject hints;

[Header("VRM Export")]
[SerializeField] internal Button vrmExportButton;
[SerializeField] internal TooltipComponentView vrmExportTooltipComponentView;
[SerializeField] internal GameObject vrmWarningBubble;
[SerializeField] internal RectTransform vrmExportedToast;

[Header("Sign Up Mode")]
[SerializeField] internal GameObject signUpHeader;
[SerializeField] internal TMP_Text signUpHeaderTitle;
Expand All @@ -78,8 +82,8 @@ public class BackpackEditorHUDV2ComponentView : BaseComponentView<BackpackEditor
public AvatarSlotsView AvatarSlotsView => avatarSlotsView;
public BackpackFiltersComponentView BackpackFiltersComponentView => backpackFiltersComponentView;
public OutfitsSectionComponentView OutfitsSectionComponentView => outfitsSectionComponentView;
private DataStore_EmotesCustomization emotesCustomizationDataStore => DataStore.i.emotesCustomization;

private DataStore_EmotesCustomization emotesCustomizationDataStore => DataStore.i.emotesCustomization;
private Transform thisTransform;
private bool isAvatarDirty;
private AvatarModel avatarModelToUpdate;
Expand All @@ -88,6 +92,7 @@ public class BackpackEditorHUDV2ComponentView : BaseComponentView<BackpackEditor
private SignUpStage currentStage;
private Vector2 originalAnchorPositionOfWearablesBackgroundForSignUp;
private Vector2 originalAnchorPositionOfWearablesSection;
private bool vrmWarningEnabled;

public override void Awake()
{
Expand Down Expand Up @@ -123,11 +128,17 @@ public void Initialize(
outfitButton.onClick.AddListener(ToggleOutfitSection);

vrmExportButton.onClick.RemoveAllListeners();
vrmExportButton.onClick.AddListener(() => OnVRMExport?.Invoke());
vrmExportButton.onClick.AddListener(OnVRMExportButtonClicked);

outfitsSectionComponentView.OnBackButtonPressed += ToggleNormalSection;
}

private void OnVRMExportButtonClicked()
{
if (!vrmWarningEnabled)
OnVRMExport?.Invoke();
}

public void SetOutfitsEnabled(bool isEnabled) =>
outfitButton.gameObject.SetActive(isEnabled);

Expand Down Expand Up @@ -297,6 +308,21 @@ public void SetVRMSuccessToastActive(bool active)
vrmExportedToast.gameObject.SetActive(active);
}

public void SetVRMExportWarning(bool enable)
{
vrmWarningEnabled = enable;
if (vrmWarningEnabled)
{
vrmWarningBubble.SetActive(true);
vrmExportTooltipComponentView.isViewEnabled = true;
}
else
{
vrmWarningBubble.SetActive(false);
vrmExportTooltipComponentView.isViewEnabled = false;
}
}

public void SetSignUpModeActive(bool isActive)
{
signUpHeader.SetActive(isActive);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public interface IBackpackEditorHUDView
void SetVRMButtonActive(bool enabled);
void SetVRMButtonEnabled(bool enabled);
void SetVRMSuccessToastActive(bool active);
void SetVRMExportWarning(bool enable);
void SetSignUpModeActive(bool isActive);
void SetSignUpStage(SignUpStage stage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public record InfoCardComponentModel
public List<string> removeList;
public string wearableId;
public bool unEquipAllowed = true;
public bool blockVrmExport = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class InfoCardComponentView : BaseComponentView<InfoCardComponentModel>,
[SerializeField] internal RectTransform dynamicSection;
[SerializeField] internal DynamicListComponentView hidesList;
[SerializeField] internal DynamicListComponentView hiddenByDynamicList;
[SerializeField] internal Image vrmBlockedTag;

public event Action OnEquipWearable;
public event Action OnUnEquipWearable;
Expand Down Expand Up @@ -57,6 +58,12 @@ public override void RefreshControl()
SetHiddenBy(model.hiddenBy);
SetNftImage(model.imageUri);
SetWearableId(model.wearableId);
SetVRMBlockedTag(model.blockVrmExport);
}

private void SetVRMBlockedTag(bool vrmBlocked)
{
vrmBlockedTag.gameObject.SetActive(vrmBlocked);
}

public void SetName(string nameText)
Expand Down
Loading

0 comments on commit 481ffa9

Please sign in to comment.