Adobe Air Application How to clear the data? - actionscript-3

We are migrating out Adobe Flex application to Adobe Air application and lots of feature are working fine .But the main issue which we are getting how to clear all the data/record/session after logout?
Login the Adobe Air application with userid/password .
After Successful login just go any menu item .
Click the logout button.
User redirect to login page.
User login again it will show same Window from where user did logout with all the data.
So in Adobe Air how to clear the session data or how to clear all the component when user going to logout?

I add here, as you want, a snippet of code about logout from application:
public function logoutApplication(isSessionDown:Boolean=false):void
{
// This method close other open windows (because in AIR you can open more than one window)
closeOtherWindows();
// Here I want to manage a sessionExpired variable in model locator so I can use for further aim
if (CoreML.getInstance()!=null && CoreML.getInstance().sessionExpired){
ModelLocator.getInstance().sessionExpired=true;
CoreML.getInstance().sessionExpired=false;
}
// Here I remove all opened popup
var listPopUp:IChildList = FlexGlobals.topLevelApplication.systemManager.popUpChildren;
for (var i:int = 0; i < listPopUp.numChildren; i++) {
var curr:IFlexDisplayObject = listPopUp.getChildAt(i) as IFlexDisplayObject;
try {
if (curr != null) {
PopUpManager.removePopUp(curr);
}
}
catch(ex:ExceptionFrontEndHandler) {
// If you arrive here, it isn't a popup
}
}
// here I update my component menu (it's business logic is not important)
if (this.cntComponentMenu != null) {
var newMenuComp:ComponentMenu = new ComponentMenu();
newMenuComp.container=this;
this.cntComponentMenu.removeAllElements();
this.cntComponentMenu.addElement(newMenuComp);
}
// Here I change the state of my main MXML to login and clean the text box (not binded with BO)
this.currentState='login';
if (this.cntLogin!=null){
this.cntLogin.currentState='State1';
this.cntLogin.validateNow();
this.cntLogin.userId.text="";
this.cntLogin.password.text="";
}
if (!isSessionDown) EnvDispatcher.resetInfoSession(this);
else mypackage.ModelLocator.getInstance().logout=true;
}
Here the code in result command of EnvDispatcher.resetInfoSession:
if (this.evt.sender!=null && this.evt.sender is UncertaintyAIR) {
var pnl:MyApplication = this.evt.sender as MyApplication;
pnl.currentState='login';
pnl.validateNow();
pnl.groupLogin.removeAllElements();
LoginDispatcher.logout();
LoginDispatcher.logoutSecure();
mypackage.ModelLocator.getInstance().logout=true;
var loginView:LoginView = new LoginView();
loginView.container=pnl;
pnl.groupLogin.addElement(loginView);
}

Related

Update Google Calendar UI after changing visability setting via Workspace Add-On

