aurumStoreView.py (9536B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\view\aurumstore\aurumStoreView.py 2 import logging 3 import blue 4 import carbonui.const as uiconst 5 import localization 6 import locks 7 import uthread 8 from carbonui.primitives.fill import Fill 9 from carbonui.uicore import uicore 10 from carbonui.util.color import Color 11 from eve.client.script.ui.services.viewStateSvc import View 12 from eve.client.script.ui.view.aurumstore.aurumStoreContainer import AurumStoreContainer 13 from eve.client.script.ui.view.aurumstore.loadingPanel import LoadingPanel 14 from eve.client.script.ui.view.viewStateConst import ViewOverlay 15 from eveexceptions import ExceptionEater 16 from plex.client.api.repository import get_repository 17 from plex.client.api.signal import on_balance_changed 18 logger = logging.getLogger(__name__) 19 _SearchLock = locks.RLock() 20 STORE_REQUEST_TIMEOUT = 60 21 22 class AurumStoreView(View): 23 __notifyevents__ = ['OnShowUI'] 24 __suppressedOverlays__ = {ViewOverlay.SidePanels, ViewOverlay.Target, ViewOverlay.ShipUI} 25 __subLayers__ = [('l_vgsabovesuppress', None, None), ('l_vgssuppress', None, None)] 26 _debug = False 27 28 def __init__(self, *args, **kwargs): 29 super(AurumStoreView, self).__init__(*args, **kwargs) 30 self.loadingPanel = None 31 self.isLoaded = False 32 self._immersiveAudioOverlay = None 33 34 def IsLoaded(self): 35 return self.isLoaded 36 37 def LoadView(self, **kwargs): 38 self.isLoaded = False 39 View.LoadView(self, **kwargs) 40 if not self._debug: 41 uicore.layer.main.display = False 42 uicore.layer.abovemain.display = False 43 self._SearchTasklet = None 44 categoryId = kwargs.get('categoryId', None) 45 typeIds = kwargs.get('typeIds', None) 46 categoryTag = kwargs.get('categoryTag', None) 47 uthread.new(self.SetupStoreData, categoryId, typeIds, categoryTag) 48 sm.GetService('audio').SendUIEvent('store_view_start') 49 self._immersiveAudioOverlay = sm.GetService('audio').CreateImmersiveOverlay('aurum_store_view') 50 self._immersiveAudioOverlay.set_full_screen() 51 52 def SetupStoreData(self, categoryId = None, typeIds = None, categoryTag = None): 53 logger.debug('SetupStoreData') 54 if self.loadingPanel and not self.loadingPanel.destroyed: 55 self.loadingPanel.Close() 56 self.loadingPanel = LoadingPanel(parent=uicore.layer.vgsabovesuppress) 57 if session.userid is None: 58 logger.warn('SetupStoreData - Session has no userid. Store will be unavailable') 59 self.loadingPanel.ShowStoreUnavailable() 60 return 61 try: 62 vgsSvc = sm.GetService('vgsService') 63 vgsSvc.ClearCache() 64 self.store = vgsSvc.GetStore() 65 logger.debug('SetupStoreData - Spawning Get* threads') 66 getRootCategoryListTasklet = uthread.newJoinable(self.store.GetRootCategoryList) 67 getOffersTasklet = uthread.newJoinable(self.store.GetOffers) 68 logger.debug('SetupStoreData - Creating AurumStoreContainer') 69 self.storeContainer = AurumStoreContainer(parent=self.layer, store=self.store) 70 logger.debug('SetupStoreData - Joining on Get* threads') 71 rootCategoryList = uthread.waitForJoinable(getRootCategoryListTasklet, timeout=STORE_REQUEST_TIMEOUT) 72 plexBalance = get_repository().get_balance() 73 uthread.waitForJoinable(getOffersTasklet, timeout=STORE_REQUEST_TIMEOUT) 74 logger.debug('SetupStoreData - Populating UI') 75 self.storeContainer.SetCategories(rootCategoryList) 76 if typeIds: 77 self.storeContainer.LoadTypeIdPage(typeIds) 78 if categoryId: 79 self.ShowCategory(categoryId) 80 elif categoryTag: 81 self.SelectCategoryByCategoryTag(categoryTag) 82 else: 83 self.storeContainer.LoadLandingPage() 84 self.viewOpenedTimer = sm.GetService('viewState').lastViewOpenTime 85 self.SubscribeToStoreEvents() 86 except uthread.TaskletWaitTimeout: 87 logger.warn('SetupStoreData timed out, store will be unavailable') 88 self.loadingPanel.ShowStoreUnavailable(localization.GetByLabel('UI/VirtualGoodsStore/StoreUnavailableTimeout')) 89 raise 90 except Exception as e: 91 message = None 92 logger.warn('SetupStoreData - Store loading failed') 93 self.loadingPanel.ShowStoreUnavailable(message) 94 raise 95 96 logger.debug('SetupStoreData - Loading completed successfully, showing store') 97 uicore.animations.FadeOut(self.loadingPanel, duration=0.5, timeOffset=0.5, sleep=True) 98 self.loadingPanel.Close() 99 self.storeContainer.SetPlexBalance(plexBalance) 100 self.isLoaded = True 101 102 def ShowCategory(self, categoryId): 103 if categoryId is None or categoryId not in self.store.GetCategories(): 104 return 105 self.storeContainer.SelectCategory(categoryId) 106 107 def SelectCategoryByCategoryTag(self, categoryTag): 108 categoryId = self.store.GetCategoryIdByCategoryTag(categoryTag) 109 self.ShowCategory(categoryId) 110 111 def SubscribeToStoreEvents(self): 112 on_balance_changed.connect(self.storeContainer.SetPlexBalance) 113 114 def UnsubscribeFromStoreEvents(self): 115 try: 116 on_balance_changed.disconnect(self.storeContainer.SetPlexBalance) 117 except Exception: 118 self.LogError('Error while unsubscribing from store events') 119 120 def UnloadView(self): 121 self.isLoaded = False 122 View.UnloadView(self) 123 sm.GetService('audio').SendUIEvent('store_view_end') 124 if self._immersiveAudioOverlay: 125 self._immersiveAudioOverlay.close() 126 self.UnsubscribeFromStoreEvents() 127 sm.GetService('vgsService').GetUiController().CheckCloseOffer() 128 if getattr(self, 'storeContainer', None) is not None: 129 self.storeContainer.Close() 130 uicore.layer.main.display = True 131 uicore.layer.abovemain.display = True 132 133 def OnShowUI(self): 134 if not self._debug: 135 uicore.layer.main.display = False 136 137 def SetupSuppressLayer(self): 138 if len(uicore.layer.vgssuppress.children) == 0: 139 Fill(parent=uicore.layer.vgssuppress, color=Color.BLACK) 140 uicore.layer.vgssuppress.opacity = 0.0 141 uicore.layer.vgssuppress.state = uiconst.UI_DISABLED 142 143 def ActivateSuppressLayer(self, duration = 0.25, clickCallback = None, callback = None): 144 self.SetupSuppressLayer() 145 uicore.layer.vgssuppress.state = uiconst.UI_NORMAL 146 if clickCallback is not None: 147 uicore.layer.vgssuppress.OnClick = clickCallback 148 uicore.animations.FadeTo(obj=uicore.layer.vgssuppress, startVal=uicore.layer.vgssuppress.opacity, endVal=0.7, duration=duration, callback=callback) 149 150 def DeactivateSuppressLayer(self, duration = 0.25, callback = None): 151 uicore.layer.vgssuppress.state = uiconst.UI_DISABLED 152 uicore.animations.FadeOut(uicore.layer.vgssuppress, duration=duration, sleep=True, callback=callback) 153 154 def Search(self, searchString): 155 if self._SearchTasklet is not None: 156 with _SearchLock: 157 if self._SearchTasklet is not None: 158 self._SearchTasklet.kill() 159 self._SearchTasklet = uthread.new(self._Search, searchString) 160 161 def _GetViewTime(self): 162 return blue.os.GetWallclockTime() - self.viewOpenedTimer 163 164 def FormatTimeInterval(self, time): 165 return localization.formatters.FormatTimeIntervalShortWritten(time, showFrom='day') 166 167 def _Search(self, searchString): 168 blue.pyos.synchro.SleepWallclock(280) 169 with _SearchLock: 170 offers = self.store.SearchOffers(searchString) 171 self._LogSearch(searchString) 172 self.storeContainer.SetOffers(offers) 173 174 def _LogStoreEvent(self, columnNames, eventName, *args): 175 with ExceptionEater('eventLog'): 176 uthread.new(sm.ProxySvc('eventLog').LogClientEvent, 'store', columnNames, eventName, *args) 177 178 def _LogPurchase(self, offerID, quantity, success): 179 self._LogStoreEvent(['offerID', 180 'quantity', 181 'success', 182 'viewTime'], 'Purchase', offerID, quantity, success, self._GetViewTime()) 183 184 def _LogPurchaseGift(self, offerID, quantity, success, toCharacterID, isGametime = False): 185 self._LogStoreEvent(['offerID', 186 'quantity', 187 'success', 188 'toCharacterID', 189 'isGametime', 190 'viewTime'], 'PurchaseGift', offerID, quantity, success, toCharacterID, isGametime, self.FormatTimeInterval(self._GetViewTime())) 191 192 def _LogOpenOffer(self, offerID): 193 self._LogStoreEvent(['offerID', 'viewTime'], 'OpenOffer', offerID, self._GetViewTime()) 194 195 def _LogBannerClick(self, imageUrl, actionKey, actionValue): 196 self._LogStoreEvent(['imageUrl', 197 'actionKey', 198 'actionValue', 199 'viewTime'], 'BannerClick', imageUrl, actionKey, actionValue, self._GetViewTime()) 200 201 def _LogBuyPlex(self, location): 202 self._LogStoreEvent(['aurumBalance', 'location', 'viewTime'], 'BuyAurum', get_repository().get_balance(), location, self._GetViewTime()) 203 204 def _LogFilterChange(self, filterName): 205 self._LogStoreEvent(['filterName', 'viewTime'], 'FilterChange', filterName, self._GetViewTime()) 206 207 def _LogSearch(self, searchString): 208 self._LogStoreEvent(['searchString', 'viewTime'], 'search', searchString, self._GetViewTime())