protected override async void LoadPayload(ScreenLoadPromise promise) { SpinnerOverlay.Show(); await Context.LevelManager.LoadLevelsOfType(LevelType.User); RestClient.GetArray <EventMeta>(new RequestHelper { Uri = $"{Context.ApiUrl}/events", Headers = Context.OnlinePlayer.GetRequestHeaders(), EnableDebug = true }).Then(data => { if (data.Length == 0) { Dialog.PromptGoBack("DIALOG_EVENTS_NOT_AVAILABLE".Get()); promise.Reject(); return; } IntentPayload.Events = data.ToList(); promise.Resolve(IntentPayload); }) .CatchRequestError(error => { Debug.LogError(error); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); promise.Reject(); }) .Finally(() => SpinnerOverlay.Hide()); }
protected override void LoadPayload(ScreenLoadPromise promise) { coverImage.color = Color.black; if (IntentPayload.Collection != null) { promise.Resolve(IntentPayload); return; } SpinnerOverlay.Show(); RestClient.Get <CollectionMeta>(new RequestHelper { Uri = $"{Context.ApiUrl}/collections/{IntentPayload.CollectionId}", Headers = Context.OnlinePlayer.GetRequestHeaders(), EnableDebug = true }) .Then(meta => { IntentPayload.Collection = meta; promise.Resolve(IntentPayload); }) .CatchRequestError(error => { Debug.LogError(error); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); promise.Reject(); }) .Finally(() => SpinnerOverlay.Hide()); }
protected override void LoadPayload(ScreenLoadPromise promise) { IntentPayload.IsPlayer = IntentPayload.Id == Context.OnlinePlayer.LastProfile?.User.Id; if (IntentPayload.Profile != null) { promise.Resolve(IntentPayload); return; } if (IntentPayload.IsPlayer) { if (Context.OnlinePlayer.LastFullProfile != null) { IntentPayload.Profile = Context.OnlinePlayer.LastFullProfile; promise.Resolve(IntentPayload); return; } if (Context.IsOffline()) { // Fetch offline profile and cast it as full profile Context.OnlinePlayer.FetchProfile() .Then(profile => { var fullProfile = JsonConvert.DeserializeObject <FullProfile>(JsonConvert.SerializeObject(profile)); IntentPayload.Profile = fullProfile; promise.Resolve(IntentPayload); }) .CatchRequestError(error => { Debug.LogError(error); Dialog.PromptGoBack("DIALOG_OFFLINE_FEATURE_NOT_AVAILABLE".Get()); }); return; } } SpinnerOverlay.Show(); RestClient.Get <FullProfile>(new RequestHelper { Uri = $"{Context.ApiUrl}/profile/{IntentPayload.Id}/details", Headers = Context.OnlinePlayer.GetRequestHeaders(), EnableDebug = true }).Then(data => { if (IntentPayload.IsPlayer) { Context.OnlinePlayer.LastFullProfile = data; } IntentPayload.Profile = data; promise.Resolve(IntentPayload); }).CatchRequestError(error => { Debug.LogError(error); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); }).Finally(() => SpinnerOverlay.Hide()); }
public override async void OnScreenBecameActive() { base.OnScreenBecameActive(); ProfileWidget.Instance.Enter(); ScreenCenter = new Vector2(UnityEngine.Screen.width / 2f, UnityEngine.Screen.height / 2f); var height = RectTransform.rect.height; var padding = scrollRectContentLayoutGroup.padding; padding.top = padding.bottom = (int)((height - 576) / 2f); // TODO: Un-hardcode tier card height but I'm lazy lol scrollRectContentLayoutGroup.padding = padding; if (LoadedContent == null) { SpinnerOverlay.Show(); await Context.LevelManager.LoadLevelsOfType(LevelType.Tier); RestClient.Get(new RequestHelper { Uri = $"{Context.ApiUrl}/seasons/alpha", Headers = Context.OnlinePlayer.GetRequestHeaders(), Timeout = 5, }).Then(res => { print("TierSelection: " + res.Text); var season = JsonConvert.DeserializeObject <SeasonMeta>(res.Text); LoadedContent = new Content { Season = season }; OnContentLoaded(LoadedContent); Run.After(0.4f, () => { icons.Enter(); SpinnerOverlay.Hide(); }); }).CatchRequestError(error => { if (!error.IsNetworkError) { throw error; } SpinnerOverlay.Hide(); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); }); } else { SpinnerOverlay.Show(); OnContentLoaded(LoadedContent); Run.After(0.4f, () => { icons.Enter(); SpinnerOverlay.Hide(); }); } }
private async void OnSettingsTab() { if (!initializedSettingsTab) { SpinnerOverlay.Show(); await UniTask.DelayFrame(5); InitializeSettingsTab(); await UniTask.DelayFrame(5); SpinnerOverlay.Hide(); } }
private async void OnApplicationPause(bool pauseStatus) { // Resuming? if (!pauseStatus) { if (Context.ScreenManager.History.All(it => it.ScreenId != MainMenuScreen.Id)) { return; } // Install levels SpinnerOverlay.Show(); Context.LevelManager.OnLevelInstallProgress.AddListener(SpinnerOverlay.OnLevelInstallProgress); var loadedLevelJsonFiles = await Context.LevelManager.InstallUserCommunityLevels(); Context.LevelManager.OnLevelInstallProgress.RemoveListener(SpinnerOverlay.OnLevelInstallProgress); Context.LevelManager.OnLevelLoadProgress.AddListener(SpinnerOverlay.OnLevelLoadProgress); var loadedLevels = await Context.LevelManager.LoadFromMetadataFiles(LevelType.User, loadedLevelJsonFiles, true); Context.LevelManager.OnLevelLoadProgress.RemoveListener(SpinnerOverlay.OnLevelLoadProgress); SpinnerOverlay.Hide(); if (loadedLevels.Count > 0) { var lastLoadedLevel = loadedLevels.Last(); if (Context.ScreenManager.ActiveScreenId != GamePreparationScreen.Id) { // Switch to that level while (Context.ScreenManager.PeekHistory().Let(it => it != null && it.ScreenId != MainMenuScreen.Id)) { Context.ScreenManager.PopAndPeekHistory(); } Context.ScreenManager.History.Push(new Intent(LevelSelectionScreen.Id, null)); Context.ScreenManager.ChangeScreen(GamePreparationScreen.Id, ScreenTransition.In, payload: new GamePreparationScreen.Payload { Level = lastLoadedLevel }); } else { Context.SelectedLevel = lastLoadedLevel; // Trigger the event and screen will relaod } } } }
public void UpdateLeaderboard(string mode) { ClearLeaderboard(); SpinnerOverlay.Show(); var uri = Context.ApiUrl + "/leaderboard?limit=50"; if (mode == "me") { uri += "&user="******"me") { var meEntry = leaderboard.Entries.Find(it => it.Model.Uid == Context.Player.Id); if (meEntry != null) { await UniTask.DelayFrame(0); leaderboardScrollRect.GetComponent <ScrollRectFocusHelper>() .CenterOnItem(meEntry.transform as RectTransform); } } await UniTask.DelayFrame(2); if (LoadedPayload.LeaderboardScrollPosition > -1) { leaderboardScrollRect.verticalNormalizedPosition = LoadedPayload.LeaderboardScrollPosition; } } catch (Exception e) { Debug.LogError(e); } } }
public override void OnPointerClick(PointerEventData eventData) { base.OnPointerClick(eventData); if (isStatic) { return; } if (record != null) { if (Context.ScreenManager.IsChangingScreen) { return; } if (Context.IsOffline()) { throw new InvalidOperationException(); } Context.AudioManager.Get("Navigate2").Play(); Context.Haptic(HapticTypes.MediumImpact, true); // Get full meta SpinnerOverlay.Show(); RestClient.Get <OnlineLevel>(new RequestHelper { Uri = $"{Context.ApiUrl}/levels/{record.chart.level.Uid}", Headers = Context.OnlinePlayer.GetRequestHeaders() }) .Then(it => { Context.ScreenManager.ChangeScreen(GamePreparationScreen.Id, ScreenTransition.In, 0.4f, transitionFocus: GetComponent <RectTransform>().GetScreenSpaceCenter(), payload: new GamePreparationScreen.Payload { Level = it.ToLevel(LevelType.User) }); }) .CatchRequestError(error => { Debug.LogError(error); Dialog.PromptAlert("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); }) .Finally(() => SpinnerOverlay.Hide()); } }
public static async UniTask Show(Story story) { var instance = Instance; if (instance.IsActive) { await UniTask.WaitUntil(() => !instance.IsActive); } await instance.Enter(); var spriteSets = new Dictionary <string, DialogueSpriteSet>(); var animationSets = new Dictionary <string, DialogueAnimationSet>(); if (story.globalTags != null) { story.globalTags.FindAll(it => it.Trim().StartsWith("SpriteSet:")) .Select(it => it.Substring(it.IndexOf(':') + 1).Trim()) .Select(DialogueSpriteSet.Parse) .ForEach(it => spriteSets[it.Id] = it); story.globalTags.FindAll(it => it.Trim().StartsWith("AnimationSet:")) .Select(it => it.Substring(it.IndexOf(':') + 1).Trim()) .Select(DialogueAnimationSet.Parse) .ForEach(it => animationSets[it.Id] = it); } await spriteSets.Values.Select(it => it.Initialize()); await animationSets.Values.Select(it => it.Initialize()); Sprite currentImageSprite = null; string currentImageSpritePath = null; Sprite currentSprite = null; string currentAnimation = null; var currentSpeaker = ""; var currentPosition = DialogueBoxPosition.Bottom; var shouldSetImageSprite = false; Dialogue lastDialogue = null; DialogueBox lastDialogueBox = null; DialogueHighlightTarget lastHighlightTarget = null; while (story.canContinue && !TerminateCurrentStory) { var message = ReplacePlaceholders(story.Continue()); var duration = 0f; var tags = story.currentTags; var doAction = TagValue(tags, "Action"); if (doAction != null) { switch (doAction) { case "GamePreparation/ShowGameplayTab": var tabs = Context.ScreenManager.GetScreen <GamePreparationScreen>().actionTabs; tabs.OnAction(tabs.Actions.Find(it => it.index == 2)); break; } } var setDuration = TagValue(tags, "Duration"); if (setDuration != null) { duration = float.Parse(setDuration); } var setOverlayOpacity = TagValue(tags, "OverlayOpacity"); if (setOverlayOpacity != null) { setOverlayOpacity.Split('/', out var targetOpacity, out var fadeDuration, out var fadeDelay); SetOverlayOpacity().Forget(); async UniTaskVoid SetOverlayOpacity() { await UniTask.Delay(TimeSpan.FromSeconds(float.Parse(fadeDelay))); instance.backdropImage.DOFade(float.Parse(targetOpacity), float.Parse(fadeDuration)); } } var setHighlight = TagValue(tags, "Highlight"); if (setHighlight != null) { lastHighlightTarget = await DialogueHighlightTarget.Find(setHighlight); if (lastHighlightTarget != null) { lastHighlightTarget.Highlighted = true; } } var waitForHighlightOnClick = FlagValue(tags, "WaitForHighlightOnClick"); if (waitForHighlightOnClick && lastHighlightTarget == null) { waitForHighlightOnClick = false; } var setImage = TagValue(tags, "Image"); string imageWidth = null, imageHeight = null, imageRadius = null; if (setImage != null) { if (setImage == "null") { currentImageSprite = null; } else { setImage.Split('/', out imageWidth, out imageHeight, out imageRadius, out var imageUrl); imageUrl = ReplacePlaceholders(imageUrl); SpinnerOverlay.Show(); currentImageSprite = await Context.AssetMemory.LoadAsset <Sprite>(imageUrl, AssetTag.DialogueImage); currentImageSpritePath = imageUrl; SpinnerOverlay.Hide(); shouldSetImageSprite = true; } } var setSprite = TagValue(tags, "Sprite"); if (setSprite != null) { if (setSprite == "null") { currentSprite = null; DisposeImageSprite(); } else { setSprite.Split('/', out var id, out var state); if (!spriteSets.ContainsKey(id)) { throw new ArgumentOutOfRangeException(); } currentSprite = spriteSets[id].States[state].Sprite; currentAnimation = null; } } var setAnimation = TagValue(tags, "Animation"); if (setAnimation != null) { if (setAnimation == "null") { currentAnimation = null; } else { currentAnimation = setAnimation; currentSprite = null; } } var setSpeaker = TagValue(tags, "Speaker"); if (setSpeaker != null) { currentSpeaker = setSpeaker == "null" ? null : setSpeaker; } var setPosition = TagValue(tags, "Position"); if (setPosition != null) { currentPosition = (DialogueBoxPosition)Enum.Parse(typeof(DialogueBoxPosition), setPosition); } var dialogue = new Dialogue { Message = message, SpeakerName = currentSpeaker, Sprite = currentSprite, Position = currentPosition, HasChoices = story.currentChoices.Count > 0, IsBlocked = waitForHighlightOnClick || duration > 0 }; // Lookup animation if (currentAnimation != null) { currentAnimation.Split('/', out var id, out var animationName); if (!animationSets.ContainsKey(id)) { throw new ArgumentOutOfRangeException(); } dialogue.AnimatorController = animationSets[id].Controller; dialogue.AnimationName = animationName; } DialogueBox dialogueBox; if (dialogue.Position == DialogueBoxPosition.Top) { dialogueBox = instance.topDialogueBox; } else if (dialogue.Sprite != null || dialogue.AnimatorController != null) { dialogueBox = instance.bottomFullDialogueBox; } else { dialogueBox = instance.bottomDialogueBox; } if (lastDialogue != null && (lastDialogueBox != dialogueBox || lastDialogue.SpeakerName != dialogue.SpeakerName)) { await lastDialogueBox.SetDisplayed(false); dialogueBox.messageBox.SetLocalScale(1f); } // Display image if (currentImageSprite != null) { if (shouldSetImageSprite) { instance.image.SetData(currentImageSprite, int.Parse(imageWidth), int.Parse(imageHeight), int.Parse(imageRadius)); await UniTask.Delay(TimeSpan.FromSeconds(1.5f)); shouldSetImageSprite = false; } } else { instance.image.Clear(); } if (message.IsNullOrEmptyTrimmed()) { await dialogueBox.SetDisplayed(false); } else { await dialogueBox.SetDisplayed(true); lastDialogue = dialogue; lastDialogueBox = dialogueBox; instance.detectionArea.onPointerDown.SetListener(_ => { dialogueBox.messageBox.DOScale(0.97f, 0.2f); }); instance.detectionArea.onPointerUp.SetListener(_ => { dialogueBox.messageBox.DOScale(1f, 0.2f); }); instance.detectionArea.onPointerClick.SetListener(_ => { dialogueBox.WillFastForwardDialogue = true; }); await dialogueBox.ShowDialogue(dialogue); } if (waitForHighlightOnClick) { instance.detectionArea.onPointerDown.RemoveAllListeners(); instance.detectionArea.onPointerUp.RemoveAllListeners(); await lastHighlightTarget.WaitForOnClick(); } else if (story.currentChoices.Count > 0) { var proceed = false; var buttons = new List <SoftButton>(); for (var index = 0; index < story.currentChoices.Count; index++) { var choice = story.currentChoices[index]; var choiceButton = Instantiate(instance.choiceButtonPrefab, instance.choicesRoot); var closureIndex = index; choiceButton.onPointerClick.SetListener(_ => { if (proceed) { return; } story.ChooseChoiceIndex(closureIndex); proceed = true; }); choiceButton.Label = choice.text.Get(); buttons.Add(choiceButton); } LayoutFixer.Fix(instance.choicesRoot); await UniTask.DelayFrame(5); foreach (var button in buttons) { button.transitionElement.UseCurrentStateAsDefault(); button.transitionElement.Enter(); await UniTask.Delay(TimeSpan.FromSeconds(0.2f)); } await UniTask.WaitUntil(() => proceed); buttons.ForEach(it => Destroy(it.gameObject)); } else { var proceed = false; instance.detectionArea.onPointerDown.SetListener(_ => { dialogueBox.messageBox.DOScale(0.95f, 0.2f); }); instance.detectionArea.onPointerUp.SetListener(_ => { dialogueBox.messageBox.DOScale(1f, 0.2f); proceed = true; }); if (duration > 0) { await UniTask.WhenAny(UniTask.WaitUntil(() => proceed), UniTask.Delay(TimeSpan.FromSeconds(duration))); } else { await UniTask.WaitUntil(() => proceed); } instance.detectionArea.onPointerDown.RemoveAllListeners(); instance.detectionArea.onPointerUp.RemoveAllListeners(); } if (lastHighlightTarget != null) { lastHighlightTarget.Highlighted = false; lastHighlightTarget = null; } } TerminateCurrentStory = false; if (lastDialogueBox != null) { lastDialogueBox.SetDisplayed(false); } instance.image.Clear(); await instance.Leave(); DisposeImageSprite(); spriteSets.Values.ForEach(it => it.Dispose()); animationSets.Values.ForEach(it => it.Dispose()); string TagValue(List <string> tags, string tag) { return(tags.Find(it => it.Trim().StartsWith(tag + ":"))?.Let(it => it.Substring(it.IndexOf(':') + 1).Trim())); } bool FlagValue(List <string> tags, string tag) { return(tags.Any(it => it.Trim() == tag)); } void DisposeImageSprite() { if (currentImageSprite != null) { Context.AssetMemory.DisposeAsset(currentImageSpritePath, AssetTag.DialogueImage); currentImageSprite = null; currentImageSpritePath = null; } } string ReplacePlaceholders(string str) { str = str.Replace("[N/A]", ""); str = str.Trim(); if (str.StartsWith("[STORY_")) { str = str.Substring(1, str.Length - 2).Get(); } foreach (var(placeholder, function) in PlaceholderFunctions) { if (str.Contains(placeholder)) { str = str.Replace(placeholder, function()); } } return(str); } }
protected override void LoadPayload(ScreenLoadPromise promise) { SpinnerOverlay.Show(); Context.CharacterManager.GetAvailableCharactersMeta() .Then(async characters => { try { if (Application.isEditor) { Debug.Log("Available characters:"); characters.PrintJson(); } if (characters.Count == 0) { // TODO: This should not happen! We have Sayaka SpinnerOverlay.Hide(); Dialog.PromptGoBack("DIALOG_OFFLINE_FEATURE_NOT_AVAILABLE".Get()); promise.Reject(); return; } if (!await Context.BundleManager.DownloadAndSaveCatalog()) { SpinnerOverlay.Hide(); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); promise.Reject(); return; } SpinnerOverlay.Hide(); var downloadsRequired = 0; foreach (var meta in characters) { if (!Context.BundleManager.IsUpToDate(CharacterAsset.GetMainBundleId(meta.AssetId))) { downloadsRequired++; } } print($"Number of downloads required: {downloadsRequired}"); var downloaded = 0; foreach (var meta in characters) { var(success, locallyResolved) = await Context.CharacterManager.DownloadCharacterAssetDialog( CharacterAsset.GetMainBundleId(meta.AssetId)); if (success && !locallyResolved) { downloaded++; print("Downloaded " + meta.AssetId); } if (!success) { Toast.Next(Toast.Status.Failure, "CHARACTER_FAILED_TO_DOWNLOAD".Get()); } else { IntentPayload.OwnedCharacters.Add(meta); } } print($"Number of downloads: {downloaded}"); if (downloaded > downloadsRequired) { // Update was performed, which requires player to restart the game // Why? Too lazy to figure out dynamic reloads... Dialog.PromptUnclosable("DIALOG_RESTART_REQUIRED".Get()); promise.Reject(); return; } if (IntentPayload.OwnedCharacters.Count == 0) { Dialog.PromptGoBack("DIALOG_OFFLINE_FEATURE_NOT_AVAILABLE".Get()); promise.Reject(); return; } promise.Resolve(IntentPayload); } catch (Exception e) { Debug.LogError(e); SpinnerOverlay.Hide(); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); promise.Reject(); } }) .CatchRequestError(error => { SpinnerOverlay.Hide(); promise.Reject(); if (!error.IsNetworkError) { throw error; } Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); }); }
public async void LoadCharacter(CharacterMeta meta) { ParallaxHolder.WillDelaySet = true; var isNewCharacter = Context.CharacterManager.ActiveCharacterBundleId != meta.AssetId; if (isNewCharacter) { SpinnerOverlay.Show(); infoCard.Leave(false); characterTransitionElement.Leave(false); } var character = await Context.CharacterManager.SetActiveCharacter(meta.AssetId); if (character == null) { throw new Exception("Character not downloaded or corrupted"); } if (isNewCharacter) { await UniTask.Delay(TimeSpan.FromSeconds(0.4f)); } nameText.text = meta.Name; nameGradient.SetGradient(character.nameGradient.GetGradient()); descriptionText.text = meta.Description; levelCard.SetModel(meta.Level.ToLevel(LevelType.User)); illustratorText.text = meta.Illustrator.Name; illustratorProfileButton.onPointerClick.SetListener(_ => Application.OpenURL(meta.Illustrator.Url)); if (meta.CharacterDesigner != null && !meta.CharacterDesigner.Name.IsNullOrEmptyTrimmed()) { characterDesignerHolder.gameObject.SetActive(true); characterDesignerText.text = meta.CharacterDesigner.Name; characterDesignerProfileButton.onPointerClick.SetListener(_ => Application.OpenURL(meta.CharacterDesigner.Url)); } else { characterDesignerHolder.gameObject.SetActive(false); } infoCard.transform.RebuildLayout(); if (character.musicAudio == null) { muteButtonImage.sprite = volumeSprite; muteButtonImage.SetAlpha(0.3f); muteButton.scaleOnClick = false; muteButton.onPointerClick.RemoveAllListeners(); } else { muteButtonImage.sprite = Context.Player.Settings.PlayCharacterTheme ? volumeSprite : volumeMuteSprite; muteButtonImage.SetAlpha(1f); muteButton.scaleOnClick = true; muteButton.onPointerClick.SetListener(_ => { Context.Player.Settings.PlayCharacterTheme = !Context.Player.Settings.PlayCharacterTheme; Context.Player.SaveSettings(); LoopAudioPlayer.Instance.SetMainAudio(Context.Player.Settings.PlayCharacterTheme ? character.musicAudio : LoopAudioPlayer.Instance.defaultLoopAudio); muteButtonImage.sprite = Context.Player.Settings.PlayCharacterTheme ? volumeSprite : volumeMuteSprite; }); } await characterDisplay.Load(CharacterAsset.GetTachieBundleId(meta.AssetId)); NavigationBackdrop.Instance.UpdateBlur(); infoCard.Enter(); characterTransitionElement.Leave(false, true); characterTransitionElement.Enter(); characterTransitionElement.Apply(it => { it.enterMultiplier = 0.4f; it.enterDelay = 0.4f; it.enterDuration = 0.8f; }); if (Context.IsOffline()) { SpinnerOverlay.Hide(); } else { RestClient.Post(new RequestHelper { Uri = $"{Context.ApiUrl}/profile/{Context.Player.Id}/character", Headers = Context.OnlinePlayer.GetRequestHeaders(), EnableDebug = true, Body = new CharacterPostData { characterId = meta.Id } }) .CatchRequestError(error => { Debug.LogError(error); Toast.Next(Toast.Status.Failure, "TOAST_FAILED_TO_UPDATE_PROFILE_CHARACTER".Get()); }) .Finally(() => { SpinnerOverlay.Hide(); }); } ParallaxHolder.WillDelaySet = false; }
protected override async void LoadPayload(ScreenLoadPromise promise) { if (Context.Player.ShouldOneShot("Agree Copyright Policy")) { Context.Player.ClearOneShot("Agree Copyright Policy"); if (!await TermsOverlay.Show("COPYRIGHT_POLICY".Get())) { promise.Reject(); Context.ScreenManager.ChangeScreen(Context.ScreenManager.PopAndPeekHistory(), ScreenTransition.Out, addTargetScreenToHistory: false); return; } Context.Player.ShouldOneShot("Agree Copyright Policy"); } SpinnerOverlay.Show(); var promises = new List <IPromise>(); foreach (var section in IntentPayload.Layout.Sections) { switch (section) { case Layout.LevelSection levelSection: promises.Add(RestClient.GetArray <OnlineLevel>(new RequestHelper { Uri = levelSection.Query.BuildUri(levelSection.PreviewSize), Headers = Context.OnlinePlayer.GetRequestHeaders(), EnableDebug = true }).Then(data => { levelSection.Levels = data.ToList(); })); break; case Layout.CollectionSection collectionSection: { var collectionPromises = new List <RSG.IPromise <CollectionMeta> >(); foreach (var collectionId in collectionSection.CollectionIds) { collectionPromises.Add(RestClient.Get <CollectionMeta>(new RequestHelper { Uri = $"{Context.ApiUrl}/collections/{collectionId}", Headers = Context.OnlinePlayer.GetRequestHeaders(), EnableDebug = true })); } promises.Add(Promise <CollectionMeta> .All(collectionPromises).Then(data => { collectionSection.Collections = data.ToList() .Zip(collectionSection.CollectionIds, (meta, id) => meta.Also(it => it.id = id)) .Zip(collectionSection.CollectionTitleKeys, (meta, title) => meta.Also(it => it.title = title.Get())) .Zip(collectionSection.CollectionSloganKeys, (meta, slogan) => meta.Also(it => it.slogan = slogan.Get())) .ToList(); })); break; } } } Promise.All(promises) .Then(() => { promise.Resolve(IntentPayload); }) .Catch(error => { Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); Debug.LogError(error); promise.Reject(); }) .Finally(() => SpinnerOverlay.Hide()); }
public void LoadEvent(EventMeta meta) { async UniTask LoadCover(CancellationToken token) { Assert.IsNotNull(meta.cover); var tasks = new List <UniTask>(); if (coverImage.sprite != null) { coverImage.DOKill(); coverImage.DOColor(Color.black, 0.4f); tasks.Add(UniTask.Delay(TimeSpan.FromSeconds(0.4f), cancellationToken: token)); } Sprite sprite = null; tasks.Add(Context.AssetMemory.LoadAsset <Sprite>(meta.cover.OriginalUrl, AssetTag.EventCover, cancellationToken: token).ContinueWith(result => sprite = result)); try { await tasks; } catch (OperationCanceledException) { return; } coverImage.sprite = sprite; coverImage.FitSpriteAspectRatio(); coverImage.DOColor(Color.white, 2f).SetDelay(0.8f); } async UniTask LoadLogo(CancellationToken token) { Assert.IsNotNull(meta.logo); var tasks = new List <UniTask>(); if (logoImage.sprite != null) { logoImage.DOKill(); logoImage.DOFade(0, 0.4f); tasks.Add(UniTask.Delay(TimeSpan.FromSeconds(0.4f), cancellationToken: token)); } Sprite sprite = null; tasks.Add(Context.AssetMemory.LoadAsset <Sprite>(meta.logo.OriginalUrl, AssetTag.EventLogo, cancellationToken: token).ContinueWith(result => sprite = result)); try { await tasks; } catch (OperationCanceledException) { return; } logoImage.sprite = sprite; logoImage.DOFade(1, 0.8f).SetDelay(0.4f); } AddTask(LoadCover); AddTask(LoadLogo); Context.Player.Settings.SeenEvents.Add(meta.uid); Context.Player.SaveSettings(); infoBanner.Leave(onComplete: () => { if (!Context.Player.Settings.ReadEventDetails.Contains(meta.uid)) { viewDetailsNotification.Show(); } viewDetailsButton.onPointerClick.SetListener(_ => { Context.Player.Settings.ReadEventDetails.Add(meta.uid); Context.Player.SaveSettings(); viewDetailsNotification.Hide(); if (meta.url.IsNullOrEmptyTrimmed()) { Application.OpenURL($"{Context.WebsiteUrl}/posts/{meta.uid}"); } else { WebViewOverlay.Show(meta.url, onFullyShown: () => { LoopAudioPlayer.Instance.FadeOutLoopPlayer(); }, onFullyHidden: async() => { AudioSettings.Reset(AudioSettings.GetConfiguration()); Context.AudioManager.Dispose(); Context.AudioManager.Initialize(); await UniTask.DelayFrame(5); LoopAudioPlayer.Instance.Apply(it => { it.FadeInLoopPlayer(); it.PlayAudio(it.PlayingAudio, forceReplay: true); }); }); } }); const string dateFormat = "yyyy/MM/dd HH:mm"; durationText.text = (meta.startDate.HasValue ? meta.startDate.Value.LocalDateTime.ToString(dateFormat) : "") + "~" + (meta.endDate.HasValue ? meta.endDate.Value.LocalDateTime.ToString(dateFormat) : ""); enterButton.onPointerClick.SetListener(_ => { if (meta.locked) { Context.Haptic(HapticTypes.Failure, true); // TODO return; } Context.Haptic(HapticTypes.SoftImpact, true); if (meta.levelId != null) { SpinnerOverlay.Show(); RestClient.Get <OnlineLevel>(new RequestHelper { Uri = $"{Context.ApiUrl}/levels/{meta.levelId}" }).Then(level => { Context.ScreenManager.ChangeScreen( GamePreparationScreen.Id, ScreenTransition.In, 0.4f, transitionFocus: GetComponent <RectTransform>().GetScreenSpaceCenter(), payload: new GamePreparationScreen.Payload { Level = level.ToLevel(LevelType.User) } ); }).CatchRequestError(error => { Debug.LogError(error); Dialog.PromptAlert("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); }).Finally(() => SpinnerOverlay.Hide()); } else if (meta.collectionId != null) { Context.ScreenManager.ChangeScreen( CollectionDetailsScreen.Id, ScreenTransition.In, 0.4f, transitionFocus: GetComponent <RectTransform>().GetScreenSpaceCenter(), payload: new CollectionDetailsScreen.Payload { CollectionId = meta.collectionId, Type = LevelType.User } ); } }); infoBanner.transform.RebuildLayout(); infoBanner.Enter(); }); }
private async void OnDeepLinkReceived(string url) { Debug.Log($"Deep link received: {url}"); if (!url.StartsWith("cytoid://")) { return; } var token = deepLinkToken = DateTimeOffset.Now; await UniTask.WaitUntil(() => Context.ScreenManager != null && Context.ScreenManager.History.Any(it => it.ScreenId == MainMenuScreen.Id)); if (token != deepLinkToken) { return; } if (DeepLinkDisabledScreenIds.Contains(Context.ScreenManager.ActiveScreenId)) { Debug.Log($"Ignoring, current screen: {Context.ScreenManager.ActiveScreenId}"); return; } url = url.Substring("cytoid://".Length); if (url.StartsWith("levels/")) { var id = url.Substring("levels/".Length); SpinnerOverlay.Show(); RestClient.Get <OnlineLevel>(new RequestHelper { Uri = $"{Context.ApiUrl}/levels/{id}" }).Then(async level => { try { if (token != deepLinkToken) { return; } foreach (var tag in (AssetTag[])Enum.GetValues(typeof(AssetTag))) { if (tag == AssetTag.PlayerAvatar) { continue; } Context.AssetMemory.DisposeTaggedCacheAssets(tag); } while (Context.ScreenManager.PeekHistory().Let(it => it != null && it.ScreenId != MainMenuScreen.Id)) { Context.ScreenManager.PopAndPeekHistory(); } await UniTask.WaitUntil(() => !Context.ScreenManager.IsChangingScreen); // Resolve level if (Context.LevelManager.LoadedLocalLevels.ContainsKey(level.Uid)) { var localLevel = Context.LevelManager.LoadedLocalLevels[level.Uid]; Debug.Log($"Online level {level.Uid} resolved locally"); Context.ScreenManager.History.Push(new Intent(LevelSelectionScreen.Id, null)); Context.ScreenManager.ChangeScreen(GamePreparationScreen.Id, ScreenTransition.In, payload: new GamePreparationScreen.Payload { Level = localLevel }); } else { Context.ScreenManager.History.Push(new Intent(CommunityHomeScreen.Id, null)); Context.ScreenManager.ChangeScreen(GamePreparationScreen.Id, ScreenTransition.In, payload: new GamePreparationScreen.Payload { Level = level.ToLevel(LevelType.User) }); } } catch (Exception e) { Debug.LogError(e); Dialog.PromptAlert("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); } }).CatchRequestError(error => { if (token != deepLinkToken) { return; } if (error.IsHttpError) { if (error.StatusCode != 404) { throw error; } } Context.Haptic(HapticTypes.Failure, true); Dialog.Instantiate().Also(it => { it.Message = "DIALOG_COULD_NOT_OPEN_LEVEL_X".Get(id); it.UsePositiveButton = true; it.UseNegativeButton = false; }).Open(); }).Finally(() => { if (token != deepLinkToken) { return; } SpinnerOverlay.Hide(); }); } else { Debug.LogError("Unsupported deep link"); } }
private async void OnOfflineModeToggled(bool offline) { SpinnerOverlay.Show(); async void Fix(GameObject itGameObject, bool active) { // Yes, welcome to Unity. // Don't change, unless you are absolutely certain what I am (and you are) doing. itGameObject.SetActive(active); LayoutFixer.Fix(itGameObject.transform); await UniTask.DelayFrame(5); itGameObject.SetActive(!itGameObject.activeSelf); await UniTask.DelayFrame(0); itGameObject.SetActive(!itGameObject.activeSelf); await UniTask.DelayFrame(0); LayoutFixer.Fix(itGameObject.transform); if (active) { itGameObject.GetComponent <TransitionElement>()?.Apply(x => x.UseCurrentStateAsDefault()); } } foreach (var gameObject in SceneManager.GetActiveScene().GetRootGameObjects()) { gameObject.GetComponentsInChildren <OfflineElement>(true).ForEach(it => { if (offline) { it.targets.ForEach(x => x.SetActive(false)); it.gameObject.SetActive(true); } else { it.gameObject.SetActive(false); it.targets.ForEach(x => x.SetActive(true)); } it.rebuildTransform.RebuildLayout(); var o = it.rebuildTransform.gameObject; Fix(o, o.activeSelf); }); } await UniTask.DelayFrame(10); foreach (var gameObject in SceneManager.GetActiveScene().GetRootGameObjects()) { gameObject.GetComponentsInChildren <HiddenIfOfflineElement>(true).ForEach(it => { Fix(it.gameObject, !offline); var rebuild = it.rebuildTransform; if (rebuild != null) { rebuild.RebuildLayout(); var o = rebuild.gameObject; Fix(o, o.activeSelf); } }); } await UniTask.DelayFrame(10); foreach (var screen in Context.ScreenManager.createdScreens) { LayoutFixer.Fix(screen.transform); } await UniTask.DelayFrame(5); SpinnerOverlay.Hide(); }
public async void LoadContent() { SpinnerOverlay.Show(); var willUnpackAll = false; if (Context.Player.Settings.TrainingModeVersion < BuiltInData.TrainingModeVersion) { Context.Player.Settings.TrainingModeVersion = BuiltInData.TrainingModeVersion; Context.Player.SaveSettings(); willUnpackAll = true; } // Logic: // If online: load from API // If offline: load from static list // Then for any not found in path & data built in, extract from StreamingAssets folder var levels = new List <Level>(); var builtInLevelsToUnpack = new List <string>(); if (Context.IsOnline()) { RestClient.Get <TrainingData>(Context.ApiUrl + "/training") .Then(data => { // Save to DB Context.Database.Let(it => { var col = it.GetCollection <TrainingData>("training"); col.DeleteMany(x => true); col.Insert(data); }); foreach (var onlineLevel in data.Levels) { if (!willUnpackAll && (onlineLevel.HasLocal(LevelType.User) || !BuiltInData.TrainingModeLevelIds.Contains(onlineLevel.Uid))) { levels.Add(onlineLevel.ToLevel(LevelType.User)); } else { builtInLevelsToUnpack.Add(onlineLevel.Uid); } } Continuation(); }) .CatchRequestError(error => { Debug.LogError(error); Dialog.PromptGoBack("DIALOG_COULD_NOT_CONNECT_TO_SERVER".Get()); SpinnerOverlay.Hide(); }); } else { // Load from DB, or use default var levelUids = Context.Database.GetCollection <TrainingData>("training").FindOne(x => true)?.Levels .Select(it => it.Uid) ?? BuiltInData.TrainingModeLevelIds; foreach (var uid in levelUids) { if (!willUnpackAll && Context.LevelManager.LoadedLocalLevels.ContainsKey(uid) && Context.LevelManager.LoadedLocalLevels[uid].Type == LevelType.User) { levels.Add(Context.LevelManager.LoadedLocalLevels[uid]); } else { builtInLevelsToUnpack.Add(uid); } } Continuation(); } async void Continuation() { print($"Resolved levels: {string.Join(", ", levels.Select(it => it.Id))}"); print($"Built-in levels to unpack: {string.Join(", ", builtInLevelsToUnpack)}"); var packagePaths = await Context.LevelManager.CopyBuiltInLevelsToDownloads(builtInLevelsToUnpack); if (packagePaths.Count > 0) { Toast.Next(Toast.Status.Loading, "TOAST_INITIALIZING_TRAINING_MODE".Get()); Context.LevelManager.OnLevelInstallProgress.AddListener(SpinnerOverlay.OnLevelInstallProgress); var jsonPaths = await Context.LevelManager.InstallLevels(packagePaths, LevelType.User); Context.LevelManager.OnLevelInstallProgress.RemoveListener(SpinnerOverlay.OnLevelInstallProgress); Context.LevelManager.OnLevelLoadProgress.AddListener(SpinnerOverlay.OnLevelLoadProgress); var loadedLevels = await Context.LevelManager.LoadFromMetadataFiles(LevelType.User, jsonPaths); Context.LevelManager.OnLevelLoadProgress.RemoveListener(SpinnerOverlay.OnLevelLoadProgress); levels.AddRange(loadedLevels); } SpinnerOverlay.Hide(); LoadedContent = new Content { Levels = levels.OrderBy(it => it.Meta.GetEasiestDifficultyLevel()).ToList() }; OnContentLoaded(LoadedContent); } }