I have a very basic Google Workspace Add-on that uses the CalendarApp class to toggle the visabilty of a calendar’s events when a button is pressed, using the setSelected() method
The visabilty toggling works, but the change in only reflected in the UI when the page is refreshed. Toggling the checkbox manually in the UI reflects the change immediately without needing to refresh the page.
Is there a method to replicate this immediate update behaviour via my Workspace Add-On?
A mwe is below.
function onDefaultHomePageOpen() {
// create button
var action = CardService.newAction().setFunctionName('toggleCalVis')
var button = CardService.newTextButton()
.setText("TOGGLE CAL VIS")
.setOnClickAction(action)
.setTextButtonStyle(CardService.TextButtonStyle.FILLED)
var buttonSet = CardService.newButtonSet().addButton(button)
// create CardSection
var section = CardService.newCardSection()
.addWidget(buttonSet)
// create card
var card = CardService.newCardBuilder().addSection(section)
// call CardBuilder.call() and return card
return card.build()
}
function toggleCalVis() {
// fetch calendar with UI name "foo"
var calendarName = "foo"
var calendarsByName = CalendarApp.getCalendarsByName(calendarName)
var namedCalendar = calendarsByName[0]
// Toggle calendar visabilty in the UI
if (namedCalendar.isSelected()) {
namedCalendar.setSelected(false)
}
else {
namedCalendar.setSelected(true)
}
}
In short: Create a chrome extension
(2021-sep-2)Reason: The setSelected() method changes ONLY the data on server. To apply the effect of it, you need to refresh the page. But Google Workspace Extension "for security reason" does not allow GAS to do that. However in an Chrome Extension you can unselect the checkbox of visibility by plain JS. (the class name of the left list is encoded but stable for me.) I have some code for Chrome Extension to select the nodes although I didn't worked it out(see last part).
(2021-jul-25)Worse case: Default calendars won't be selected by getAllCalendars(). I just tried the same thing as you mentioned, and the outcome is worse. I wanted to hide all calendars, and I am still pretty sure the code is correct, since I can see the calendar names in the console.
const allCals = CalendarApp.getAllCalendars()
allCals.forEach(cal => {console.log(`unselected ${cal.setSelected(false).getName()}`)})
Yet, the principle calendar, reminder calendar, and task calendar are not in the console.
And google apps script dev should ask themselves: WHY DO PEOPLE USE Calendar.setSelected()? We don't want to hide the calendar on the next run.
In the official document, none of these two behaviour is mentioned.
TL;DR part (My reason for not using GAS)
GAS(google-apps-script) has less functionality. For what I see, google is trying to build their own eco-system, but everything achievable in GAS is also available via javascript. I can even use typescript and do whatever I want by creating an extension.
GAS is NOT easy to learn. The learning was also painful, I spent 4 hours to build the first sample card, and I can interact correctly with the opened event after 9 hours. The documentation is far from finished.
GAS is poorly supported. The native web-based code editor (https://script.google.com/) is not build for coding real apps, it loses the version control freedom in new interface. And does not support cross-file search. Instead of import, codes run from top to bottom in the list, which you need to find that by yourself. (pass along no extension, no prettier, I can tolerate these)
In comparison with other online JS code editors, like codepen / code sandbox / etcetera it does so less function. Moreover, VSCode also has a online version now(github codespaces).
I hope my 13 hours in GAS are not totally wasted. As least whoever read this can just avoid suffering the same painful test.
Here's the code(typescript) for disable all the checks in Chrome.
TRACKER_CAL_ID_ENCODED is the calendar ID of which I don't want to uncheck. Since it is not the major part of this question, it is not very carefully commented.
(line update: 2022-jan-31) Aware that the mutationsList.length >= 3 is not accurate, I cannot see how mutationsList.length works.
Extension:
getSelectCalendarNode()
.then(unSelectCalendars)
function getSelectCalendarNode() {
return new Promise((resolve) => {
document.onreadystatechange = function () {
if (document.readyState == "complete") {
const leftSidebarNode = document.querySelector(
"div.QQYuzf[jsname=QA0Szd]"
)!;
new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.target) {
let _selectCalendarNode = document.querySelector("#dws12b.R16x0");
// customized calendars will start loading on 3th+ step, hence 3, but when will they stop loading? I didn't work this out
if (mutationsList.length >= 3) {
// The current best workaround I saw is setTimeout after loading event... There's no event of loading complete.
setTimeout(() => {
observer.disconnect();
resolve(_selectCalendarNode);
}, 1000);
}
}
}
}).observe(leftSidebarNode, { childList: true, subtree: true });
}
};
});
}
function unSelectCalendars(selectCalendarNode: unknown) {
const selcar = selectCalendarNode as HTMLDivElement;
const calwrappers = selcar.firstChild!.childNodes; // .XXcuqd
for (const calrow of calwrappers) {
const calLabel = calrow.firstChild!.firstChild as HTMLLabelElement;
const calSelectWrap = calLabel.firstChild!;
const calSelcted =
(calSelectWrap.firstChild!.firstChild! as HTMLDivElement).getAttribute(
"aria-checked"
) == "true"
? true
: false;
// const calNameSpan = calSelectWrap.nextSibling!
// .firstChild! as HTMLSpanElement;
// const calName = calNameSpan.innerText;
const encodedCalID = calLabel.getAttribute("data-id")!; // const decodedCalID = atob(encodedCalID);
if ((encodedCalID === TRACKER_CAL_ID_ENCODED) !== calSelcted) {
//XOR
calLabel.click();
}
}
console.log(selectCalendarNode);
return;
}
There is no way to make a webpage refresh with Google Apps Script
Possible workarounds:
From the sidebar, provide users a link that redirects them to the Calendar UI webpage (thus a new, refreshed version of it will be opened)
Install a Goole Chrome extension that refreshes the tab in specified intervals

window.addEventListener is not working on a user click on the browser back button in polymer 2.0?

