Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Research app selection messaging #133

Merged
merged 11 commits into from
Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
49 changes: 49 additions & 0 deletions research-app-messages/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,52 @@ export function isPingPongMessage(o: any): o is PingPongMessage { // eslint-dis
typeof o.threadId === "string" &&
(o.sessionId === undefined || typeof o.sessionId === "string");
}

/** Information about the current state of source and catalog selection
* inside the WWT application
*
* This message is broadcasted by the application whenever one of the user's selection
* options inside of the application is adjusted. The Vue listeners for the selected
* catalogs and sources are deep listeners, meaning that this message will be broadcasted
* whenever a property of one of their items changes.
*
* Not all fields of this message will always be present, depending on the
* nature of the event triggering the emission of this message. A message
* missing a particular field should be treated as conveying no information
* about the state described by that field.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Er, I think this docstring needs to be relocated?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep - this got left behind when I was moving things into selections.ts.


export interface SelectionStateMessage {

/** The tag identifying this message type. */
type: "wwt_selection_state";

/** An app/client session identifier.
*
* If a single client is communicating with multiple apps, it needs to be able
* to tell which app is the source of any update messages. This session
* identifier allows clients to do so. The default value is "default". But if
* a client sends a [[PingPongMessage]] with a customized ``sessionId`` field,
* that value will start appearing in these view state update messages.
*/
sessionId: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

The whitespace here has gotten wonky somehow.


/** The most recent source that was added to the selection list. */
mostRecentSource?: string;

/** The list of HiPS catalogs that are currently selected. */
selectedCatalogs?: string[];

/** The list of sources that are currently selected. */
selectedSources?: string[];
}

/** Type guard function for [[SelectionStateMessage]] */
export function isSelectionStateMessage(o: any): o is SelectionStateMessage { // eslint-disable-line @typescript-eslint/no-explicit-any
return typeof o.type === "string" &&
o.type == "wwt_selection_state" &&
typeof o.threadId === "string" &&
(o.sessionId === undefined || typeof o.sessionId === "string") &&
(o.mostRecentSource === undefined || typeof o.mostRecentSource === "string") &&
(o.selectedSources === undefined || typeof o.selectedSources === "string");
Copy link
Contributor

Choose a reason for hiding this comment

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

There are some problems here — there's no threadId in the message and some of the types here should be array types. But overall, since this is an outgoing message, we don't have TypeScript code that needs to do rigorous checking of the message structure, so I think we should be able to skip this function altogether.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, various issues aside, you're right - we don't need this.

}
55 changes: 55 additions & 0 deletions research-app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ import {
layers,
settings,
ApplicationStateMessage,
SelectionStateMessage,
ViewStateMessage,
} from "@wwtelescope/research-app-messages";

Expand Down Expand Up @@ -876,6 +877,7 @@ export default class App extends WWTAwareComponent {
defaultColor = Color.fromArgb(1, 255, 255, 255);
wwtComponentNamespace = wwtEngineNamespace;
lastClosePt: Source | null = null;
lastSelectedSource: Source | null = null;
distanceThreshold = 0.01;
hideAllChrome = false;
hipsUrl = "http://www.worldwidetelescope.org/wwtweb/catalog.aspx?W=hips"; // Temporary
Expand Down Expand Up @@ -1307,6 +1309,7 @@ export default class App extends WWTAwareComponent {
name: this.nameForSource(this.lastClosePt),
};
this.addSource(source);
this.lastSelectedSource = source;
}
this.isMouseMoving = false;
}
Expand Down Expand Up @@ -1755,6 +1758,58 @@ export default class App extends WWTAwareComponent {
this.statusMessageDestination.postMessage(msg, this.allowedOrigin);
}

@Watch("lastSelectedSource")
onLastSelectedSourceChanged(source: Source) {
// Notify clients when a source is selected

if (this.statusMessageDestination === null || this.allowedOrigin === null)
return;

const msg: SelectionStateMessage = {
type: "wwt_selection_state",
sessionId: this.statusMessageSessionId,
mostRecentSource: JSON.stringify(source),
};

this.statusMessageDestination.postMessage(msg, this.allowedOrigin);
}

@Watch("hipsCatalogs", {deep:true})
onSelectedCatalogsChanged(catalogs: ImagesetInfo[]) {
// Notify clients when the list of selected catalogs is changed
// By making this a deep watcher, it keeps of track of any change
// in the list - even events like a property of a list entry changing

if (this.statusMessageDestination === null || this.allowedOrigin === null)
return;

const msg: SelectionStateMessage = {
type: "wwt_selection_state",
sessionId: this.statusMessageSessionId,
selectedCatalogs: catalogs.map(catalog => JSON.stringify(catalog)),
};

this.statusMessageDestination.postMessage(msg, this.allowedOrigin);
}

@Watch("sources", {deep:true})
onSelectedSourcesChanged(sources: Source[]) {
// Notify clients when the list of selected sources is changed
// By making this a deep watcher, it keeps of track of any change
// in the list - even events like a property of a list entry changing

if (this.statusMessageDestination === null || this.allowedOrigin === null)
return;

const msg: SelectionStateMessage = {
type: "wwt_selection_state",
sessionId: this.statusMessageSessionId,
selectedSources: sources.map(source => JSON.stringify(source)),
};

this.statusMessageDestination.postMessage(msg, this.allowedOrigin);
}

// A client has requested that we load a HiPS catalog. Once it's loaded we
// reply to the client with the details of the catalog-as-spreadsheet-layer,
// so that it can know what the catalog's characteristics are.
Expand Down