config.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { Structure, Model } from '../mol-model/structure';
  8. import { PluginContext } from './context';
  9. import { PdbDownloadProvider } from '../mol-plugin-state/actions/structure';
  10. import { EmdbDownloadProvider } from '../mol-plugin-state/actions/volume';
  11. import { StructureRepresentationPresetProvider } from '../mol-plugin-state/builder/structure/representation-preset';
  12. export class PluginConfigItem<T = any> {
  13. toString() { return this.key; }
  14. valueOf() { return this.key; }
  15. constructor(public key: string, public defaultValue?: T) { }
  16. }
  17. function item<T>(key: string, defaultValue?: T) { return new PluginConfigItem(key, defaultValue); }
  18. function preferWebGl1() {
  19. if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;
  20. // WebGL2 isn't working in MacOS 12.0.1 Safari 15.1 (but is working in Safari tech preview)
  21. // prefer webgl 1 based on the userAgent substring
  22. if (navigator.userAgent.indexOf('Version/15.1 Safari') > 0) {
  23. return true;
  24. }
  25. // Check for iOS device which enabled WebGL2 recently but it doesn't seem
  26. // to be full up to speed yet.
  27. // adapted from https://stackoverflow.com/questions/9038625/detect-if-device-is-ios
  28. const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
  29. const isAppleDevice = navigator.userAgent.includes('Macintosh');
  30. const isTouchScreen = navigator.maxTouchPoints >= 4; // true for iOS 13 (and hopefully beyond)
  31. return !(window as any).MSStream && (isIOS || (isAppleDevice && isTouchScreen));
  32. }
  33. export const PluginConfig = {
  34. item,
  35. General: {
  36. IsBusyTimeoutMs: item('plugin-config.is-busy-timeout', 750),
  37. DisableAntialiasing: item('plugin-config.disable-antialiasing', false),
  38. DisablePreserveDrawingBuffer: item('plugin-config.disable-preserve-drawing-buffer', false),
  39. PixelScale: item('plugin-config.pixel-scale', 1),
  40. PickScale: item('plugin-config.pick-scale', 0.25),
  41. PickPadding: item('plugin-config.pick-padding', 3),
  42. EnableWboit: item('plugin-config.enable-wboit', true),
  43. // as of Oct 1 2021, WebGL 2 doesn't work on iOS 15.
  44. // TODO: check back in a few weeks to see if it was fixed
  45. PreferWebGl1: item('plugin-config.prefer-webgl1', preferWebGl1()),
  46. },
  47. State: {
  48. DefaultServer: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state'),
  49. CurrentServer: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state'),
  50. HistoryCapacity: item('history-capacity.server', 5)
  51. },
  52. VolumeStreaming: {
  53. Enabled: item('volume-streaming.enabled', true),
  54. DefaultServer: item('volume-streaming.server', 'https://ds.litemol.org'),
  55. CanStream: item('volume-streaming.can-stream', (s: Structure, plugin: PluginContext) => {
  56. return s.models.length === 1 && Model.probablyHasDensityMap(s.models[0]);
  57. }),
  58. EmdbHeaderServer: item('volume-streaming.emdb-header-server', 'https://ftp.wwpdb.org/pub/emdb/structures'),
  59. },
  60. Viewport: {
  61. ShowExpand: item('viewer.show-expand-button', true),
  62. ShowControls: item('viewer.show-controls-button', true),
  63. ShowSettings: item('viewer.show-settings-button', true),
  64. ShowSelectionMode: item('viewer.show-selection-model-button', true),
  65. ShowAnimation: item('viewer.show-animation-button', true),
  66. },
  67. Download: {
  68. DefaultPdbProvider: item<PdbDownloadProvider>('download.default-pdb-provider', 'pdbe'),
  69. DefaultEmdbProvider: item<EmdbDownloadProvider>('download.default-emdb-provider', 'pdbe'),
  70. },
  71. Structure: {
  72. SizeThresholds: item('structure.size-thresholds', Structure.DefaultSizeThresholds),
  73. DefaultRepresentationPresetParams: item<StructureRepresentationPresetProvider.CommonParams>('structure.default-representation-preset-params', { })
  74. }
  75. };
  76. export class PluginConfigManager {
  77. private _config = new Map<PluginConfigItem<any>, unknown>();
  78. get<T>(key: PluginConfigItem<T>) {
  79. if (!this._config.has(key)) return key.defaultValue;
  80. return this._config.get(key) as T;
  81. }
  82. set<T>(key: PluginConfigItem<T>, value: T) {
  83. this._config.set(key, value);
  84. }
  85. delete<T>(key: PluginConfigItem<T>) {
  86. this._config.delete(key);
  87. }
  88. constructor(initial?: [PluginConfigItem, unknown][]) {
  89. if (!initial) return;
  90. initial.forEach(([k, v]) => this._config.set(k, v));
  91. }
  92. }