| // Copyright (C) 2023 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| import {Disposable} from '../base/disposable'; |
| import {globals} from '../frontend/globals'; |
| import {runQueryInNewTab} from '../frontend/query_result_tab'; |
| import {TrackPredicate, Viewer} from '../public'; |
| |
| import {Actions} from './actions'; |
| |
| class SidebarImpl { |
| hide() { |
| globals.dispatch(Actions.setSidebar({ |
| visible: false, |
| })); |
| } |
| |
| show() { |
| globals.dispatch(Actions.setSidebar({ |
| visible: true, |
| })); |
| } |
| |
| isVisible() { |
| return globals.state.sidebarVisible; |
| } |
| }; |
| |
| class TracksImpl { |
| pin(predicate: TrackPredicate) { |
| const tracks = Object.values(globals.state.tracks); |
| for (const track of tracks) { |
| const tags = { |
| name: track.name, |
| }; |
| if (predicate(tags) && !this.isPinned(track.key)) { |
| globals.dispatch(Actions.toggleTrackPinned({ |
| trackKey: track.key, |
| })); |
| } |
| } |
| } |
| |
| unpin(predicate: TrackPredicate) { |
| const tracks = Object.values(globals.state.tracks); |
| for (const track of tracks) { |
| const tags = { |
| name: track.name, |
| }; |
| if (predicate(tags) && this.isPinned(track.key)) { |
| globals.dispatch(Actions.toggleTrackPinned({ |
| trackKey: track.key, |
| })); |
| } |
| } |
| } |
| |
| private isPinned(trackId: string): boolean { |
| return globals.state.pinnedTracks.includes(trackId); |
| } |
| }; |
| |
| export class ViewerImpl implements Viewer { |
| sidebar = new SidebarImpl(); |
| tracks = new TracksImpl(); |
| |
| tabs = { |
| openQuery: runQueryInNewTab, |
| }; |
| |
| commands = { |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| run: (id: string, ...args: any[]) => { |
| globals.commandManager.runCommand(id, ...args); |
| }, |
| }; |
| |
| constructor() {} |
| |
| getProxy(pluginId: string): ViewerProxy { |
| return new ViewerProxy(this, pluginId); |
| } |
| } |
| |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| type AnyFunction = (...args: any[]) => any; |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| type AnyProcedure = (...args: any[]) => void; |
| |
| function wrap<F extends AnyFunction>( |
| allow: () => boolean, f: F, deadResult: ReturnType<F>) { |
| return (...args: Parameters<F>) => { |
| if (allow()) { |
| return f(...args); |
| } else { |
| return deadResult; |
| } |
| }; |
| } |
| |
| function wrapVoid<F extends AnyProcedure>(allow: () => boolean, f: F) { |
| return (...args: Parameters<F>) => { |
| if (allow()) { |
| f(...args); |
| } |
| }; |
| } |
| |
| export class ViewerProxy implements Viewer, Disposable { |
| readonly parent: ViewerImpl; |
| readonly pluginId: string; |
| private alive: boolean; |
| |
| // ViewerImpl: |
| sidebar: Viewer['sidebar']; |
| tracks: Viewer['tracks']; |
| tabs: Viewer['tabs']; |
| commands: Viewer['commands']; |
| |
| // ViewerProxy: |
| constructor(parent: ViewerImpl, pluginId: string) { |
| this.parent = parent; |
| this.pluginId = pluginId; |
| this.alive = true; |
| const allow = () => this.alive; |
| |
| const p = parent; |
| this.sidebar = { |
| hide: wrapVoid(allow, p.sidebar.hide.bind(p.sidebar)), |
| show: wrapVoid(allow, p.sidebar.show.bind(p.sidebar)), |
| isVisible: wrap(allow, p.sidebar.isVisible.bind(p.sidebar), false), |
| }; |
| |
| this.tracks = { |
| pin: wrapVoid(allow, p.tracks.pin.bind(p.tracks)), |
| unpin: wrapVoid(allow, p.tracks.unpin.bind(p.tracks)), |
| }; |
| |
| this.tabs = { |
| openQuery: wrapVoid(allow, p.tabs.openQuery.bind(p.tabs)), |
| }; |
| |
| this.commands = { |
| run: wrapVoid(allow, p.commands.run.bind(p.commands)), |
| }; |
| } |
| |
| dispose(): void { |
| this.alive = false; |
| } |
| } |