window.addEventListener('popstate', function(event) {
alert("you are not able to push back button");
});
I have create the web application using polymer 2.0 but I have to click on the back button to the browser is logout I have to show the alert if the user is click on the back button of the browser I have tried window.addEventListener but still got error.
I've not been able to stop the browser's back button, but I've managed to get around it. In my app, I want to warn the user that they will log out by backing up to the first page, and give them a chance to leave or stay put. Using the polymer-2-starter-kit as my starting point, and tracking a connected property, I got this working:
_routePageChanged(page) {
// If no page was found in the route data, page will be an empty string.
// Default to 'home' in that case.
this.page = (page && this.connected) ? page : 'home';
// Close the drawer.
this.drawerOpened = false;
}
_pageChanged(page, oldPage) {
// Warn user if backing up logs out.
if ((page == '' || page == 'home') && this.connected) {
if (window.confirm("Do you really mean to logout?")) {
this.$.xhrLogout.generateRequest();
} else {
window.history.forward();
}
}
const resolvedPageUrl = this.resolveUrl('my-' + page + '.html');
Polymer.importHref(
resolvedPageUrl,
null,
this._showPage404.bind(this),
true);
}
So if the user is connected, and navigates to the initial page, I can force them to stay on the page where they were with window.history.forward().

Add 1 to variable Starting from random number AS3

I am in the process of creating an interactive map which gives users the option of clicking on a random site, viewing the content and then either going back to the overview, or continuing on to the next site.
I am having trouble adding 1 to the site number, when the users click "next site". Instead of continuing on to the next site, it goes on from a random number.
My code for the view site button
vmsite1.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandlervmsite1);
function mouseDownHandlervmsite1(event:MouseEvent):void
{
gotoAndStop(33); // WHERE THE DYNAMIC CONTENT LOADS
var siteNumber = 1;
}
My code for the next button:
next_site1.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandlernext_site1);
function mouseDownHandlernext_site1(event:MouseEvent):void
{
siteNumber = siteNumber;
if (siteNumber <= 29) {
siteNumber ++;
}
else {
siteNumber = siteNumber;
}
// UNLOAD THE PREVIOUS SLIDE SHOW
myLoader.unload();
SiteNumberText1.text = siteNumber.toString();
site1scroll.scrollTarget = field;
loadData();
// LOAD THE SLIDE SHOW
var urlforswfcomp2:URLRequest = new URLRequest(URLSWF + siteNumber + imgext);
myLoader.load(urlforswfcomp2);
}
I have had a look through the AS3 guide on the Adobe website, but I can't find an issue similar to mine.
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7fcf.html
http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/operators.html
Thanks in Advance!
I moved my siteNumber variable definition outside the button code, and it worked. This is my new view more button code.
var siteNumber:int = 0;
vmsite1.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandlervmsite1);
function mouseDownHandlervmsite1(event:MouseEvent):void
{
gotoAndStop(33);
siteNumber = 1
}

Dynamic embedded dashboard height in GoodData

I am trying to embed GoodData dashboard to an iframe in my application and it works well but each tab on that dashboard has different number of reports on it and I'd like to make the iframe height dynamic based on the actual dashboard content.
Is there a way how to do it? Does GoodData somehow propagate the space needed to render the dashboard?
Thank you.
In fact there is a postMessage() sent event called 'ui.frameinfo' which you could use to detect the dashboard tab height (when using dashboard.html). It is sent every time the tab changes its height.
The following listener should print out the iframe's internal height:
window.addEventListener('message', function(e) {
var message;
try {
message = JSON.parse(e.data);
} catch (e) {
// valid messages are JSON
message = {};
}
// drop other than GoodData events
if (!message.gdc) return;
if (message.gdc.name === 'ui.frameinfo') {
console.log('frame height:', message.gdc.data.height);
}
}
Note that this is not an official feature (yet) and potentially subject to change.

Create Context Menu with MDM Zinc

I have the following in the main function of my Flash application but when I publish this with MDM Zinc, I still get the default Flash right-click context menu.
var openFileMenuItem:String = "Open";
var closeFileMenUItem:String = "Close File";
var exitMenuItem:String = "Quit MyApplication";
mdm.Menu.Context.onContextMenuClick = onContextMenuClickHandler;
mdm.Menu.Context.enable();
mdm.Menu.Context.insertItem(openFileMenuItem);
mdm.Menu.Context.insertItem(closeFileMenUItem);
mdm.Menu.Context.insertDivider();
mdm.Menu.Context.insertItem(exitMenuItem);
function onContextMenuClickHandler(event:mdm.Event):void
{
switch(event.data.name)
{
case openFileMenuItem:
mdm.Dialogs.prompt("open");
break;
case closeFileMenUItem:
mdm.Dialogs.prompt("close");
break;
case exitMenuItem:
mdm.Dialogs.prompt("exit");
break;
};
}
The above should work as it is pretty well taken from the online documentation for MDM Zinc, but I just get the default Flash context menu. Is there anything else I have to do?
There is a property in MDM Zinc called "Allow Right Click". This needs to be set to "False" for the custom context menu to be displayed!