ooxml-ui 1.14.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +139 -2
- package/dist/{chunk-LAVVSCRJ.js → chunk-CHFMXUPK.js} +195 -12
- package/dist/chunk-GSWCAZQ3.js +3533 -0
- package/dist/{chunk-C3MXKNNK.js → chunk-JVNIZBG7.js} +1462 -781
- package/dist/{chunk-C5F7454A.js → chunk-QUG6IRQQ.js} +2 -2
- package/dist/{chunk-DSQBXLMO.js → chunk-UIVYZERK.js} +1 -1
- package/dist/controls.d.ts +1 -1
- package/dist/controls.d.ts.map +1 -1
- package/dist/controls.js +1 -1
- package/dist/docx.js +3 -3
- package/dist/index.js +5 -5
- package/dist/pptx/{chart-3d-view-scene-CFUVOILD.cjs → chart-3d-view-scene-3HDRDXX6.cjs} +38 -38
- package/dist/pptx/{chart-3d-view-scene-BEAJCQIS.mjs → chart-3d-view-scene-NMFMG76N.mjs} +2 -2
- package/dist/pptx/{chunk-5UGJC25J.cjs → chunk-3DGTZWI5.cjs} +1 -1
- package/dist/pptx/{chunk-4NBVWV6I.cjs → chunk-A2X5BP7J.cjs} +581 -0
- package/dist/pptx/{chunk-2JTHIDMD.cjs → chunk-CEH63AZB.cjs} +1172 -85
- package/dist/pptx/{chunk-DWUC6LZK.mjs → chunk-GCHJRKXZ.mjs} +10 -30
- package/dist/pptx/{chunk-VXKFXPCU.mjs → chunk-HL53SH7C.mjs} +1169 -86
- package/dist/pptx/{chunk-5DUBDWOU.cjs → chunk-KTHBMVMQ.cjs} +10436 -6294
- package/dist/pptx/{chunk-HULZNSHL.cjs → chunk-L2LK7TEC.cjs} +19 -40
- package/dist/pptx/{chunk-GUAP5VUN.mjs → chunk-RACO4FQT.mjs} +9643 -5546
- package/dist/pptx/{chunk-P3YE5LT2.mjs → chunk-XOMYHWQ3.mjs} +1 -1
- package/dist/pptx/{chunk-OJXPN2WX.mjs → chunk-ZNXKAINY.mjs} +581 -0
- package/dist/pptx/dom/element-styles.d.ts.map +1 -1
- package/dist/pptx/dom/elements/chart-editable.d.ts +11 -0
- package/dist/pptx/dom/elements/chart-editable.d.ts.map +1 -1
- package/dist/pptx/dom/elements/chart.d.ts.map +1 -1
- package/dist/pptx/dom/index.cjs +278 -265
- package/dist/pptx/dom/index.mjs +37 -25
- package/dist/pptx/export/html2canvas-clone.cjs +2 -2
- package/dist/pptx/export/html2canvas-clone.mjs +1 -1
- package/dist/pptx/i18n/index.cjs +6 -6
- package/dist/pptx/i18n/index.mjs +1 -1
- package/dist/pptx/i18n/translations-en-chart-format.d.ts +3 -0
- package/dist/pptx/i18n/translations-en-chart-format.d.ts.map +1 -0
- package/dist/pptx/i18n/translations-en-compare.d.ts +3 -0
- package/dist/pptx/i18n/translations-en-compare.d.ts.map +1 -0
- package/dist/pptx/i18n/translations-en-design-galleries.d.ts +3 -0
- package/dist/pptx/i18n/translations-en-design-galleries.d.ts.map +1 -0
- package/dist/pptx/i18n/translations-en-galleries-smartart-layouts.d.ts +6 -0
- package/dist/pptx/i18n/translations-en-galleries-smartart-layouts.d.ts.map +1 -0
- package/dist/pptx/i18n/translations-en-shape-gallery.d.ts +7 -0
- package/dist/pptx/i18n/translations-en-shape-gallery.d.ts.map +1 -0
- package/dist/pptx/i18n/translations-en.d.ts.map +1 -1
- package/dist/pptx/index.cjs +3338 -3146
- package/dist/pptx/index.mjs +6 -6
- package/dist/pptx/render/chart-axis-primitives.d.ts.map +1 -1
- package/dist/pptx/render/chart-canvas-drag.d.ts.map +1 -1
- package/dist/pptx/render/chart-cartesian-bars.d.ts.map +1 -1
- package/dist/pptx/render/chart-category-axis.d.ts.map +1 -1
- package/dist/pptx/render/chart-combo-stock.cjs +3 -3
- package/dist/pptx/render/chart-combo-stock.mjs +1 -1
- package/dist/pptx/render/chart-date-axis.d.ts.map +1 -1
- package/dist/pptx/render/chart-format/chart-area-outer-effects.d.ts +20 -0
- package/dist/pptx/render/chart-format/chart-area-outer-effects.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-3d-svg.d.ts +23 -0
- package/dist/pptx/render/chart-format/chart-format-3d-svg.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-context-menu.d.ts +11 -0
- package/dist/pptx/render/chart-format/chart-format-context-menu.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-effects-svg.d.ts +87 -0
- package/dist/pptx/render/chart-format/chart-format-effects-svg.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-fixtures.test-util.d.ts +10 -0
- package/dist/pptx/render/chart-format/chart-format-fixtures.test-util.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-geometry.d.ts +25 -0
- package/dist/pptx/render/chart-format/chart-format-geometry.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-hit-test.d.ts +42 -0
- package/dist/pptx/render/chart-format/chart-format-hit-test.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-paint-svg.d.ts +38 -0
- package/dist/pptx/render/chart-format/chart-format-paint-svg.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-3d.d.ts +13 -0
- package/dist/pptx/render/chart-format/chart-format-pane-3d.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-axis.d.ts +12 -0
- package/dist/pptx/render/chart-format/chart-format-pane-axis.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-common.d.ts +14 -0
- package/dist/pptx/render/chart-format/chart-format-pane-common.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-edit-extra.d.ts +28 -0
- package/dist/pptx/render/chart-format/chart-format-pane-edit-extra.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-edit.d.ts +18 -0
- package/dist/pptx/render/chart-format/chart-format-pane-edit.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-effects.d.ts +31 -0
- package/dist/pptx/render/chart-format/chart-format-pane-effects.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-fill-kinds.d.ts +15 -0
- package/dist/pptx/render/chart-format/chart-format-pane-fill-kinds.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-fill-line.d.ts +12 -0
- package/dist/pptx/render/chart-format/chart-format-pane-fill-line.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-model.d.ts +17 -0
- package/dist/pptx/render/chart-format/chart-format-pane-model.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-options.d.ts +13 -0
- package/dist/pptx/render/chart-format/chart-format-pane-options.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-text.d.ts +14 -0
- package/dist/pptx/render/chart-format/chart-format-pane-text.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-pane-types.d.ts +96 -0
- package/dist/pptx/render/chart-format/chart-format-pane-types.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-render-labels.d.ts +26 -0
- package/dist/pptx/render/chart-format/chart-format-render-labels.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-render-lines.d.ts +36 -0
- package/dist/pptx/render/chart-format/chart-format-render-lines.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-render-series.d.ts +30 -0
- package/dist/pptx/render/chart-format/chart-format-render-series.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-render-text.d.ts +28 -0
- package/dist/pptx/render/chart-format/chart-format-render-text.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-render.d.ts +26 -0
- package/dist/pptx/render/chart-format/chart-format-render.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-format-targets.d.ts +36 -0
- package/dist/pptx/render/chart-format/chart-format-targets.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/chart-selection-strip.d.ts +39 -0
- package/dist/pptx/render/chart-format/chart-selection-strip.d.ts.map +1 -0
- package/dist/pptx/render/chart-format/index.d.ts +16 -0
- package/dist/pptx/render/chart-format/index.d.ts.map +1 -0
- package/dist/pptx/render/chart-legend-layout.d.ts +3 -1
- package/dist/pptx/render/chart-legend-layout.d.ts.map +1 -1
- package/dist/pptx/render/chart-overlays.cjs +7 -7
- package/dist/pptx/render/chart-overlays.mjs +1 -1
- package/dist/pptx/render/chart-surface-treemap.cjs +4 -4
- package/dist/pptx/render/chart-surface-treemap.mjs +1 -1
- package/dist/pptx/render/chart-svg-primitives.d.ts +6 -0
- package/dist/pptx/render/chart-svg-primitives.d.ts.map +1 -1
- package/dist/pptx/render/chart-view-model-build.d.ts.map +1 -1
- package/dist/pptx/render/chart-view-model-dom.d.ts +17 -2
- package/dist/pptx/render/chart-view-model-dom.d.ts.map +1 -1
- package/dist/pptx/render/chart-view-model-types.d.ts +3 -0
- package/dist/pptx/render/chart-view-model-types.d.ts.map +1 -1
- package/dist/pptx/render/chart-view-model.cjs +44 -44
- package/dist/pptx/render/chart-view-model.mjs +1 -1
- package/dist/pptx/render/chart-waterfall-map.cjs +6 -6
- package/dist/pptx/render/chart-waterfall-map.mjs +1 -1
- package/dist/pptx/render/context-menu-commands.d.ts +6 -1
- package/dist/pptx/render/context-menu-commands.d.ts.map +1 -1
- package/dist/pptx/render/customization/customization-catalog.d.ts +1 -1
- package/dist/pptx/render/customization/customization-catalog.d.ts.map +1 -1
- package/dist/pptx/render/customization/customization-descriptions.d.ts.map +1 -1
- package/dist/pptx/render/customization/ribbon-control-catalog-core.d.ts +11 -1
- package/dist/pptx/render/customization/ribbon-control-catalog-core.d.ts.map +1 -1
- package/dist/pptx/render/customization/ribbon-control-catalog-tail.d.ts +10 -0
- package/dist/pptx/render/customization/ribbon-control-catalog-tail.d.ts.map +1 -1
- package/dist/pptx/render/customization/ribbon-control-catalog.d.ts +21 -1
- package/dist/pptx/render/customization/ribbon-control-catalog.d.ts.map +1 -1
- package/dist/pptx/render/deck-style.d.ts +126 -0
- package/dist/pptx/render/deck-style.d.ts.map +1 -0
- package/dist/pptx/render/editor-chrome/metrics.d.ts +7 -0
- package/dist/pptx/render/editor-chrome/metrics.d.ts.map +1 -1
- package/dist/pptx/render/frame-effect-style.d.ts +22 -0
- package/dist/pptx/render/frame-effect-style.d.ts.map +1 -0
- package/dist/pptx/render/index.d.ts +6 -0
- package/dist/pptx/render/index.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-design-commands.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-module.d.ts +2 -1
- package/dist/pptx/render/ribbon-galleries/gallery-module.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-placements.d.ts +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-placements.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-registry.d.ts +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-registry.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-types.d.ts +52 -3
- package/dist/pptx/render/ribbon-galleries/gallery-types.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/gallery-view.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/smartart-layouts-gallery.d.ts +5 -0
- package/dist/pptx/render/ribbon-galleries/smartart-layouts-gallery.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/theme-backgrounds-gallery.d.ts +7 -0
- package/dist/pptx/render/ribbon-galleries/theme-backgrounds-gallery.d.ts.map +1 -0
- package/dist/pptx/render/ribbon-galleries/theme-colors-gallery.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/theme-effects-gallery.d.ts +6 -0
- package/dist/pptx/render/ribbon-galleries/theme-effects-gallery.d.ts.map +1 -0
- package/dist/pptx/render/ribbon-galleries/theme-fonts-gallery.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-galleries/theme-variants-gallery.d.ts +32 -0
- package/dist/pptx/render/ribbon-galleries/theme-variants-gallery.d.ts.map +1 -0
- package/dist/pptx/render/ribbon-galleries/themes-gallery.d.ts +17 -0
- package/dist/pptx/render/ribbon-galleries/themes-gallery.d.ts.map +1 -0
- package/dist/pptx/render/ribbon-home-families-objects.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-home-families.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-home-menus.d.ts +1 -1
- package/dist/pptx/render/ribbon-home-menus.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-home-spec.d.ts +9 -1
- package/dist/pptx/render/ribbon-home-spec.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-home-state-objects.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-icons/chart-format-icons.d.ts +4 -0
- package/dist/pptx/render/ribbon-icons/chart-format-icons.d.ts.map +1 -0
- package/dist/pptx/render/ribbon-icons.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-insert-layout.d.ts.map +1 -1
- package/dist/pptx/render/ribbon-insert-state.d.ts +6 -0
- package/dist/pptx/render/ribbon-insert-state.d.ts.map +1 -1
- package/dist/pptx/render/shape-gallery-home.d.ts +6 -0
- package/dist/pptx/render/shape-gallery-home.d.ts.map +1 -0
- package/dist/pptx/render/shape-gallery.d.ts +51 -0
- package/dist/pptx/render/shape-gallery.d.ts.map +1 -0
- package/dist/pptx/render/slide-compare-text.d.ts +13 -0
- package/dist/pptx/render/slide-compare-text.d.ts.map +1 -0
- package/dist/pptx/render/slide-compare.d.ts +10 -0
- package/dist/pptx/render/slide-compare.d.ts.map +1 -1
- package/dist/pptx/render/table-style-presets.d.ts +2 -0
- package/dist/pptx/render/table-style-presets.d.ts.map +1 -1
- package/dist/pptx/render/text-3d-presets.d.ts +4 -0
- package/dist/pptx/render/text-3d-presets.d.ts.map +1 -1
- package/dist/pptx/render/text-warp-presets.d.ts +2 -0
- package/dist/pptx/render/text-warp-presets.d.ts.map +1 -1
- package/dist/pptx/render/toolbar-actions.d.ts +1 -1
- package/dist/pptx/render/toolbar-actions.d.ts.map +1 -1
- package/dist/pptx/render/visual-effects.d.ts.map +1 -1
- package/dist/pptx/theme/index.cjs +16 -16
- package/dist/pptx/theme/index.mjs +1 -1
- package/dist/pptx/web-components/chart-format-pane-fields.d.ts +17 -0
- package/dist/pptx/web-components/chart-format-pane-fields.d.ts.map +1 -0
- package/dist/pptx/web-components/chart-format-pane-styles.d.ts +3 -0
- package/dist/pptx/web-components/chart-format-pane-styles.d.ts.map +1 -0
- package/dist/pptx/web-components/chart-format-pane.d.ts +34 -0
- package/dist/pptx/web-components/chart-format-pane.d.ts.map +1 -0
- package/dist/pptx/web-components/index.d.ts +3 -1
- package/dist/pptx/web-components/index.d.ts.map +1 -1
- package/dist/pptx/web-components/mobile-insert-styles.d.ts +2 -0
- package/dist/pptx/web-components/mobile-insert-styles.d.ts.map +1 -0
- package/dist/pptx/web-components/mobile-insert.d.ts +21 -0
- package/dist/pptx/web-components/mobile-insert.d.ts.map +1 -0
- package/dist/pptx/web-components/ribbon-gallery.d.ts +11 -0
- package/dist/pptx/web-components/ribbon-gallery.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-home-controls.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-home-layout.d.ts +6 -0
- package/dist/pptx/web-components/ribbon-home-layout.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-home-menu.d.ts +1 -1
- package/dist/pptx/web-components/ribbon-home-menu.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-home-styles.d.ts +1 -1
- package/dist/pptx/web-components/ribbon-home-styles.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-home.d.ts +2 -0
- package/dist/pptx/web-components/ribbon-home.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-icons.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-insert-styles.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-insert-table-picker.d.ts +2 -0
- package/dist/pptx/web-components/ribbon-insert-table-picker.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-insert-view.d.ts.map +1 -1
- package/dist/pptx/web-components/ribbon-overflow.d.ts.map +1 -1
- package/dist/pptx/web-components/theme-editor-dock.d.ts +12 -1
- package/dist/pptx/web-components/theme-editor-dock.d.ts.map +1 -1
- package/dist/{presentation-preview-HVKJ3KJN.js → presentation-preview-HMEBDYEL.js} +1 -1
- package/dist/ribbon/gallery.d.ts +50 -0
- package/dist/ribbon/gallery.d.ts.map +1 -1
- package/dist/ribbon/ribbon-group.d.ts +1 -1
- package/dist/ribbon/ribbon-group.d.ts.map +1 -1
- package/dist/teams/activity-feed.d.ts +1 -1
- package/dist/teams/app/add-tab-dialog.d.ts +11 -10
- package/dist/teams/app/bind.d.ts +2 -0
- package/dist/teams/app/channel-tab.d.ts +3 -2
- package/dist/teams/app/chat-app.d.ts +2 -1
- package/dist/teams/app/content-preview.d.ts +3 -2
- package/dist/teams/app/create-channel-dialog.d.ts +3 -2
- package/dist/teams/app/draft-list.d.ts +2 -1
- package/dist/teams/app/file-actions.d.ts +3 -2
- package/dist/teams/app/files-panel.d.ts +3 -2
- package/dist/teams/app/followed-threads.d.ts +2 -1
- package/dist/teams/app/markdown-preview.d.ts +2 -1
- package/dist/teams/app/meeting-dialog.d.ts +11 -3
- package/dist/teams/app/message-transfers.d.ts +2 -1
- package/dist/teams/app/notify-delivery.d.ts +3 -2
- package/dist/teams/app/pinned-bar.d.ts +3 -2
- package/dist/teams/app/presentation-preview.d.ts +3 -2
- package/dist/teams/app/profile-menu.d.ts +12 -2
- package/dist/teams/app/repeat-text.d.ts +26 -0
- package/dist/teams/app/settings-density.d.ts +2 -1
- package/dist/teams/app/settings-notifications.d.ts +2 -1
- package/dist/teams/app/settings-search.d.ts +6 -4
- package/dist/teams/app/settings-theme.d.ts +2 -1
- package/dist/teams/app/sign-in-flow.d.ts +49 -0
- package/dist/teams/app/sign-in-strings.d.ts +4 -0
- package/dist/teams/app/teams-app.d.ts +12 -2
- package/dist/teams/app/teams-settings.d.ts +3 -2
- package/dist/teams/app/teams-sign-in.d.ts +57 -0
- package/dist/teams/app/thread-pane.d.ts +2 -1
- package/dist/teams/app/workbook-actions.d.ts +2 -1
- package/dist/teams/app-rail.d.ts +1 -0
- package/dist/teams/base.d.ts +25 -5
- package/dist/teams/calendar-view.d.ts +1 -0
- package/dist/teams/call-controls.d.ts +1 -0
- package/dist/teams/call-grid.d.ts +1 -0
- package/dist/teams/chat-list.d.ts +1 -0
- package/dist/teams/i18n/core-text.d.ts +3 -0
- package/dist/teams/i18n/describe.d.ts +4 -0
- package/dist/teams/i18n/lit-element.d.ts +16 -0
- package/dist/teams/i18n/locales/de/calendar.d.ts +2 -0
- package/dist/teams/i18n/locales/de/chat.d.ts +2 -0
- package/dist/teams/i18n/locales/de/core.d.ts +2 -0
- package/dist/teams/i18n/locales/de/files.d.ts +2 -0
- package/dist/teams/i18n/locales/de/settings.d.ts +2 -0
- package/dist/teams/i18n/locales/de/shell.d.ts +2 -0
- package/dist/teams/i18n/locales/de.d.ts +617 -0
- package/dist/teams/i18n/locales/en/calendar.d.ts +78 -0
- package/dist/teams/i18n/locales/en/chat.d.ts +109 -0
- package/dist/teams/i18n/locales/en/core.d.ts +34 -0
- package/dist/teams/i18n/locales/en/files.d.ts +128 -0
- package/dist/teams/i18n/locales/en/settings.d.ts +131 -0
- package/dist/teams/i18n/locales/en/shell.d.ts +146 -0
- package/dist/teams/i18n/locales/en.d.ts +617 -0
- package/dist/teams/i18n/locales/es/calendar.d.ts +2 -0
- package/dist/teams/i18n/locales/es/chat.d.ts +2 -0
- package/dist/teams/i18n/locales/es/core.d.ts +2 -0
- package/dist/teams/i18n/locales/es/files.d.ts +2 -0
- package/dist/teams/i18n/locales/es/settings.d.ts +2 -0
- package/dist/teams/i18n/locales/es/shell.d.ts +2 -0
- package/dist/teams/i18n/locales/es.d.ts +617 -0
- package/dist/teams/i18n/locales/fr/calendar.d.ts +2 -0
- package/dist/teams/i18n/locales/fr/chat.d.ts +2 -0
- package/dist/teams/i18n/locales/fr/core.d.ts +2 -0
- package/dist/teams/i18n/locales/fr/files.d.ts +2 -0
- package/dist/teams/i18n/locales/fr/settings.d.ts +2 -0
- package/dist/teams/i18n/locales/fr/shell.d.ts +2 -0
- package/dist/teams/i18n/locales/fr.d.ts +617 -0
- package/dist/teams/i18n/locales/zh-CN/calendar.d.ts +2 -0
- package/dist/teams/i18n/locales/zh-CN/chat.d.ts +2 -0
- package/dist/teams/i18n/locales/zh-CN/core.d.ts +2 -0
- package/dist/teams/i18n/locales/zh-CN/files.d.ts +2 -0
- package/dist/teams/i18n/locales/zh-CN/settings.d.ts +2 -0
- package/dist/teams/i18n/locales/zh-CN/shell.d.ts +2 -0
- package/dist/teams/i18n/locales/zh-CN.d.ts +617 -0
- package/dist/teams/i18n/runtime.d.ts +15 -0
- package/dist/teams/i18n/translator.d.ts +28 -0
- package/dist/teams.js +3 -3
- package/dist/visio.js +31 -4
- package/dist/xlsx/dialogs/help-dialogs.d.ts +1 -1
- package/dist/xlsx/dialogs/pivot-field-settings.d.ts +3 -3
- package/dist/xlsx/dialogs/pivot-page-filter.d.ts +1 -1
- package/dist/xlsx.js +68 -37
- package/package.json +2 -2
- package/dist/chunk-VRVFLYGI.js +0 -236
- /package/dist/pptx/{chunk-47FYJVMH.cjs → chunk-BDXQX6RA.cjs} +0 -0
- /package/dist/pptx/{chunk-XRWEURSV.mjs → chunk-ZAOD6O2D.mjs} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { TeamsLitElement, LOCALE_HOST, teamsI18n, inheritLocale, pushLocale } from './chunk-GSWCAZQ3.js';
|
|
1
2
|
import { THEME_CSS, installOfficeUiTheme } from './chunk-7E3HU7RL.js';
|
|
2
|
-
import { defineMenuButton, defineMenuItem, registerControls, defineSwitch } from './chunk-
|
|
3
|
+
import { defineMenuButton, defineMenuItem, registerControls, defineSwitch } from './chunk-CHFMXUPK.js';
|
|
3
4
|
import { registerIcon, getIcon } from './chunk-M6GF5ED2.js';
|
|
4
5
|
import { initialsOf, definePresence } from './chunk-KNC2UEUR.js';
|
|
5
6
|
import { definer, OfficeElement, controlStyles } from './chunk-CWBSXK7P.js';
|
|
6
|
-
import { nothing, html,
|
|
7
|
-
import { filterActivity, ACTIVITY_FILTERS,
|
|
7
|
+
import { nothing, html, unsafeCSS, svg } from 'lit';
|
|
8
|
+
import { filterActivity, ACTIVITY_FILTERS, localZone, startOfDay, occurrencesBetween, DAY_MS as DAY_MS$1, dayKey, zonedToUtc, viewDays, zonedParts, shiftAnchor, layoutDay, mentionQueryAt, filterMentionTargets, insertMention, MAX_ATTACHMENTS, mentionsUser, mentionSegments, detectContentKind, contentUrl, readContent, sortFiles, filterFiles, parseServerConfig, STATUS_DURATIONS, MAX_STATUS_MESSAGE_CHARS, isPresenceStatus, PRESENCE_STATUSES, isStatusDuration, IDLE_MINUTE_CHOICES, sanitizeChannelName, MAX_CHANNEL_NAME_CHARS, MAX_CHANNEL_TOPIC_CHARS, MAX_CHAT_MEMBERS, occurrenceAt, MAX_RECURRENCE_COUNT, MINUTE_MS, MAX_MEETING_TITLE, MAX_MEETING_DESCRIPTION, markdownBlocks, repeatChoices, serverOrigin, probeTeamsAccounts, requestTeamsSession, signOutTeamsSession, checkTeamsSession, createTeamsClient, sanitizeAttachment, markdownInline, TeamsSignInError } from 'ooxml-core/teams';
|
|
8
9
|
import { repeat } from 'lit/directives/repeat.js';
|
|
9
10
|
import { live } from 'lit/directives/live.js';
|
|
10
11
|
import { keyed } from 'lit/directives/keyed.js';
|
|
@@ -19,6 +20,37 @@ var withStyles = (css) => {
|
|
|
19
20
|
};
|
|
20
21
|
var TeamsElement = class extends OfficeElement {
|
|
21
22
|
static syncUpdates = false;
|
|
23
|
+
static properties = { locale: { type: String } };
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
this.locale = "";
|
|
27
|
+
}
|
|
28
|
+
get [LOCALE_HOST]() {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
get i18n() {
|
|
32
|
+
return teamsI18n(this.locale);
|
|
33
|
+
}
|
|
34
|
+
t(key, params) {
|
|
35
|
+
return this.i18n.t(key, params);
|
|
36
|
+
}
|
|
37
|
+
tn(key, count, params) {
|
|
38
|
+
return this.i18n.tn(key, count, params);
|
|
39
|
+
}
|
|
40
|
+
/** The accessible name of the host element itself, rewritten with every update. */
|
|
41
|
+
hostLabel() {
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
connectedCallback() {
|
|
45
|
+
super.connectedCallback();
|
|
46
|
+
inheritLocale(this);
|
|
47
|
+
}
|
|
48
|
+
update(changed) {
|
|
49
|
+
super.update(changed);
|
|
50
|
+
const label = this.hostLabel();
|
|
51
|
+
if (label !== void 0) this.setAttribute("aria-label", label);
|
|
52
|
+
if (changed.has("locale")) pushLocale(this);
|
|
53
|
+
}
|
|
22
54
|
};
|
|
23
55
|
function colorFor(id) {
|
|
24
56
|
let hue = 0;
|
|
@@ -26,32 +58,68 @@ function colorFor(id) {
|
|
|
26
58
|
return `hsl(${hue} 45% 42%)`;
|
|
27
59
|
}
|
|
28
60
|
var DAY_MS = 864e5;
|
|
29
|
-
function formatTime(ts) {
|
|
30
|
-
return new Date(ts).toLocaleTimeString(
|
|
61
|
+
function formatTime(ts, locale) {
|
|
62
|
+
return new Date(ts).toLocaleTimeString(teamsI18n(locale).intl, {
|
|
63
|
+
hour: "2-digit",
|
|
64
|
+
minute: "2-digit"
|
|
65
|
+
});
|
|
31
66
|
}
|
|
32
|
-
function
|
|
67
|
+
function dayKind(ts, now = Date.now()) {
|
|
33
68
|
const start = (t) => new Date(t).setHours(0, 0, 0, 0);
|
|
34
69
|
const diff = Math.round((start(now) - start(ts)) / DAY_MS);
|
|
35
|
-
|
|
36
|
-
if (diff === 1) return "Yesterday";
|
|
37
|
-
return new Date(ts).toLocaleDateString([], { weekday: "long", month: "long", day: "numeric" });
|
|
70
|
+
return diff === 0 ? "today" : diff === 1 ? "yesterday" : "other";
|
|
38
71
|
}
|
|
39
|
-
function
|
|
72
|
+
function dayLabel(ts, now = Date.now(), locale) {
|
|
73
|
+
const i18n = teamsI18n(locale);
|
|
74
|
+
const kind = dayKind(ts, now);
|
|
75
|
+
if (kind === "today") return i18n.t("time.today");
|
|
76
|
+
if (kind === "yesterday") return i18n.t("time.yesterday");
|
|
77
|
+
return new Date(ts).toLocaleDateString(i18n.intl, {
|
|
78
|
+
weekday: "long",
|
|
79
|
+
month: "long",
|
|
80
|
+
day: "numeric"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function formatSize(bytes, locale) {
|
|
40
84
|
if (bytes === void 0) return "";
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
85
|
+
const i18n = teamsI18n(locale);
|
|
86
|
+
const number = (n, digits = 0) => new Intl.NumberFormat(i18n.intl, {
|
|
87
|
+
maximumFractionDigits: digits,
|
|
88
|
+
minimumFractionDigits: digits
|
|
89
|
+
}).format(n);
|
|
90
|
+
if (bytes < 1024) return i18n.t("size.bytes", { size: number(bytes) });
|
|
91
|
+
if (bytes < 1048576) return i18n.t("size.kb", { size: number(Math.round(bytes / 1024)) });
|
|
92
|
+
return i18n.t("size.mb", { size: number(bytes / 1048576, 1) });
|
|
44
93
|
}
|
|
45
|
-
var timeOnly = (ts) => new Date(ts).toLocaleTimeString(
|
|
46
|
-
function formatWhen(start, end) {
|
|
47
|
-
const
|
|
94
|
+
var timeOnly = (ts, intl) => new Date(ts).toLocaleTimeString(intl, { hour: "numeric", minute: "2-digit" });
|
|
95
|
+
function formatWhen(start, end, locale) {
|
|
96
|
+
const intl = teamsI18n(locale).intl;
|
|
97
|
+
const day = new Date(start).toLocaleDateString(intl, {
|
|
48
98
|
weekday: "short",
|
|
49
99
|
month: "short",
|
|
50
100
|
day: "numeric"
|
|
51
101
|
});
|
|
52
102
|
const sameDay = new Date(start).toDateString() === new Date(end).toDateString();
|
|
53
|
-
const tail = sameDay ? timeOnly(end) : `${new Date(end).toLocaleDateString(
|
|
54
|
-
return `${day}, ${timeOnly(start)} - ${tail}`;
|
|
103
|
+
const tail = sameDay ? timeOnly(end, intl) : `${new Date(end).toLocaleDateString(intl, { month: "short", day: "numeric" })}, ${timeOnly(end, intl)}`;
|
|
104
|
+
return `${day}, ${timeOnly(start, intl)} - ${tail}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/teams/i18n/describe.ts
|
|
108
|
+
function describeActivityIn(item, i18n) {
|
|
109
|
+
const where = item.chat ? item.channelName : `# ${item.channelName}`;
|
|
110
|
+
const actor = item.actorName;
|
|
111
|
+
switch (item.kind) {
|
|
112
|
+
case "mention":
|
|
113
|
+
return i18n.t("activity.mention", { actor, where });
|
|
114
|
+
case "reply":
|
|
115
|
+
return i18n.t("activity.reply", { actor, where });
|
|
116
|
+
case "reaction":
|
|
117
|
+
return item.emoji ? i18n.t("activity.reactionEmoji", { actor, emoji: item.emoji }) : i18n.t("activity.reaction", { actor });
|
|
118
|
+
case "pin":
|
|
119
|
+
return i18n.t("activity.pin", { actor, where });
|
|
120
|
+
case "meeting":
|
|
121
|
+
return i18n.t("activity.meeting", { title: item.channelName });
|
|
122
|
+
}
|
|
55
123
|
}
|
|
56
124
|
var GLYPHS = {
|
|
57
125
|
back: "M12.5 4 6.5 10l6 6",
|
|
@@ -90,12 +158,12 @@ function icon(name) {
|
|
|
90
158
|
var activity_feed_default = ":host {\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\nheader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--office-space-2);\n padding: var(--office-space-3) var(--office-space-3) var(--office-space-1);\n}\nh2 {\n margin: 0;\n font-size: var(--office-font-size-lg);\n font-weight: var(--office-font-weight-bold);\n}\n.read-all {\n padding: var(--office-space-1) var(--office-space-2);\n border: 0;\n border-radius: var(--office-radius);\n background: transparent;\n color: var(--office-teams-brand);\n font-size: var(--office-font-size-sm);\n}\n.read-all:hover:not(:disabled) {\n background: var(--office-selected);\n}\n.read-all:disabled {\n color: var(--office-teams-text-subtle);\n cursor: default;\n}\n.filters {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-1);\n padding: var(--office-space-1) var(--office-space-3) var(--office-space-2);\n}\n.filters button {\n display: inline-flex;\n align-items: center;\n gap: var(--office-space-1);\n padding: var(--office-space-1) var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-full);\n background: transparent;\n font-size: var(--office-font-size-sm);\n}\n.filters button:hover {\n background: var(--office-selected);\n}\n.filters button[aria-pressed='true'] {\n border-color: var(--office-teams-brand);\n background: var(--office-teams-brand-subtle);\n color: var(--office-teams-brand);\n font-weight: var(--office-font-weight-bold);\n}\n.count {\n min-width: 1.4em;\n padding: 0 var(--office-space-1);\n border-radius: var(--office-radius-full);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font-size: var(--office-font-size-3xs);\n line-height: 1.6;\n text-align: center;\n}\nul {\n flex: 1;\n min-height: 0;\n margin: 0;\n padding: 0 var(--office-space-2) var(--office-space-2);\n overflow-y: auto;\n list-style: none;\n}\nli {\n position: relative;\n}\n.item {\n display: flex;\n align-items: flex-start;\n gap: var(--office-space-3);\n width: 100%;\n padding: var(--office-space-2) var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius-md);\n background: transparent;\n color: inherit;\n text-align: start;\n}\n.item:hover {\n background: var(--office-selected);\n}\n.item[aria-current='true'] {\n background: var(--office-teams-brand-subtle);\n}\n.face {\n position: relative;\n flex: none;\n}\n.kind {\n position: absolute;\n inset-block-end: calc(-1 * var(--office-space-1));\n inset-inline-end: calc(-1 * var(--office-space-1));\n display: grid;\n place-items: center;\n width: 1.5em;\n height: 1.5em;\n border-radius: var(--office-radius-full);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n}\n.kind svg {\n width: 0.9em;\n height: 0.9em;\n}\n.text {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-width: 0;\n}\n.line {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\nli[data-unread='true'] .line {\n font-weight: var(--office-font-weight-bold);\n}\n.preview {\n overflow: hidden;\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-sm);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.when {\n display: flex;\n flex: none;\n flex-direction: column;\n align-items: flex-end;\n gap: var(--office-space-1);\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-xs);\n}\n.dot {\n width: 0.7em;\n height: 0.7em;\n border-radius: var(--office-radius-full);\n background: var(--office-teams-brand);\n}\n.toggle {\n position: absolute;\n inset-block-end: var(--office-space-1);\n inset-inline-end: var(--office-space-2);\n display: none;\n place-items: center;\n width: 2em;\n height: 2em;\n border: 0;\n border-radius: var(--office-radius);\n background: var(--office-popover);\n color: var(--office-teams-text-subtle);\n box-shadow: var(--office-shadow-teams);\n}\nli:hover .toggle,\nli:focus-within .toggle {\n display: grid;\n}\n.empty {\n margin: 0;\n padding: var(--office-space-4);\n color: var(--office-teams-text-subtle);\n text-align: center;\n}\n@media (pointer: coarse) {\n .filters button,\n .read-all {\n min-height: var(--office-touch-target, 44px);\n }\n .toggle {\n display: grid;\n width: var(--office-touch-target, 44px);\n height: var(--office-touch-target, 44px);\n }\n}\n";
|
|
91
159
|
|
|
92
160
|
// src/teams/activity-feed.ts
|
|
93
|
-
var
|
|
94
|
-
all: "
|
|
95
|
-
unread: "
|
|
96
|
-
mentions: "
|
|
97
|
-
replies: "
|
|
98
|
-
reactions: "
|
|
161
|
+
var FILTER_KEY = {
|
|
162
|
+
all: "activity.filter.all",
|
|
163
|
+
unread: "activity.filter.unread",
|
|
164
|
+
mentions: "activity.filter.mentions",
|
|
165
|
+
replies: "activity.filter.replies",
|
|
166
|
+
reactions: "activity.filter.reactions"
|
|
99
167
|
};
|
|
100
168
|
var KIND_ICON = {
|
|
101
169
|
mention: "at",
|
|
@@ -104,18 +172,19 @@ var KIND_ICON = {
|
|
|
104
172
|
pin: "pin",
|
|
105
173
|
meeting: "calendar"
|
|
106
174
|
};
|
|
107
|
-
var
|
|
108
|
-
all: "
|
|
109
|
-
unread: "
|
|
110
|
-
mentions: "
|
|
111
|
-
replies: "
|
|
112
|
-
reactions: "
|
|
175
|
+
var EMPTY_KEY = {
|
|
176
|
+
all: "activity.empty.all",
|
|
177
|
+
unread: "activity.empty.unread",
|
|
178
|
+
mentions: "activity.empty.mentions",
|
|
179
|
+
replies: "activity.empty.replies",
|
|
180
|
+
reactions: "activity.empty.reactions"
|
|
113
181
|
};
|
|
114
|
-
function activityTime(ts, now = Date.now()) {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
182
|
+
function activityTime(ts, now = Date.now(), locale) {
|
|
183
|
+
const kind = dayKind(ts, now);
|
|
184
|
+
if (kind === "today") return formatTime(ts, locale);
|
|
185
|
+
const i18n = teamsI18n(locale);
|
|
186
|
+
if (kind === "yesterday") return i18n.t("time.yesterday");
|
|
187
|
+
return new Date(ts).toLocaleDateString(i18n.intl, { month: "short", day: "numeric" });
|
|
119
188
|
}
|
|
120
189
|
var OfficeUiActivityFeed = class extends TeamsElement {
|
|
121
190
|
static styles = withStyles(activity_feed_default);
|
|
@@ -138,17 +207,17 @@ var OfficeUiActivityFeed = class extends TeamsElement {
|
|
|
138
207
|
const unread = this.unread;
|
|
139
208
|
return html`
|
|
140
209
|
<header>
|
|
141
|
-
<h2
|
|
210
|
+
<h2>${this.t("activity.title")}</h2>
|
|
142
211
|
<button
|
|
143
212
|
type="button"
|
|
144
213
|
class="read-all"
|
|
145
214
|
?disabled=${unread === 0}
|
|
146
215
|
@click=${() => this.fire("office-activity-read-all", {})}
|
|
147
216
|
>
|
|
148
|
-
|
|
217
|
+
${this.t("activity.markAllRead")}
|
|
149
218
|
</button>
|
|
150
219
|
</header>
|
|
151
|
-
<div class="filters" role="group" aria-label
|
|
220
|
+
<div class="filters" role="group" aria-label=${this.t("activity.filterLabel")}>
|
|
152
221
|
${ACTIVITY_FILTERS.map(
|
|
153
222
|
(value) => html`<button
|
|
154
223
|
type="button"
|
|
@@ -158,23 +227,24 @@ var OfficeUiActivityFeed = class extends TeamsElement {
|
|
|
158
227
|
this.fire("office-activity-filter", { filter: value });
|
|
159
228
|
}}
|
|
160
229
|
>
|
|
161
|
-
${
|
|
230
|
+
${this.t(FILTER_KEY[value])}${value === "unread" && unread ? html` <span class="count">${unread}</span>` : nothing}
|
|
162
231
|
</button>`
|
|
163
232
|
)}
|
|
164
233
|
</div>
|
|
165
|
-
${shown.length ? html`<ul aria-label
|
|
234
|
+
${shown.length ? html`<ul aria-label=${this.t("activity.feedLabel")}>
|
|
166
235
|
${shown.map((item) => this.row(item))}
|
|
167
|
-
</ul>` : html`<p class="empty" role="status">${
|
|
236
|
+
</ul>` : html`<p class="empty" role="status">${this.t(EMPTY_KEY[this.filter])}</p>`}
|
|
168
237
|
`;
|
|
169
238
|
}
|
|
170
239
|
row(item) {
|
|
171
|
-
const line =
|
|
240
|
+
const line = describeActivityIn(item, this.i18n);
|
|
241
|
+
const toggle = this.t(item.read ? "activity.markUnread" : "activity.markRead");
|
|
172
242
|
return html`<li data-unread=${String(!item.read)} data-kind=${item.kind}>
|
|
173
243
|
<button
|
|
174
244
|
type="button"
|
|
175
245
|
class="item"
|
|
176
246
|
aria-current=${this.selectedId === item.id ? "true" : "false"}
|
|
177
|
-
aria-label=${`${item.read ? "" : "
|
|
247
|
+
aria-label=${`${item.read ? "" : `${this.t("activity.unreadPrefix")} `}${line}. ${item.preview}`}
|
|
178
248
|
@click=${() => this.fire("office-activity-open", { id: item.id })}
|
|
179
249
|
>
|
|
180
250
|
<span class="face">
|
|
@@ -190,15 +260,17 @@ var OfficeUiActivityFeed = class extends TeamsElement {
|
|
|
190
260
|
<span class="preview">${item.preview}</span>
|
|
191
261
|
</span>
|
|
192
262
|
<span class="when">
|
|
193
|
-
<time datetime=${new Date(item.ts).toISOString()}
|
|
263
|
+
<time datetime=${new Date(item.ts).toISOString()}
|
|
264
|
+
>${activityTime(item.ts, Date.now(), this.locale)}</time
|
|
265
|
+
>
|
|
194
266
|
${item.read ? nothing : html`<span class="dot" aria-hidden="true"></span>`}
|
|
195
267
|
</span>
|
|
196
268
|
</button>
|
|
197
269
|
<button
|
|
198
270
|
type="button"
|
|
199
271
|
class="toggle"
|
|
200
|
-
title=${
|
|
201
|
-
aria-label=${
|
|
272
|
+
title=${toggle}
|
|
273
|
+
aria-label=${toggle}
|
|
202
274
|
@click=${() => this.fire("office-activity-read", { id: item.id, read: !item.read })}
|
|
203
275
|
>
|
|
204
276
|
${icon(item.read ? "bell" : "check")}
|
|
@@ -231,7 +303,9 @@ var OfficeUiAppRail = class extends TeamsElement {
|
|
|
231
303
|
connectedCallback() {
|
|
232
304
|
super.connectedCallback();
|
|
233
305
|
this.setAttribute("role", "navigation");
|
|
234
|
-
|
|
306
|
+
}
|
|
307
|
+
hostLabel() {
|
|
308
|
+
return this.t("rail.appBar");
|
|
235
309
|
}
|
|
236
310
|
updated(changed) {
|
|
237
311
|
const dialog = this.renderRoot.querySelector("dialog");
|
|
@@ -264,7 +338,7 @@ var OfficeUiAppRail = class extends TeamsElement {
|
|
|
264
338
|
<button
|
|
265
339
|
type="button"
|
|
266
340
|
class="more"
|
|
267
|
-
aria-label=${badge ?
|
|
341
|
+
aria-label=${badge ? this.t("rail.moreUnread", { count: badge }) : this.t("rail.more")}
|
|
268
342
|
aria-haspopup="dialog"
|
|
269
343
|
aria-expanded=${String(this.moreOpen)}
|
|
270
344
|
aria-current=${inMore ? "page" : "false"}
|
|
@@ -274,13 +348,13 @@ var OfficeUiAppRail = class extends TeamsElement {
|
|
|
274
348
|
${icon("more")}
|
|
275
349
|
${badge ? html`<span class="badge">${total(badge)}</span>` : nothing}
|
|
276
350
|
</span>
|
|
277
|
-
<span class="short" aria-hidden="true"
|
|
351
|
+
<span class="short" aria-hidden="true">${this.t("rail.more")}</span>
|
|
278
352
|
</button>
|
|
279
353
|
</li>` : nothing}
|
|
280
354
|
</ul>
|
|
281
355
|
${secondary.length ? html`<dialog
|
|
282
356
|
class="sheet"
|
|
283
|
-
aria-label
|
|
357
|
+
aria-label=${this.t("rail.moreApps")}
|
|
284
358
|
@cancel=${(e) => {
|
|
285
359
|
e.preventDefault();
|
|
286
360
|
this.closeMore();
|
|
@@ -292,7 +366,9 @@ var OfficeUiAppRail = class extends TeamsElement {
|
|
|
292
366
|
<ul>
|
|
293
367
|
${secondary.map((item) => html`<li>${this.button(item, true)}</li>`)}
|
|
294
368
|
</ul>
|
|
295
|
-
<button type="button" class="close" @click=${() => this.closeMore()}>
|
|
369
|
+
<button type="button" class="close" @click=${() => this.closeMore()}>
|
|
370
|
+
${this.t("common.close")}
|
|
371
|
+
</button>
|
|
296
372
|
</dialog>` : nothing}
|
|
297
373
|
`;
|
|
298
374
|
}
|
|
@@ -319,13 +395,13 @@ var defineAppRail = definer("office-ui-app-rail", () => OfficeUiAppRail);
|
|
|
319
395
|
var avatar_default = ":host {\n --_size: 2.3em;\n position: relative;\n display: inline-block;\n width: var(--_size);\n height: var(--_size);\n flex: none;\n}\n:host([size='sm']) {\n --_size: 1.7em;\n}\n:host([size='lg']) {\n --_size: 3em;\n}\n:host([size='xl']) {\n --_size: 6em;\n}\n\n.face {\n display: grid;\n place-items: center;\n width: 100%;\n height: 100%;\n border-radius: var(--office-radius-full);\n color: var(--office-call-foreground);\n font-size: calc(var(--_size) * 0.38);\n font-weight: var(--office-font-weight-bold);\n user-select: none;\n}\n\n.presence {\n position: absolute;\n inset-inline-end: 0;\n inset-block-end: 0;\n width: 32%;\n height: 32%;\n min-width: 0.5em;\n min-height: 0.5em;\n border-radius: var(--office-radius-full);\n border: var(--office-border-width-thick) solid var(--office-background);\n background: var(--office-presence-offline);\n}\n.presence[data-presence='available'] {\n background: var(--office-presence-available);\n}\n.presence[data-presence='busy'] {\n background: var(--office-presence-busy);\n}\n.presence[data-presence='away'] {\n background: var(--office-presence-away);\n}\n.presence[data-presence='dnd'] {\n background: var(--office-presence-busy);\n}\n.presence[data-presence='brb'] {\n background: var(--office-presence-away);\n}\n/* Do not disturb carries a white bar; Away and Be right back share the clock hands. */\n.presence[data-presence='dnd']::after,\n.presence[data-presence='away']::after,\n.presence[data-presence='brb']::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n background: var(--office-background);\n}\n.presence[data-presence='dnd']::after {\n width: 60%;\n height: 16%;\n border-radius: var(--office-radius-full);\n}\n.presence[data-presence='away']::after,\n.presence[data-presence='brb']::after {\n width: 14%;\n height: 50%;\n inset-block: 10% auto;\n border-radius: var(--office-radius-full);\n}\n/* Appear offline is a hollow grey ring. */\n.presence[data-presence='offline'] {\n background: var(--office-background);\n border-color: var(--office-presence-offline);\n box-shadow: inset 0 0 0 var(--office-border-width-thick) var(--office-presence-offline);\n}\n";
|
|
320
396
|
|
|
321
397
|
// src/teams/avatar.ts
|
|
322
|
-
var
|
|
323
|
-
available: "
|
|
324
|
-
busy: "
|
|
325
|
-
dnd: "
|
|
326
|
-
brb: "
|
|
327
|
-
away: "
|
|
328
|
-
offline: "
|
|
398
|
+
var PRESENCE_KEY = {
|
|
399
|
+
available: "presence.available",
|
|
400
|
+
busy: "presence.busy",
|
|
401
|
+
dnd: "presence.dnd",
|
|
402
|
+
brb: "presence.brb",
|
|
403
|
+
away: "presence.away",
|
|
404
|
+
offline: "presence.offline"
|
|
329
405
|
};
|
|
330
406
|
var OfficeUiAvatar = class extends TeamsElement {
|
|
331
407
|
static styles = withStyles(avatar_default);
|
|
@@ -345,9 +421,9 @@ var OfficeUiAvatar = class extends TeamsElement {
|
|
|
345
421
|
this.presence = "";
|
|
346
422
|
}
|
|
347
423
|
willUpdate(changed) {
|
|
348
|
-
if (changed.has("name") || changed.has("presence")) {
|
|
424
|
+
if (changed.has("name") || changed.has("presence") || changed.has("locale")) {
|
|
349
425
|
this.setAttribute("role", "img");
|
|
350
|
-
const status = this.presence ? `, ${
|
|
426
|
+
const status = this.presence ? `, ${this.t(PRESENCE_KEY[this.presence])}` : "";
|
|
351
427
|
this.setAttribute("aria-label", `${this.name}${status}`);
|
|
352
428
|
}
|
|
353
429
|
}
|
|
@@ -358,7 +434,7 @@ var OfficeUiAvatar = class extends TeamsElement {
|
|
|
358
434
|
${this.presence ? html`<span
|
|
359
435
|
class="presence"
|
|
360
436
|
data-presence=${this.presence}
|
|
361
|
-
title=${
|
|
437
|
+
title=${this.t(PRESENCE_KEY[this.presence])}
|
|
362
438
|
></span>` : ""}
|
|
363
439
|
`;
|
|
364
440
|
}
|
|
@@ -404,9 +480,11 @@ var OfficeUiCallControls = class extends TeamsElement {
|
|
|
404
480
|
connectedCallback() {
|
|
405
481
|
super.connectedCallback();
|
|
406
482
|
this.setAttribute("role", "toolbar");
|
|
407
|
-
this.setAttribute("aria-label", "Meeting controls");
|
|
408
483
|
this.timer = setInterval(() => this.now = Date.now(), 1e3);
|
|
409
484
|
}
|
|
485
|
+
hostLabel() {
|
|
486
|
+
return this.t("call.controls");
|
|
487
|
+
}
|
|
410
488
|
disconnectedCallback() {
|
|
411
489
|
clearInterval(this.timer);
|
|
412
490
|
super.disconnectedCallback();
|
|
@@ -437,19 +515,19 @@ var OfficeUiCallControls = class extends TeamsElement {
|
|
|
437
515
|
>${this.startedAt ? html`<time>${formatElapsed(this.now - this.startedAt)}</time>` : nothing}
|
|
438
516
|
</div>
|
|
439
517
|
<div class="actions">
|
|
440
|
-
${this.button("chat", "
|
|
441
|
-
${this.button("people", "
|
|
442
|
-
${this.button("hand", this.hand ? "
|
|
443
|
-
${this.button("camera", this.camera ? "
|
|
444
|
-
${this.button("mic", this.mic ? "
|
|
445
|
-
${this.button("screen", this.screen ? "
|
|
518
|
+
${this.button("chat", this.t("call.chat"), "chat", { on: this.panel === "chat" })}
|
|
519
|
+
${this.button("people", this.t("call.people"), "users", { on: this.panel === "people" })}
|
|
520
|
+
${this.button("hand", this.t(this.hand ? "call.lower" : "call.raise"), "hand", { on: this.hand })}
|
|
521
|
+
${this.button("camera", this.t(this.camera ? "call.cameraOff" : "call.cameraOn"), this.camera ? "video" : "videoOff", { off: !this.camera })}
|
|
522
|
+
${this.button("mic", this.t(this.mic ? "call.mute" : "call.unmute"), this.mic ? "mic" : "micOff", { off: !this.mic })}
|
|
523
|
+
${this.button("screen", this.t(this.screen ? "call.stopSharing" : "call.share"), "screenShare", { on: this.screen, disabled: this.shareUnavailable })}
|
|
446
524
|
<button
|
|
447
525
|
type="button"
|
|
448
526
|
class="leave"
|
|
449
|
-
aria-label
|
|
527
|
+
aria-label=${this.t("call.leaveCall")}
|
|
450
528
|
@click=${() => this.fire("office-call-action", { action: "leave" })}
|
|
451
529
|
>
|
|
452
|
-
${icon("phoneOff")}<span class="text"
|
|
530
|
+
${icon("phoneOff")}<span class="text">${this.t("call.leave")}</span>
|
|
453
531
|
</button>
|
|
454
532
|
</div>
|
|
455
533
|
`;
|
|
@@ -487,7 +565,7 @@ var OfficeUiCalendarAgenda = class extends TeamsElement {
|
|
|
487
565
|
const key = dayKey(row.o.start, this.zone);
|
|
488
566
|
let group = groups.get(key);
|
|
489
567
|
if (!group) {
|
|
490
|
-
const label = new Intl.DateTimeFormat(
|
|
568
|
+
const label = new Intl.DateTimeFormat(this.i18n.intl, {
|
|
491
569
|
weekday: "long",
|
|
492
570
|
month: "short",
|
|
493
571
|
day: "numeric",
|
|
@@ -495,25 +573,28 @@ var OfficeUiCalendarAgenda = class extends TeamsElement {
|
|
|
495
573
|
}).format(row.o.start);
|
|
496
574
|
groups.set(
|
|
497
575
|
key,
|
|
498
|
-
group = {
|
|
576
|
+
group = {
|
|
577
|
+
label: key === dayKey(now, this.zone) ? this.t("agenda.todayDate", { date: label }) : label,
|
|
578
|
+
rows: []
|
|
579
|
+
}
|
|
499
580
|
);
|
|
500
581
|
}
|
|
501
582
|
group.rows.push(row);
|
|
502
583
|
}
|
|
503
584
|
return html`
|
|
504
585
|
<header>
|
|
505
|
-
<h2
|
|
586
|
+
<h2>${this.t("calendar.title")}</h2>
|
|
506
587
|
<button
|
|
507
588
|
class="new"
|
|
508
589
|
type="button"
|
|
509
|
-
title
|
|
510
|
-
aria-label
|
|
590
|
+
title=${this.t("calendar.newMeeting")}
|
|
591
|
+
aria-label=${this.t("calendar.newMeeting")}
|
|
511
592
|
@click=${() => this.fire("office-agenda-new", {})}
|
|
512
593
|
>
|
|
513
594
|
${icon("plus")}
|
|
514
595
|
</button>
|
|
515
596
|
</header>
|
|
516
|
-
${groups.size === 0 ? html`<p class="empty"
|
|
597
|
+
${groups.size === 0 ? html`<p class="empty">${this.t("agenda.empty")}</p>` : [...groups.values()].map(
|
|
517
598
|
(g) => html`<section>
|
|
518
599
|
<h3>${g.label}</h3>
|
|
519
600
|
<ul>
|
|
@@ -537,20 +618,20 @@ var OfficeUiCalendarAgenda = class extends TeamsElement {
|
|
|
537
618
|
>
|
|
538
619
|
<span class="time">${time}</span>
|
|
539
620
|
<span class="title">${title}</span>
|
|
540
|
-
<span class="who">${m.mine ? "
|
|
621
|
+
<span class="who">${m.mine ? this.t("agenda.youOrganized") : m.organizerName}</span>
|
|
541
622
|
</button>
|
|
542
623
|
${joinable ? html`<button
|
|
543
624
|
type="button"
|
|
544
625
|
class="join"
|
|
545
|
-
aria-label=${
|
|
626
|
+
aria-label=${this.t("agenda.join", { title })}
|
|
546
627
|
@click=${() => this.fire("office-agenda-join", { meetingId: m.id })}
|
|
547
628
|
>
|
|
548
|
-
${m.live ? "
|
|
629
|
+
${this.t(m.live ? "call.joinNow" : "call.join")}
|
|
549
630
|
</button>` : ""}
|
|
550
631
|
</li>`;
|
|
551
632
|
}
|
|
552
633
|
clock(ms) {
|
|
553
|
-
return new Date(ms).toLocaleTimeString(
|
|
634
|
+
return new Date(ms).toLocaleTimeString(this.i18n.intl, {
|
|
554
635
|
hour: "numeric",
|
|
555
636
|
minute: "2-digit",
|
|
556
637
|
timeZone: this.zone
|
|
@@ -567,9 +648,9 @@ var calendar_view_default = ":host {\n --_hour: 4em;\n display: flex;\n flex-dir
|
|
|
567
648
|
|
|
568
649
|
// src/teams/calendar-view.ts
|
|
569
650
|
var MODES = [
|
|
570
|
-
{ id: "workweek", label: "
|
|
571
|
-
{ id: "week", label: "
|
|
572
|
-
{ id: "day", label: "
|
|
651
|
+
{ id: "workweek", label: "calendar.workWeek" },
|
|
652
|
+
{ id: "week", label: "calendar.week" },
|
|
653
|
+
{ id: "day", label: "calendar.day" }
|
|
573
654
|
];
|
|
574
655
|
var SLOT_MINUTES = 30;
|
|
575
656
|
var FIRST_VISIBLE_HOUR = 8;
|
|
@@ -601,7 +682,6 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
601
682
|
connectedCallback() {
|
|
602
683
|
super.connectedCallback();
|
|
603
684
|
this.setAttribute("role", "region");
|
|
604
|
-
this.setAttribute("aria-label", "Calendar");
|
|
605
685
|
if (!this.anchor) this.anchor = this.clock();
|
|
606
686
|
if (globalThis.matchMedia?.("(max-width: 40em)").matches && this.mode === "workweek")
|
|
607
687
|
this.mode = "day";
|
|
@@ -611,6 +691,9 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
611
691
|
this.resize.observe(this);
|
|
612
692
|
}
|
|
613
693
|
}
|
|
694
|
+
hostLabel() {
|
|
695
|
+
return this.t("calendar.title");
|
|
696
|
+
}
|
|
614
697
|
disconnectedCallback() {
|
|
615
698
|
clearInterval(this.timer);
|
|
616
699
|
this.resize?.disconnect();
|
|
@@ -636,10 +719,11 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
636
719
|
range(days) {
|
|
637
720
|
const first = days[0];
|
|
638
721
|
const last = days[days.length - 1];
|
|
639
|
-
const
|
|
722
|
+
const intl = this.i18n.intl;
|
|
723
|
+
const fmt = (opts, ms) => new Intl.DateTimeFormat(intl, { ...opts, timeZone: this.zone }).format(ms);
|
|
640
724
|
if (days.length === 1)
|
|
641
725
|
return fmt({ weekday: "long", month: "long", day: "numeric", year: "numeric" }, first.start);
|
|
642
|
-
return new Intl.DateTimeFormat(
|
|
726
|
+
return new Intl.DateTimeFormat(intl, {
|
|
643
727
|
month: "long",
|
|
644
728
|
day: "numeric",
|
|
645
729
|
year: "numeric",
|
|
@@ -666,12 +750,12 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
666
750
|
<div class="bar">
|
|
667
751
|
<h2 class="range" aria-live="polite">${this.range(days)}</h2>
|
|
668
752
|
<button type="button" class="today" @click=${() => this.anchor = this.clock()}>
|
|
669
|
-
|
|
753
|
+
${this.t("time.today")}
|
|
670
754
|
</button>
|
|
671
755
|
<button
|
|
672
756
|
type="button"
|
|
673
757
|
class="step"
|
|
674
|
-
aria-label=${this.mode === "day" ? "
|
|
758
|
+
aria-label=${this.t(this.mode === "day" ? "calendar.previousDay" : "calendar.previousWeek")}
|
|
675
759
|
@click=${() => this.anchor = shiftAnchor(this.anchor || now, this.mode, -1, this.zone)}
|
|
676
760
|
>
|
|
677
761
|
${icon("back")}
|
|
@@ -679,19 +763,19 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
679
763
|
<button
|
|
680
764
|
type="button"
|
|
681
765
|
class="step next"
|
|
682
|
-
aria-label=${this.mode === "day" ? "
|
|
766
|
+
aria-label=${this.t(this.mode === "day" ? "calendar.nextDay" : "calendar.nextWeek")}
|
|
683
767
|
@click=${() => this.anchor = shiftAnchor(this.anchor || now, this.mode, 1, this.zone)}
|
|
684
768
|
>
|
|
685
769
|
${icon("back")}
|
|
686
770
|
</button>
|
|
687
|
-
<div class="modes" role="group" aria-label
|
|
771
|
+
<div class="modes" role="group" aria-label=${this.t("calendar.viewLabel")}>
|
|
688
772
|
${MODES.map(
|
|
689
773
|
(m) => html`<button
|
|
690
774
|
type="button"
|
|
691
775
|
aria-pressed=${String(this.mode === m.id)}
|
|
692
776
|
@click=${() => this.setMode(m.id)}
|
|
693
777
|
>
|
|
694
|
-
${m.label}
|
|
778
|
+
${this.t(m.label)}
|
|
695
779
|
</button>`
|
|
696
780
|
)}
|
|
697
781
|
</div>
|
|
@@ -700,7 +784,7 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
700
784
|
class="new"
|
|
701
785
|
@click=${() => this.fire("office-calendar-new", { start: 0 })}
|
|
702
786
|
>
|
|
703
|
-
${icon("plus")}
|
|
787
|
+
${icon("plus")} ${this.t("calendar.newMeeting")}
|
|
704
788
|
</button>
|
|
705
789
|
</div>
|
|
706
790
|
<div class="scroller">
|
|
@@ -717,15 +801,16 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
717
801
|
}
|
|
718
802
|
hourLabel(hour) {
|
|
719
803
|
if (hour === 0) return "";
|
|
720
|
-
return new Date(Date.UTC(2e3, 0, 1, hour)).toLocaleTimeString(
|
|
804
|
+
return new Date(Date.UTC(2e3, 0, 1, hour)).toLocaleTimeString(this.i18n.intl, {
|
|
721
805
|
hour: "numeric",
|
|
722
806
|
timeZone: "UTC"
|
|
723
807
|
});
|
|
724
808
|
}
|
|
725
809
|
dayHead(day, today) {
|
|
726
|
-
const name = new Intl.DateTimeFormat(
|
|
727
|
-
|
|
728
|
-
|
|
810
|
+
const name = new Intl.DateTimeFormat(this.i18n.intl, {
|
|
811
|
+
weekday: "short",
|
|
812
|
+
timeZone: this.zone
|
|
813
|
+
}).format(day.start);
|
|
729
814
|
return html`<div class="head" data-today=${String(today)}>
|
|
730
815
|
<span class="dow">${name}</span>
|
|
731
816
|
<span class="dom">${day.day}</span>
|
|
@@ -741,7 +826,7 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
741
826
|
this.zone
|
|
742
827
|
);
|
|
743
828
|
const byKey = new Map(occurrences.map((x) => [x.o.key, x.m]));
|
|
744
|
-
const label = new Intl.DateTimeFormat(
|
|
829
|
+
const label = new Intl.DateTimeFormat(this.i18n.intl, {
|
|
745
830
|
weekday: "long",
|
|
746
831
|
month: "long",
|
|
747
832
|
day: "numeric",
|
|
@@ -788,7 +873,7 @@ var OfficeUiCalendarView = class extends TeamsElement {
|
|
|
788
873
|
</div>`;
|
|
789
874
|
}
|
|
790
875
|
clockText(ms) {
|
|
791
|
-
return new Date(ms).toLocaleTimeString(
|
|
876
|
+
return new Date(ms).toLocaleTimeString(this.i18n.intl, {
|
|
792
877
|
hour: "numeric",
|
|
793
878
|
minute: "2-digit",
|
|
794
879
|
timeZone: this.zone
|
|
@@ -812,11 +897,13 @@ var OfficeUiCallGrid = class extends TeamsElement {
|
|
|
812
897
|
connectedCallback() {
|
|
813
898
|
super.connectedCallback();
|
|
814
899
|
this.setAttribute("role", "list");
|
|
815
|
-
|
|
900
|
+
}
|
|
901
|
+
hostLabel() {
|
|
902
|
+
return this.t("call.participants");
|
|
816
903
|
}
|
|
817
904
|
render() {
|
|
818
905
|
const people = this.participants;
|
|
819
|
-
if (people.length === 0) return html`<p class="empty"
|
|
906
|
+
if (people.length === 0) return html`<p class="empty">${this.t("call.nobody")}</p>`;
|
|
820
907
|
const sharer = people.find((p) => p.screen);
|
|
821
908
|
const spotlight = sharer !== void 0 && people.length > 1;
|
|
822
909
|
const ordered = sharer ? [sharer, ...people.filter((p) => p !== sharer)] : people;
|
|
@@ -851,11 +938,11 @@ var OfficeUiCallGrid = class extends TeamsElement {
|
|
|
851
938
|
${showAvatar ? html`<office-ui-avatar size="xl" name=${p.name} seed=${p.id}></office-ui-avatar>` : nothing}
|
|
852
939
|
<div class="name">
|
|
853
940
|
${p.audio === false ? html`<span class="muted">${icon("micOff")}</span>` : nothing}
|
|
854
|
-
<span>${p.self ?
|
|
941
|
+
<span>${p.self ? this.t("common.nameYou", { name: p.name }) : p.name}</span>
|
|
855
942
|
</div>
|
|
856
|
-
${p.hand ? html`<span class="hand" role="img" aria-label
|
|
943
|
+
${p.hand ? html`<span class="hand" role="img" aria-label=${this.t("call.handRaised")}>✋</span>` : nothing}
|
|
857
944
|
${!p.self && p.connection && p.connection !== "connected" ? html`<span class="status"
|
|
858
|
-
>${p.connection === "failed" ? "
|
|
945
|
+
>${this.t(p.connection === "failed" ? "call.connectionFailed" : "call.connecting")}</span
|
|
859
946
|
>` : nothing}
|
|
860
947
|
</div>
|
|
861
948
|
`;
|
|
@@ -877,7 +964,7 @@ var OfficeUiChannelList = class extends TeamsElement {
|
|
|
877
964
|
};
|
|
878
965
|
constructor() {
|
|
879
966
|
super();
|
|
880
|
-
this.heading = "
|
|
967
|
+
this.heading = "";
|
|
881
968
|
this.channels = [];
|
|
882
969
|
this.selectedId = "";
|
|
883
970
|
this.collapsed = false;
|
|
@@ -892,13 +979,13 @@ var OfficeUiChannelList = class extends TeamsElement {
|
|
|
892
979
|
@click=${() => this.collapsed = !this.collapsed}
|
|
893
980
|
>
|
|
894
981
|
<span class="chevron" data-open=${String(!this.collapsed)}>${icon("chevronRight")}</span>
|
|
895
|
-
<span class="name">${this.heading}</span>
|
|
982
|
+
<span class="name">${this.heading || this.t("channels.heading")}</span>
|
|
896
983
|
</button>
|
|
897
984
|
<button
|
|
898
985
|
class="add"
|
|
899
986
|
type="button"
|
|
900
|
-
title
|
|
901
|
-
aria-label
|
|
987
|
+
title=${this.t("channels.add")}
|
|
988
|
+
aria-label=${this.t("channels.add")}
|
|
902
989
|
@click=${() => this.fire("office-channel-create", {})}
|
|
903
990
|
>
|
|
904
991
|
${icon("plus")}
|
|
@@ -917,7 +1004,9 @@ var OfficeUiChannelList = class extends TeamsElement {
|
|
|
917
1004
|
>
|
|
918
1005
|
${icon(c.kind === "direct" ? "message" : "hash")}
|
|
919
1006
|
<span class="title">${c.name}</span>
|
|
920
|
-
${c.live ? html`<span class="live" title
|
|
1007
|
+
${c.live ? html`<span class="live" title=${this.t("call.inProgress")}
|
|
1008
|
+
>${icon("video")}</span
|
|
1009
|
+
>` : ""}
|
|
921
1010
|
${c.unread ? html`<span class="count">${c.unread > 99 ? "99+" : c.unread}</span>` : ""}
|
|
922
1011
|
</button>
|
|
923
1012
|
</li>
|
|
@@ -978,7 +1067,7 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
978
1067
|
this.replyingTo = null;
|
|
979
1068
|
this.editing = false;
|
|
980
1069
|
this.disabled = false;
|
|
981
|
-
this.placeholder = "
|
|
1070
|
+
this.placeholder = "";
|
|
982
1071
|
this.value = "";
|
|
983
1072
|
this.files = [];
|
|
984
1073
|
this.missingFiles = [];
|
|
@@ -1111,7 +1200,7 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1111
1200
|
typingLine() {
|
|
1112
1201
|
const n = this.typing.slice(0, 3);
|
|
1113
1202
|
if (n.length === 0) return "";
|
|
1114
|
-
return n.length === 1 ?
|
|
1203
|
+
return n.length === 1 ? this.t("composer.typingOne", { name: n[0] }) : this.t("composer.typingMany", { names: n.join(", ") });
|
|
1115
1204
|
}
|
|
1116
1205
|
mentionList() {
|
|
1117
1206
|
const options = this.pickerOptions();
|
|
@@ -1120,7 +1209,7 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1120
1209
|
id="mention-list"
|
|
1121
1210
|
class="mentions"
|
|
1122
1211
|
role="listbox"
|
|
1123
|
-
aria-label
|
|
1212
|
+
aria-label=${this.t("composer.mentionPeople")}
|
|
1124
1213
|
@mousedown=${(event) => event.preventDefault()}
|
|
1125
1214
|
>
|
|
1126
1215
|
${options.map(
|
|
@@ -1136,13 +1225,13 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1136
1225
|
seed=${target.id}
|
|
1137
1226
|
></office-ui-avatar>` : html`<span class="everyone" aria-hidden="true">@</span>`}
|
|
1138
1227
|
<span class="name">${target.name}</span>
|
|
1139
|
-
${target.kind === "user" ? nothing : html`<span class="hint">${target.kind === "channel" ? "
|
|
1228
|
+
${target.kind === "user" ? nothing : html`<span class="hint">${this.t(target.kind === "channel" ? "composer.notifyChannel" : "composer.notifyTeam")}</span>`}
|
|
1140
1229
|
</li>`
|
|
1141
1230
|
)}
|
|
1142
1231
|
</ul>`;
|
|
1143
1232
|
}
|
|
1144
1233
|
render() {
|
|
1145
|
-
const banner = this.editing ? "
|
|
1234
|
+
const banner = this.editing ? this.t("composer.editing") : this.replyingTo !== null ? this.t("composer.replyingTo", { name: this.replyingTo }) : "";
|
|
1146
1235
|
return html`
|
|
1147
1236
|
<div class="typing" aria-live="polite">${this.typingLine()}</div>
|
|
1148
1237
|
<div
|
|
@@ -1162,19 +1251,19 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1162
1251
|
}}
|
|
1163
1252
|
>
|
|
1164
1253
|
${this.missingFiles.length ? html`<div role="status">
|
|
1165
|
-
|
|
1254
|
+
${this.t("composer.reattach")}
|
|
1166
1255
|
<ul>
|
|
1167
1256
|
${this.missingFiles.map(
|
|
1168
1257
|
(name) => html`<li>
|
|
1169
1258
|
${name}<button
|
|
1170
1259
|
type="button"
|
|
1171
|
-
aria-label=${
|
|
1260
|
+
aria-label=${this.t("composer.discardMissing", { name })}
|
|
1172
1261
|
@click=${() => {
|
|
1173
1262
|
this.missingFiles = this.missingFiles.filter((item) => item !== name);
|
|
1174
1263
|
this.saveDraft();
|
|
1175
1264
|
}}
|
|
1176
1265
|
>
|
|
1177
|
-
|
|
1266
|
+
${this.t("composer.discard")}
|
|
1178
1267
|
</button>
|
|
1179
1268
|
</li>`
|
|
1180
1269
|
)}
|
|
@@ -1184,7 +1273,7 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1184
1273
|
<span>${banner}</span>
|
|
1185
1274
|
<button
|
|
1186
1275
|
type="button"
|
|
1187
|
-
aria-label
|
|
1276
|
+
aria-label=${this.t("common.cancel")}
|
|
1188
1277
|
@click=${() => this.fire("office-chat-cancel", {})}
|
|
1189
1278
|
>
|
|
1190
1279
|
${icon("close")}
|
|
@@ -1193,12 +1282,12 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1193
1282
|
${this.mentionList()}
|
|
1194
1283
|
<textarea
|
|
1195
1284
|
rows="1"
|
|
1196
|
-
aria-label
|
|
1285
|
+
aria-label=${this.t("composer.message")}
|
|
1197
1286
|
aria-haspopup="listbox"
|
|
1198
1287
|
aria-controls=${this.pickerOptions().length ? "mention-list" : nothing}
|
|
1199
1288
|
aria-activedescendant=${this.pickerOptions().length ? `mention-option-${this.pickerIndex}` : nothing}
|
|
1200
1289
|
.value=${live(this.value)}
|
|
1201
|
-
placeholder=${this.placeholder}
|
|
1290
|
+
placeholder=${this.placeholder || this.t("composer.placeholder")}
|
|
1202
1291
|
?disabled=${this.disabled}
|
|
1203
1292
|
@input=${this.onInput}
|
|
1204
1293
|
@paste=${(event) => {
|
|
@@ -1219,7 +1308,7 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1219
1308
|
(f, i) => html`<li>
|
|
1220
1309
|
<button
|
|
1221
1310
|
type="button"
|
|
1222
|
-
aria-label=${
|
|
1311
|
+
aria-label=${this.t("people.remove", { name: f.name })}
|
|
1223
1312
|
@click=${() => {
|
|
1224
1313
|
this.files = this.files.filter((_, j) => j !== i);
|
|
1225
1314
|
this.focusMessage();
|
|
@@ -1234,8 +1323,8 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1234
1323
|
<div class="bar">
|
|
1235
1324
|
<button
|
|
1236
1325
|
type="button"
|
|
1237
|
-
title
|
|
1238
|
-
aria-label
|
|
1326
|
+
title=${this.t("composer.attach")}
|
|
1327
|
+
aria-label=${this.t("composer.attach")}
|
|
1239
1328
|
?disabled=${this.disabled}
|
|
1240
1329
|
@click=${() => this.renderRoot.querySelector("input[type=file]")?.click()}
|
|
1241
1330
|
>
|
|
@@ -1244,8 +1333,8 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1244
1333
|
<div class="emoji">
|
|
1245
1334
|
<button
|
|
1246
1335
|
type="button"
|
|
1247
|
-
title
|
|
1248
|
-
aria-label
|
|
1336
|
+
title=${this.t("composer.emoji")}
|
|
1337
|
+
aria-label=${this.t("composer.emoji")}
|
|
1249
1338
|
aria-expanded=${String(this.emojiOpen)}
|
|
1250
1339
|
?disabled=${this.disabled}
|
|
1251
1340
|
@click=${() => this.emojiOpen = !this.emojiOpen}
|
|
@@ -1279,8 +1368,8 @@ var OfficeUiChatComposer = class extends TeamsElement {
|
|
|
1279
1368
|
<button
|
|
1280
1369
|
type="button"
|
|
1281
1370
|
class="send"
|
|
1282
|
-
title
|
|
1283
|
-
aria-label
|
|
1371
|
+
title=${this.t("composer.send")}
|
|
1372
|
+
aria-label=${this.t("composer.sendMessage")}
|
|
1284
1373
|
?disabled=${!this.canSend}
|
|
1285
1374
|
@click=${this.submit}
|
|
1286
1375
|
>
|
|
@@ -1331,16 +1420,19 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1331
1420
|
super.connectedCallback();
|
|
1332
1421
|
this.setAttribute("role", "log");
|
|
1333
1422
|
this.setAttribute("aria-live", "polite");
|
|
1334
|
-
this.setAttribute("aria-label", "Messages");
|
|
1335
1423
|
this.addEventListener("scroll", () => {
|
|
1336
1424
|
this.stickToBottom = this.scrollHeight - this.scrollTop - this.clientHeight < 64;
|
|
1337
1425
|
});
|
|
1338
1426
|
}
|
|
1427
|
+
hostLabel() {
|
|
1428
|
+
return this.t("chat.messages");
|
|
1429
|
+
}
|
|
1339
1430
|
updated() {
|
|
1340
1431
|
if (this.stickToBottom) this.scrollTop = this.scrollHeight;
|
|
1341
1432
|
}
|
|
1342
1433
|
render() {
|
|
1343
|
-
if (this.messages.length === 0) return html`<p class="empty"
|
|
1434
|
+
if (this.messages.length === 0) return html`<p class="empty">${this.t("chat.empty")}</p>`;
|
|
1435
|
+
const now = Date.now();
|
|
1344
1436
|
const byId = new Map(this.messages.map((m) => [m.id, m]));
|
|
1345
1437
|
const rows = [];
|
|
1346
1438
|
let previous;
|
|
@@ -1350,9 +1442,9 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1350
1442
|
previous = void 0;
|
|
1351
1443
|
continue;
|
|
1352
1444
|
}
|
|
1353
|
-
if (!previous || dayLabel(previous.ts) !== dayLabel(m.ts))
|
|
1354
|
-
rows.push(html`<div class="day"><span>${dayLabel(m.ts)}</span></div>`);
|
|
1355
|
-
const grouped = previous !== void 0 && previous.authorId === m.authorId && m.ts - previous.ts < GROUP_MS && !m.replyTo && dayLabel(previous.ts) === dayLabel(m.ts);
|
|
1445
|
+
if (!previous || dayLabel(previous.ts, now, this.locale) !== dayLabel(m.ts, now, this.locale))
|
|
1446
|
+
rows.push(html`<div class="day"><span>${dayLabel(m.ts, now, this.locale)}</span></div>`);
|
|
1447
|
+
const grouped = previous !== void 0 && previous.authorId === m.authorId && m.ts - previous.ts < GROUP_MS && !m.replyTo && dayLabel(previous.ts, now, this.locale) === dayLabel(m.ts, now, this.locale);
|
|
1356
1448
|
rows.push(this.message(m, grouped, byId.get(m.replyTo ?? "")));
|
|
1357
1449
|
previous = m;
|
|
1358
1450
|
}
|
|
@@ -1377,18 +1469,18 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1377
1469
|
<div class="body">
|
|
1378
1470
|
${grouped ? nothing : html`<header>
|
|
1379
1471
|
<span class="author">${m.authorName}</span>
|
|
1380
|
-
<time>${formatTime(m.ts)}</time>
|
|
1472
|
+
<time>${formatTime(m.ts, this.locale)}</time>
|
|
1381
1473
|
</header>`}
|
|
1382
1474
|
${this.pinMark(m)}
|
|
1383
1475
|
<div class="bubble">
|
|
1384
1476
|
${parent ? html`<blockquote>
|
|
1385
1477
|
<strong>${parent.authorName}</strong
|
|
1386
|
-
>${parent.deleted ? "
|
|
1478
|
+
>${parent.deleted ? this.t("chat.deleted") : parent.text.slice(0, 120)}
|
|
1387
1479
|
</blockquote>` : nothing}
|
|
1388
|
-
${m.deleted ? html`<span class="deleted"
|
|
1480
|
+
${m.deleted ? html`<span class="deleted">${this.t("chat.deleted")}</span>` : html`<span class="text">${this.body(m)}</span>${m.editedAt ? html` <span class="edited">${this.t("chat.edited")}</span>` : nothing}`}
|
|
1389
1481
|
${!m.deleted && m.meetingId ? this.meetingCard(m.meetingId) : nothing}
|
|
1390
1482
|
${!m.deleted && m.attachments?.length ? this.files(m.attachments) : nothing}
|
|
1391
|
-
${!m.deleted && m.tabId ? html`<button class="thread-link" type="button" @click=${() => this.fire("office-chat-open-tab", { tabId: m.tabId })}
|
|
1483
|
+
${!m.deleted && m.tabId ? html`<button class="thread-link" type="button" @click=${() => this.fire("office-chat-open-tab", { tabId: m.tabId })}>${this.t("chat.openTab")}</button>` : nothing}
|
|
1392
1484
|
</div>
|
|
1393
1485
|
${!m.deleted && reactions.length ? html`<div class="reactions">
|
|
1394
1486
|
${reactions.map(
|
|
@@ -1406,7 +1498,7 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1406
1498
|
)}
|
|
1407
1499
|
</div>` : nothing}
|
|
1408
1500
|
${m.deleted ? nothing : this.toolbar(m, own)}
|
|
1409
|
-
${this.replyCounts[m.id] === void 0 ? nothing : html`<button type="button" class="thread-link" @click=${() => this.fire("office-chat-thread", { messageId: m.id })}>${this.
|
|
1501
|
+
${this.replyCounts[m.id] === void 0 ? nothing : html`<button type="button" class="thread-link" @click=${() => this.fire("office-chat-thread", { messageId: m.id })}>${this.tn("chat.replies", this.replyCounts[m.id])}</button>`}
|
|
1410
1502
|
</div>
|
|
1411
1503
|
</article>
|
|
1412
1504
|
`;
|
|
@@ -1427,38 +1519,38 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1427
1519
|
return html`<div class="meeting-card" data-gone="true">
|
|
1428
1520
|
<span class="meeting-icon">${icon("calendar")}</span>
|
|
1429
1521
|
<span class="meeting-meta">
|
|
1430
|
-
<span class="meeting-title"
|
|
1522
|
+
<span class="meeting-title">${this.t("chat.meetingGone")}</span>
|
|
1431
1523
|
</span>
|
|
1432
1524
|
</div>`;
|
|
1433
1525
|
return html`<div class="meeting-card">
|
|
1434
1526
|
<span class="meeting-icon">${icon("calendar")}</span>
|
|
1435
1527
|
<span class="meeting-meta">
|
|
1436
1528
|
<span class="meeting-title">${card.title}</span>
|
|
1437
|
-
<span class="meeting-time">${formatWhen(card.start, card.end)}</span>
|
|
1529
|
+
<span class="meeting-time">${formatWhen(card.start, card.end, this.locale)}</span>
|
|
1438
1530
|
</span>
|
|
1439
1531
|
<button
|
|
1440
1532
|
type="button"
|
|
1441
1533
|
class="meeting-open"
|
|
1442
1534
|
@click=${() => this.fire("office-chat-meeting", { meetingId, action: "open" })}
|
|
1443
1535
|
>
|
|
1444
|
-
|
|
1536
|
+
${this.t("chat.meetingDetails")}
|
|
1445
1537
|
</button>
|
|
1446
1538
|
<button
|
|
1447
1539
|
type="button"
|
|
1448
1540
|
class="meeting-join"
|
|
1449
1541
|
@click=${() => this.fire("office-chat-meeting", { meetingId, action: "join" })}
|
|
1450
1542
|
>
|
|
1451
|
-
${card.live ? "
|
|
1543
|
+
${this.t(card.live ? "call.joinNow" : "call.join")}
|
|
1452
1544
|
</button>
|
|
1453
1545
|
</div>`;
|
|
1454
1546
|
}
|
|
1455
1547
|
toolbar(m, own) {
|
|
1456
1548
|
return html`
|
|
1457
|
-
<div class="toolbar" role="toolbar" aria-label
|
|
1549
|
+
<div class="toolbar" role="toolbar" aria-label=${this.t("chat.messageActions")}>
|
|
1458
1550
|
${QUICK_REACTIONS.slice(0, 4).map(
|
|
1459
1551
|
(emoji) => html`<button
|
|
1460
1552
|
type="button"
|
|
1461
|
-
aria-label=${
|
|
1553
|
+
aria-label=${this.t("chat.react", { emoji })}
|
|
1462
1554
|
@click=${() => this.fire("office-chat-react", { messageId: m.id, emoji })}
|
|
1463
1555
|
>
|
|
1464
1556
|
${emoji}
|
|
@@ -1466,8 +1558,9 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1466
1558
|
)}
|
|
1467
1559
|
<button
|
|
1468
1560
|
type="button"
|
|
1469
|
-
|
|
1470
|
-
|
|
1561
|
+
data-action="reply"
|
|
1562
|
+
title=${this.t("chat.reply")}
|
|
1563
|
+
aria-label=${this.t("chat.reply")}
|
|
1471
1564
|
@click=${() => this.fire("office-chat-reply", { messageId: m.id })}
|
|
1472
1565
|
>
|
|
1473
1566
|
${icon("reply")}
|
|
@@ -1475,16 +1568,16 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1475
1568
|
${this.pinButton(m)}
|
|
1476
1569
|
${own ? html`<button
|
|
1477
1570
|
type="button"
|
|
1478
|
-
title
|
|
1479
|
-
aria-label
|
|
1571
|
+
title=${this.t("common.edit")}
|
|
1572
|
+
aria-label=${this.t("common.edit")}
|
|
1480
1573
|
@click=${() => this.fire("office-chat-edit", { messageId: m.id })}
|
|
1481
1574
|
>
|
|
1482
1575
|
${icon("pencil")}
|
|
1483
1576
|
</button>
|
|
1484
1577
|
<button
|
|
1485
1578
|
type="button"
|
|
1486
|
-
title
|
|
1487
|
-
aria-label
|
|
1579
|
+
title=${this.t("chat.delete")}
|
|
1580
|
+
aria-label=${this.t("chat.delete")}
|
|
1488
1581
|
@click=${() => this.fire("office-chat-delete", { messageId: m.id })}
|
|
1489
1582
|
>
|
|
1490
1583
|
${icon("trash")}
|
|
@@ -1493,11 +1586,11 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1493
1586
|
`;
|
|
1494
1587
|
}
|
|
1495
1588
|
pinMark(m) {
|
|
1496
|
-
return !m.deleted && this.pinnedIds.includes(m.id) ? html`<span class="pin-mark">${icon("pin")}
|
|
1589
|
+
return !m.deleted && this.pinnedIds.includes(m.id) ? html`<span class="pin-mark">${icon("pin")} ${this.t("chat.pinned")}</span>` : nothing;
|
|
1497
1590
|
}
|
|
1498
1591
|
pinButton(m) {
|
|
1499
1592
|
const pinned = this.pinnedIds.includes(m.id);
|
|
1500
|
-
const label = pinned ? "
|
|
1593
|
+
const label = this.t(pinned ? "chat.unpin" : "chat.pin");
|
|
1501
1594
|
return html`<button
|
|
1502
1595
|
type="button"
|
|
1503
1596
|
title=${label}
|
|
@@ -1515,13 +1608,15 @@ var OfficeUiChatList = class extends TeamsElement {
|
|
|
1515
1608
|
<button
|
|
1516
1609
|
type="button"
|
|
1517
1610
|
class="file"
|
|
1518
|
-
aria-label=${
|
|
1611
|
+
aria-label=${this.t("chat.openFile", { name: a.name })}
|
|
1519
1612
|
@click=${() => this.fire("office-chat-open-file", { attachment: a })}
|
|
1520
1613
|
>
|
|
1521
1614
|
<span class="badge" data-kind=${a.kind}>${KIND_LETTER[a.kind]}</span>
|
|
1522
1615
|
<span class="meta">
|
|
1523
1616
|
<span class="file-name">${a.name}</span>
|
|
1524
|
-
<span class="file-size"
|
|
1617
|
+
<span class="file-size"
|
|
1618
|
+
>${a.kind.toUpperCase()} ${formatSize(a.size, this.locale)}</span
|
|
1619
|
+
>
|
|
1525
1620
|
</span>
|
|
1526
1621
|
</button>
|
|
1527
1622
|
`
|
|
@@ -1535,9 +1630,9 @@ var defineChatList = definer("office-ui-chat-list", () => OfficeUiChatList);
|
|
|
1535
1630
|
var chat_sidebar_default = ":host {\n display: block;\n overflow: auto;\n}\nheader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--office-space-3) var(--office-space-3) var(--office-space-2) var(--office-space-4);\n}\nh2 {\n margin: 0;\n font-size: var(--office-font-size-lg);\n}\n.new {\n display: grid;\n place-items: center;\n width: 2.2em;\n height: 2.2em;\n border: 0;\n border-radius: var(--office-radius-md);\n background: transparent;\n color: var(--office-teams-brand);\n}\n.new:hover {\n background: var(--office-selected);\n}\nul {\n margin: 0;\n padding: 0 var(--office-space-2);\n list-style: none;\n}\n.empty {\n margin: var(--office-space-4);\n color: var(--office-teams-text-subtle);\n}\n.row {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--office-space-3);\n width: 100%;\n padding: var(--office-space-2) var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius);\n background: transparent;\n color: var(--office-teams-text-subtle);\n text-align: start;\n}\n.row:hover {\n background: var(--office-selected);\n}\n.row[aria-current='true'] {\n background: var(--office-teams-brand-subtle);\n color: var(--office-foreground);\n}\n.row[aria-current='true']::before {\n content: '';\n position: absolute;\n inset-inline-start: 0;\n inset-block: 20%;\n width: var(--office-space-1);\n border-radius: var(--office-radius-full);\n background: var(--office-teams-brand);\n}\n.group {\n display: grid;\n place-items: center;\n flex: none;\n width: 2.3em;\n height: 2.3em;\n border-radius: var(--office-radius-full);\n background: var(--office-teams-bubble);\n color: var(--office-teams-brand);\n}\n.text {\n display: grid;\n flex: 1;\n min-width: 0;\n}\n.line {\n display: flex;\n align-items: baseline;\n gap: var(--office-space-2);\n}\n.title {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n color: var(--office-foreground);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\ntime {\n font-size: var(--office-font-size-xs);\n}\n.preview {\n overflow: hidden;\n font-size: var(--office-font-size-sm);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.row[data-unread='true'] .title,\n.row[data-unread='true'] .preview {\n color: var(--office-foreground);\n font-weight: var(--office-font-weight-bold);\n}\n.live {\n display: grid;\n color: var(--office-call-live);\n}\n.count {\n min-width: 1.6em;\n padding: 0 var(--office-space-1);\n border-radius: var(--office-radius-full);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font-size: var(--office-font-size-xs);\n line-height: 1.6;\n text-align: center;\n}\n@media (pointer: coarse) {\n .new,\n .row {\n min-width: var(--office-touch-target, 44px);\n min-height: var(--office-touch-target, 44px);\n }\n}\n";
|
|
1536
1631
|
|
|
1537
1632
|
// src/teams/chat-sidebar.ts
|
|
1538
|
-
function stamp(ts) {
|
|
1633
|
+
function stamp(ts, locale) {
|
|
1539
1634
|
if (!ts) return "";
|
|
1540
|
-
return
|
|
1635
|
+
return dayKind(ts) === "today" ? formatTime(ts, locale) : new Date(ts).toLocaleDateString(teamsI18n(locale).intl, { month: "short", day: "numeric" });
|
|
1541
1636
|
}
|
|
1542
1637
|
var OfficeUiChatSidebar = class extends TeamsElement {
|
|
1543
1638
|
static styles = withStyles(chat_sidebar_default);
|
|
@@ -1553,25 +1648,28 @@ var OfficeUiChatSidebar = class extends TeamsElement {
|
|
|
1553
1648
|
render() {
|
|
1554
1649
|
return html`
|
|
1555
1650
|
<header>
|
|
1556
|
-
<h2
|
|
1651
|
+
<h2>${this.t("rail.chat")}</h2>
|
|
1557
1652
|
<button
|
|
1558
1653
|
class="new"
|
|
1559
1654
|
type="button"
|
|
1560
|
-
title
|
|
1561
|
-
aria-label
|
|
1655
|
+
title=${this.t("chat.new")}
|
|
1656
|
+
aria-label=${this.t("chat.new")}
|
|
1562
1657
|
@click=${() => this.fire("office-chat-new", {})}
|
|
1563
1658
|
>
|
|
1564
1659
|
${icon("plus")}
|
|
1565
1660
|
</button>
|
|
1566
1661
|
</header>
|
|
1567
|
-
${this.chats.length === 0 ? html`<p class="empty"
|
|
1662
|
+
${this.chats.length === 0 ? html`<p class="empty">${this.t("chat.none")}</p>` : html`<ul>
|
|
1568
1663
|
${this.chats.map((c) => this.row(c))}
|
|
1569
1664
|
</ul>`}
|
|
1570
1665
|
`;
|
|
1571
1666
|
}
|
|
1572
1667
|
row(c) {
|
|
1573
1668
|
const other = c.kind === "direct" ? c.members.find((m) => !m.self) : void 0;
|
|
1574
|
-
const preview = c.lastMessage ? c.lastMessage.system ? c.lastMessage.text : c.lastMessage.mine ?
|
|
1669
|
+
const preview = c.lastMessage ? c.lastMessage.system ? c.lastMessage.text : c.lastMessage.mine ? this.t("chat.previewYou", { text: c.lastMessage.text }) : c.kind === "direct" ? c.lastMessage.text : this.t("chat.previewAuthor", {
|
|
1670
|
+
author: c.lastMessage.authorName,
|
|
1671
|
+
text: c.lastMessage.text
|
|
1672
|
+
}) : this.t("chat.noMessagesPreview");
|
|
1575
1673
|
return html`
|
|
1576
1674
|
<li>
|
|
1577
1675
|
<button
|
|
@@ -1591,12 +1689,14 @@ var OfficeUiChatSidebar = class extends TeamsElement {
|
|
|
1591
1689
|
<span class="text">
|
|
1592
1690
|
<span class="line">
|
|
1593
1691
|
<span class="title">${c.title}</span>
|
|
1594
|
-
<time>${stamp(c.ts)}</time>
|
|
1692
|
+
<time>${stamp(c.ts, this.locale)}</time>
|
|
1595
1693
|
</span>
|
|
1596
1694
|
<span class="preview">${preview}</span>
|
|
1597
1695
|
</span>
|
|
1598
|
-
${c.live ? html`<span class="live" title
|
|
1599
|
-
${c.unread ? html`<span
|
|
1696
|
+
${c.live ? html`<span class="live" title=${this.t("call.inProgress")}>${icon("video")}</span>` : nothing}
|
|
1697
|
+
${c.unread ? html`<span
|
|
1698
|
+
class="count"
|
|
1699
|
+
aria-label=${this.t("chat.unreadCount", { count: c.unread })}
|
|
1600
1700
|
>${c.unread > 99 ? "99+" : c.unread}</span
|
|
1601
1701
|
>` : nothing}
|
|
1602
1702
|
</button>
|
|
@@ -1624,7 +1724,7 @@ var OfficeUiPeoplePicker = class extends TeamsElement {
|
|
|
1624
1724
|
this.contacts = [];
|
|
1625
1725
|
this.selected = [];
|
|
1626
1726
|
this.exclude = [];
|
|
1627
|
-
this.label = "
|
|
1727
|
+
this.label = "";
|
|
1628
1728
|
this.query = "";
|
|
1629
1729
|
}
|
|
1630
1730
|
toggle(id) {
|
|
@@ -1637,14 +1737,15 @@ var OfficeUiPeoplePicker = class extends TeamsElement {
|
|
|
1637
1737
|
(c) => !this.exclude.includes(c.id) && (!q || c.name.toLocaleLowerCase().includes(q))
|
|
1638
1738
|
);
|
|
1639
1739
|
const chosen = this.contacts.filter((c) => this.selected.includes(c.id));
|
|
1740
|
+
const label = this.label || this.t("people.label");
|
|
1640
1741
|
return html`
|
|
1641
|
-
${chosen.length ? html`<ul class="chips" aria-label
|
|
1742
|
+
${chosen.length ? html`<ul class="chips" aria-label=${this.t("people.selected")}>
|
|
1642
1743
|
${chosen.map(
|
|
1643
1744
|
(c) => html`<li>
|
|
1644
1745
|
<button
|
|
1645
1746
|
type="button"
|
|
1646
1747
|
class="chip"
|
|
1647
|
-
aria-label=${
|
|
1748
|
+
aria-label=${this.t("people.remove", { name: c.name })}
|
|
1648
1749
|
@click=${() => this.toggle(c.id)}
|
|
1649
1750
|
>
|
|
1650
1751
|
${c.name} <span aria-hidden="true">×</span>
|
|
@@ -1654,14 +1755,14 @@ var OfficeUiPeoplePicker = class extends TeamsElement {
|
|
|
1654
1755
|
</ul>` : nothing}
|
|
1655
1756
|
<input
|
|
1656
1757
|
type="search"
|
|
1657
|
-
placeholder
|
|
1658
|
-
aria-label=${
|
|
1758
|
+
placeholder=${this.t("people.search")}
|
|
1759
|
+
aria-label=${this.t("people.search")}
|
|
1659
1760
|
.value=${this.query}
|
|
1660
1761
|
@input=${(e) => this.query = e.target.value}
|
|
1661
1762
|
/>
|
|
1662
1763
|
${offered.length === 0 ? html`<p class="none">
|
|
1663
|
-
${this.contacts.length === 0 ?
|
|
1664
|
-
</p>` : html`<ul class="list" role="group" aria-label=${
|
|
1764
|
+
${this.contacts.length === 0 ? this.t("people.nobodyElse") : this.t("people.noMatch")}
|
|
1765
|
+
</p>` : html`<ul class="list" role="group" aria-label=${label}>
|
|
1665
1766
|
${offered.map(
|
|
1666
1767
|
(c) => html`<li>
|
|
1667
1768
|
<label>
|
|
@@ -1736,20 +1837,20 @@ var OfficeUiPrejoin = class extends TeamsElement {
|
|
|
1736
1837
|
.muted=${true}
|
|
1737
1838
|
.srcObject=${this.preview}
|
|
1738
1839
|
></video>` : html`<office-ui-avatar size="xl" name=${this.name}></office-ui-avatar>
|
|
1739
|
-
<p>${this.video ? "
|
|
1840
|
+
<p>${this.t(this.video ? "prejoin.startingCamera" : "prejoin.cameraOff")}</p>`}
|
|
1740
1841
|
</div>
|
|
1741
1842
|
<div class="panel">
|
|
1742
|
-
<h2
|
|
1843
|
+
<h2>${this.t("prejoin.title")}</h2>
|
|
1743
1844
|
<p class="for">${this.heading}</p>
|
|
1744
|
-
${this.toggle("
|
|
1745
|
-
${this.toggle("
|
|
1845
|
+
${this.toggle(this.t("prejoin.camera"), this.video ? "video" : "videoOff", this.video, "video")}
|
|
1846
|
+
${this.toggle(this.t("prejoin.microphone"), this.audio ? "mic" : "micOff", this.audio, "audio")}
|
|
1746
1847
|
<div class="actions">
|
|
1747
1848
|
<button
|
|
1748
1849
|
type="button"
|
|
1749
1850
|
class="cancel"
|
|
1750
1851
|
@click=${() => this.fire("office-prejoin-cancel", {})}
|
|
1751
1852
|
>
|
|
1752
|
-
|
|
1853
|
+
${this.t("common.cancel")}
|
|
1753
1854
|
</button>
|
|
1754
1855
|
<button
|
|
1755
1856
|
type="button"
|
|
@@ -1757,7 +1858,7 @@ var OfficeUiPrejoin = class extends TeamsElement {
|
|
|
1757
1858
|
?disabled=${this.busy}
|
|
1758
1859
|
@click=${() => this.fire("office-prejoin-join", {})}
|
|
1759
1860
|
>
|
|
1760
|
-
${this.busy ? "
|
|
1861
|
+
${this.t(this.busy ? "prejoin.joining" : "call.joinNow")}
|
|
1761
1862
|
</button>
|
|
1762
1863
|
</div>
|
|
1763
1864
|
${nothing}
|
|
@@ -1767,6 +1868,71 @@ var OfficeUiPrejoin = class extends TeamsElement {
|
|
|
1767
1868
|
}
|
|
1768
1869
|
};
|
|
1769
1870
|
var definePrejoin = definer("office-ui-prejoin", () => OfficeUiPrejoin);
|
|
1871
|
+
|
|
1872
|
+
// src/teams/i18n/core-text.ts
|
|
1873
|
+
var exact = (text) => new RegExp(`^${text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")}$`, "u");
|
|
1874
|
+
var RULES = [
|
|
1875
|
+
[exact("That person is not available to chat with"), "core.personUnavailable"],
|
|
1876
|
+
[exact("Pick at least one person"), "core.pickPerson"],
|
|
1877
|
+
[exact("The chat could not be created"), "core.chatNotCreated"],
|
|
1878
|
+
[
|
|
1879
|
+
exact("The meeting needs a title and an end after its start (24 hours at most)"),
|
|
1880
|
+
"core.meetingInvalid"
|
|
1881
|
+
],
|
|
1882
|
+
[exact("Only the organizer can change a meeting"), "core.organizerChange"],
|
|
1883
|
+
[exact("Only the organizer can cancel a meeting"), "core.organizerCancel"],
|
|
1884
|
+
[
|
|
1885
|
+
exact("Only the organizer can cancel an occurrence of a meeting"),
|
|
1886
|
+
"core.organizerCancelOccurrence"
|
|
1887
|
+
],
|
|
1888
|
+
[
|
|
1889
|
+
exact("Only the organizer can change an occurrence of a meeting"),
|
|
1890
|
+
"core.organizerChangeOccurrence"
|
|
1891
|
+
],
|
|
1892
|
+
[exact("Camera unavailable"), "core.cameraUnavailable"],
|
|
1893
|
+
[
|
|
1894
|
+
exact("Reattach or discard the missing draft attachments before sending"),
|
|
1895
|
+
"core.reattachDrafts"
|
|
1896
|
+
],
|
|
1897
|
+
[exact("The edit was not applied; the draft was retained"), "core.editNotApplied"],
|
|
1898
|
+
[exact("Message send canceled. The message was saved in Drafts."), "core.sendCanceled"],
|
|
1899
|
+
[
|
|
1900
|
+
/^Message was not sent: (.*)\. Saved in Drafts\.$/su,
|
|
1901
|
+
"core.sendFailed",
|
|
1902
|
+
(m) => ({ reason: m[1] ?? "" })
|
|
1903
|
+
],
|
|
1904
|
+
[exact("This message cannot be pinned"), "core.cannotPin"],
|
|
1905
|
+
[exact("Could not open the file"), "core.openFailed"],
|
|
1906
|
+
[exact("This meeting is not available"), "core.meetingUnavailable"],
|
|
1907
|
+
[exact("The channel is no longer available"), "core.channelGone"],
|
|
1908
|
+
[
|
|
1909
|
+
exact("The channel is no longer available; the uploaded files were not shared"),
|
|
1910
|
+
"core.channelGoneUploaded"
|
|
1911
|
+
],
|
|
1912
|
+
[exact("Configure file storage before sharing files"), "core.configureStorage"],
|
|
1913
|
+
[exact("Configure file storage before sharing attachments"), "core.configureStorage"],
|
|
1914
|
+
[exact("The files could not be shared"), "core.filesNotShared"],
|
|
1915
|
+
[/^Choose between 1 and (\d+) files$/u, "core.chooseFiles", (m) => ({ max: m[1] ?? "" })],
|
|
1916
|
+
[exact("Enter a workbook name"), "core.workbookName"],
|
|
1917
|
+
[/^Upload failed \((\d+)\)$/u, "core.uploadFailed", (m) => ({ status: m[1] ?? "" })],
|
|
1918
|
+
[exact("Server returned an invalid file URL"), "core.invalidFileUrl"],
|
|
1919
|
+
[exact("This file cannot be saved to the channel"), "core.cannotSaveFile"],
|
|
1920
|
+
[exact("The file could not be uploaded"), "core.fileNotUploaded"],
|
|
1921
|
+
[/^Could not load content \((\d+)\)$/u, "core.loadFailed", (m) => ({ status: m[1] ?? "" })],
|
|
1922
|
+
[exact("Content streaming is unavailable"), "core.streamingUnavailable"],
|
|
1923
|
+
[exact("Content is too large to preview"), "core.tooLarge"],
|
|
1924
|
+
[exact("The file is no longer available"), "core.fileGone"],
|
|
1925
|
+
[/^Call is full \((\d+) participants\)$/u, "core.callFull", (m) => ({ max: m[1] ?? "" })],
|
|
1926
|
+
[/^Link failed \((\d+)\)$/u, "core.linkFailed", (m) => ({ status: m[1] ?? "" })]
|
|
1927
|
+
];
|
|
1928
|
+
function localizeCoreText(text, i18n) {
|
|
1929
|
+
if (i18n.locale === "en") return text;
|
|
1930
|
+
for (const [pattern, key, params] of RULES) {
|
|
1931
|
+
const match = pattern.exec(text);
|
|
1932
|
+
if (match) return i18n.t(key, params?.(match));
|
|
1933
|
+
}
|
|
1934
|
+
return text;
|
|
1935
|
+
}
|
|
1770
1936
|
var TeamsController = class {
|
|
1771
1937
|
constructor(host, onNotice, onNotification = () => void 0) {
|
|
1772
1938
|
this.host = host;
|
|
@@ -1903,15 +2069,16 @@ function pickFile(root, accept = OPEN_ACCEPT) {
|
|
|
1903
2069
|
input.click();
|
|
1904
2070
|
});
|
|
1905
2071
|
}
|
|
1906
|
-
function workbookActions(state, actions) {
|
|
2072
|
+
function workbookActions(state, actions, i18n = teamsI18n()) {
|
|
2073
|
+
const { t } = i18n;
|
|
1907
2074
|
return html`<button type="button" ?disabled=${state.saving} @click=${actions.toggle}>
|
|
1908
|
-
${state.editing ? "
|
|
2075
|
+
${t(state.editing ? "workbook.view" : "workbook.edit")}
|
|
1909
2076
|
</button>
|
|
1910
2077
|
<button type="button" ?disabled=${state.saving} @click=${actions.download}>
|
|
1911
|
-
|
|
2078
|
+
${t("workbook.download")}
|
|
1912
2079
|
</button>
|
|
1913
|
-
${state.canShare ? html`<button type="button" ?disabled=${state.saving || !state.editing} @click=${actions.share}>${state.saving ? "
|
|
1914
|
-
${state.saving ? html`<button type="button" @click=${actions.cancel}
|
|
2080
|
+
${state.canShare ? html`<button type="button" ?disabled=${state.saving || !state.editing} @click=${actions.share}>${t(state.saving ? "workbook.saving" : "workbook.saveToChannel")}</button>` : nothing}
|
|
2081
|
+
${state.saving ? html`<button type="button" @click=${actions.cancel}>${t("workbook.cancelSave")}</button>` : nothing}`;
|
|
1915
2082
|
}
|
|
1916
2083
|
function inline(text, base) {
|
|
1917
2084
|
return markdownInline(text, base).map((token) => {
|
|
@@ -1925,7 +2092,7 @@ function inline(text, base) {
|
|
|
1925
2092
|
return token.text;
|
|
1926
2093
|
});
|
|
1927
2094
|
}
|
|
1928
|
-
function markdownPreview(source, base) {
|
|
2095
|
+
function markdownPreview(source, base, i18n = teamsI18n()) {
|
|
1929
2096
|
return markdownBlocks(source).map((block) => {
|
|
1930
2097
|
if (block.kind === "code") return html`<pre><code>${block.text}</code></pre>`;
|
|
1931
2098
|
if (block.kind === "table" && block.table) {
|
|
@@ -1934,7 +2101,7 @@ function markdownPreview(source, base) {
|
|
|
1934
2101
|
class="markdown-table"
|
|
1935
2102
|
tabindex="0"
|
|
1936
2103
|
role="region"
|
|
1937
|
-
aria-label
|
|
2104
|
+
aria-label=${i18n.t("preview.markdownTable")}
|
|
1938
2105
|
>
|
|
1939
2106
|
<table>
|
|
1940
2107
|
<thead>
|
|
@@ -1967,7 +2134,7 @@ function markdownPreview(source, base) {
|
|
|
1967
2134
|
}
|
|
1968
2135
|
|
|
1969
2136
|
// src/teams/app/content-preview.ts
|
|
1970
|
-
var TeamsContentPreview = class extends
|
|
2137
|
+
var TeamsContentPreview = class extends TeamsLitElement {
|
|
1971
2138
|
static styles = unsafeCSS(content_preview_default);
|
|
1972
2139
|
static properties = {
|
|
1973
2140
|
detail: { attribute: false },
|
|
@@ -2029,14 +2196,14 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2029
2196
|
/** Called by the workspace before replacing this pane. */
|
|
2030
2197
|
canLeave() {
|
|
2031
2198
|
if (this.saving) {
|
|
2032
|
-
this.saveError = "
|
|
2199
|
+
this.saveError = this.t("preview.waitSave");
|
|
2033
2200
|
return false;
|
|
2034
2201
|
}
|
|
2035
2202
|
if (!this.commitPendingEdit()) {
|
|
2036
|
-
this.saveError = "
|
|
2203
|
+
this.saveError = this.t("preview.finishEditLeave");
|
|
2037
2204
|
return false;
|
|
2038
2205
|
}
|
|
2039
|
-
return !this.dirty || globalThis.confirm?.("
|
|
2206
|
+
return !this.dirty || globalThis.confirm?.(this.t("preview.discardEdits")) === true;
|
|
2040
2207
|
}
|
|
2041
2208
|
commitPendingEdit() {
|
|
2042
2209
|
const viewer = this.shadowRoot?.querySelector(
|
|
@@ -2064,15 +2231,15 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2064
2231
|
const kind = detectContentKind(detail.attachment.name, detail.attachment.mime);
|
|
2065
2232
|
try {
|
|
2066
2233
|
const url = contentUrl(detail.url, this.ownerDocument.baseURI);
|
|
2067
|
-
if (!url) throw new Error("
|
|
2234
|
+
if (!url) throw new Error(this.t("preview.noUrl"));
|
|
2068
2235
|
const embed = this.embeds[detail.attachment.kind];
|
|
2069
2236
|
if (embed || kind === "website") {
|
|
2070
2237
|
this.frame = contentUrl(embed ? embed(detail) : url, this.ownerDocument.baseURI);
|
|
2071
|
-
if (!this.frame) throw new Error("
|
|
2238
|
+
if (!this.frame) throw new Error(this.t("preview.badEmbed"));
|
|
2072
2239
|
this.status = "ready";
|
|
2073
2240
|
return;
|
|
2074
2241
|
}
|
|
2075
|
-
if (kind === "other") throw new Error(
|
|
2242
|
+
if (kind === "other") throw new Error(this.t("preview.noViewer"));
|
|
2076
2243
|
const bytes = await readContent(
|
|
2077
2244
|
url,
|
|
2078
2245
|
request.signal,
|
|
@@ -2086,26 +2253,26 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2086
2253
|
if (kind === "xlsx") (await import('./xlsx.js')).defineXlsxEditor();
|
|
2087
2254
|
if (kind === "vsdx") (await import('./visio.js')).registerVisioViewer();
|
|
2088
2255
|
if (kind === "pptx")
|
|
2089
|
-
(await import('./presentation-preview-
|
|
2256
|
+
(await import('./presentation-preview-HMEBDYEL.js')).defineTeamsPresentationPreview();
|
|
2090
2257
|
if (request.signal.aborted) return;
|
|
2091
2258
|
this.native = kind;
|
|
2092
2259
|
await this.updateComplete;
|
|
2093
2260
|
if (request.signal.aborted) return;
|
|
2094
2261
|
const viewer = this.shadowRoot?.querySelector("docx-editor, xlsx-editor, visio-viewer, teams-presentation-preview");
|
|
2095
|
-
if (!viewer) throw new Error("
|
|
2262
|
+
if (!viewer) throw new Error(this.t("preview.notMounted"));
|
|
2096
2263
|
await viewer.load(bytes, detail.attachment.name);
|
|
2097
2264
|
}
|
|
2098
2265
|
if (!request.signal.aborted) this.status = "ready";
|
|
2099
2266
|
} catch (error) {
|
|
2100
2267
|
if (request.signal.aborted) return;
|
|
2101
2268
|
this.native = null;
|
|
2102
|
-
this.error = error instanceof Error ? error.message : "
|
|
2269
|
+
this.error = error instanceof Error ? localizeCoreText(error.message, this.i18n) : this.t("preview.failed");
|
|
2103
2270
|
this.status = "error";
|
|
2104
2271
|
}
|
|
2105
2272
|
}
|
|
2106
2273
|
toggleWorkbook() {
|
|
2107
2274
|
if (!this.commitPendingEdit()) {
|
|
2108
|
-
this.saveError = "
|
|
2275
|
+
this.saveError = this.t("preview.finishEditSwitch");
|
|
2109
2276
|
return;
|
|
2110
2277
|
}
|
|
2111
2278
|
this.saveError = "";
|
|
@@ -2115,7 +2282,7 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2115
2282
|
if (this.saving || !download && !this.saveCopy || this.native !== "xlsx" || !this.detail)
|
|
2116
2283
|
return;
|
|
2117
2284
|
if (!this.commitPendingEdit()) {
|
|
2118
|
-
this.saveError = "
|
|
2285
|
+
this.saveError = this.t("preview.finishEditSave");
|
|
2119
2286
|
return;
|
|
2120
2287
|
}
|
|
2121
2288
|
const viewer = this.shadowRoot?.querySelector("xlsx-editor");
|
|
@@ -2150,7 +2317,7 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2150
2317
|
this.saved = true;
|
|
2151
2318
|
} catch (error) {
|
|
2152
2319
|
if (!request?.signal.aborted && !controller.signal.aborted)
|
|
2153
|
-
this.saveError = error instanceof Error ? error.message : "
|
|
2320
|
+
this.saveError = error instanceof Error ? localizeCoreText(error.message, this.i18n) : this.t("preview.saveFailed");
|
|
2154
2321
|
} finally {
|
|
2155
2322
|
if (this.saveAbort === controller) {
|
|
2156
2323
|
this.saveAbort = void 0;
|
|
@@ -2162,14 +2329,14 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2162
2329
|
this.saveAbort?.abort();
|
|
2163
2330
|
this.saveAbort = void 0;
|
|
2164
2331
|
this.saving = false;
|
|
2165
|
-
this.saveError = "
|
|
2332
|
+
this.saveError = this.t("preview.saveCanceled");
|
|
2166
2333
|
}
|
|
2167
2334
|
render() {
|
|
2168
2335
|
const detail = this.detail;
|
|
2169
2336
|
if (!detail) return nothing;
|
|
2170
2337
|
const kind = detectContentKind(detail.attachment.name, detail.attachment.mime);
|
|
2171
2338
|
const url = contentUrl(detail.url, this.ownerDocument.baseURI);
|
|
2172
|
-
return html`<section aria-label
|
|
2339
|
+
return html`<section aria-label=${this.t("preview.title")}>
|
|
2173
2340
|
<header>
|
|
2174
2341
|
<h2>${detail.attachment.name}</h2>
|
|
2175
2342
|
${this.native === "xlsx" && this.status === "ready" ? workbookActions(
|
|
@@ -2179,24 +2346,27 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2179
2346
|
share: () => void this.saveWorkbookCopy(),
|
|
2180
2347
|
download: () => void this.saveWorkbookCopy(true),
|
|
2181
2348
|
cancel: () => this.cancelWorkbookSave()
|
|
2182
|
-
}
|
|
2349
|
+
},
|
|
2350
|
+
this.i18n
|
|
2183
2351
|
) : nothing}
|
|
2184
|
-
${url ? html`<a href=${url} target="_blank" rel="noopener noreferrer"
|
|
2352
|
+
${url ? html`<a href=${url} target="_blank" rel="noopener noreferrer">${this.t("preview.openExternally")}</a>` : nothing}
|
|
2185
2353
|
<button
|
|
2186
2354
|
type="button"
|
|
2187
2355
|
@click=${() => this.dispatchEvent(new CustomEvent("teams-preview-close", { bubbles: true, composed: true }))}
|
|
2188
2356
|
>
|
|
2189
|
-
|
|
2357
|
+
${this.t("preview.close")}
|
|
2190
2358
|
</button>
|
|
2191
2359
|
</header>
|
|
2192
|
-
${this.native === "xlsx" ? html`<p class="hint"
|
|
2193
|
-
${this.saved ? html`<p role="status"
|
|
2194
|
-
${this.downloaded ? html`<p role="status"
|
|
2360
|
+
${this.native === "xlsx" ? html`<p class="hint">${this.t(this.saveCopy ? "preview.editsLocalShare" : "preview.editsLocal")}</p>` : nothing}
|
|
2361
|
+
${this.saved ? html`<p role="status">${this.t("preview.copyShared")}</p>` : nothing}
|
|
2362
|
+
${this.downloaded ? html`<p role="status">${this.t("preview.downloadStarted")}</p>` : nothing}
|
|
2195
2363
|
${this.saveError ? html`<p role="alert">${this.saveError}</p>` : nothing}
|
|
2196
|
-
${this.status === "loading" ? html`<p role="status"
|
|
2364
|
+
${this.status === "loading" ? html`<p role="status">${this.t("preview.loading")}</p>` : nothing}
|
|
2197
2365
|
${this.status === "error" ? html`<p role="alert">${this.error}</p>
|
|
2198
|
-
<button type="button" @click=${() => void this.load()}>
|
|
2199
|
-
|
|
2366
|
+
<button type="button" @click=${() => void this.load()}>
|
|
2367
|
+
${this.t("common.retry")}
|
|
2368
|
+
</button>` : nothing}
|
|
2369
|
+
${this.frame ? html`<p class="hint">${this.t("preview.blocksEmbedding")}</p>
|
|
2200
2370
|
<iframe
|
|
2201
2371
|
title=${detail.attachment.name}
|
|
2202
2372
|
src=${this.frame}
|
|
@@ -2205,8 +2375,13 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2205
2375
|
></iframe>` : nothing}
|
|
2206
2376
|
${keyed(
|
|
2207
2377
|
detail,
|
|
2208
|
-
this.native === "docx" ? html`<docx-editor
|
|
2378
|
+
this.native === "docx" ? html`<docx-editor
|
|
2379
|
+
.readOnly=${true}
|
|
2380
|
+
.locale=${this.i18n.locale}
|
|
2381
|
+
.fileName=${detail.attachment.name}
|
|
2382
|
+
></docx-editor>` : this.native === "xlsx" ? html`<xlsx-editor
|
|
2209
2383
|
.readOnly=${!this.editing}
|
|
2384
|
+
.locale=${this.i18n.locale}
|
|
2210
2385
|
.fileName=${detail.attachment.name}
|
|
2211
2386
|
@workbook-change=${() => {
|
|
2212
2387
|
this.revision++;
|
|
@@ -2220,7 +2395,7 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2220
2395
|
@file-command=${(e) => {
|
|
2221
2396
|
if (["save", "saveAs", "export", "exportCsv"].includes(e.detail.command) && !this.commitPendingEdit()) {
|
|
2222
2397
|
e.preventDefault();
|
|
2223
|
-
this.saveError = "
|
|
2398
|
+
this.saveError = this.t("preview.finishEditSave");
|
|
2224
2399
|
return;
|
|
2225
2400
|
}
|
|
2226
2401
|
if (e.detail.command === "save") {
|
|
@@ -2229,10 +2404,10 @@ var TeamsContentPreview = class extends LitElement {
|
|
|
2229
2404
|
}
|
|
2230
2405
|
if (e.detail.command === "new" || e.detail.command === "open") e.preventDefault();
|
|
2231
2406
|
}}
|
|
2232
|
-
></xlsx-editor>` : this.native === "vsdx" ? html`<visio-viewer .showToolbar=${false}></visio-viewer>` : this.native === "pptx" ? html`<teams-presentation-preview></teams-presentation-preview>` : nothing
|
|
2407
|
+
></xlsx-editor>` : this.native === "vsdx" ? html`<visio-viewer .showToolbar=${false} locale=${this.i18n.locale}></visio-viewer>` : this.native === "pptx" ? html`<teams-presentation-preview></teams-presentation-preview>` : nothing
|
|
2233
2408
|
)}
|
|
2234
2409
|
${this.status === "ready" && !this.frame && !this.native ? html`<article>
|
|
2235
|
-
${kind === "markdown" ? markdownPreview(this.text, url) : html`<pre>${this.text}</pre>`}
|
|
2410
|
+
${kind === "markdown" ? markdownPreview(this.text, url, this.i18n) : html`<pre>${this.text}</pre>`}
|
|
2236
2411
|
</article>` : nothing}
|
|
2237
2412
|
</section>`;
|
|
2238
2413
|
}
|
|
@@ -2246,7 +2421,7 @@ function defineTeamsContentPreview() {
|
|
|
2246
2421
|
var channel_tab_default = ":host {\n display: flex;\n flex: 1;\n min-height: 0;\n min-width: 0;\n}\n";
|
|
2247
2422
|
|
|
2248
2423
|
// src/teams/app/channel-tab.ts
|
|
2249
|
-
var TeamsChannelTab = class extends
|
|
2424
|
+
var TeamsChannelTab = class extends TeamsLitElement {
|
|
2250
2425
|
static styles = unsafeCSS(channel_tab_default);
|
|
2251
2426
|
static properties = {
|
|
2252
2427
|
tab: { attribute: false },
|
|
@@ -2298,12 +2473,12 @@ var TeamsChannelTab = class extends LitElement {
|
|
|
2298
2473
|
try {
|
|
2299
2474
|
const url = tab.content.type === "file" ? await client.fileUrl(attachment) : attachment.url;
|
|
2300
2475
|
if (generation !== this.generation || !this.isConnected) return;
|
|
2301
|
-
if (!url) throw new Error("
|
|
2476
|
+
if (!url) throw new Error(this.t("tab.unresolved"));
|
|
2302
2477
|
this.detail = { attachment, url, channelId: tab.channelId };
|
|
2303
2478
|
if (tab.content.type === "file") this.openInHost();
|
|
2304
2479
|
} catch (error) {
|
|
2305
2480
|
if (generation === this.generation)
|
|
2306
|
-
this.error = error instanceof Error ? error.message : "
|
|
2481
|
+
this.error = error instanceof Error ? localizeCoreText(error.message, this.i18n) : this.t("tab.openFailed");
|
|
2307
2482
|
}
|
|
2308
2483
|
}
|
|
2309
2484
|
saveCopy() {
|
|
@@ -2326,7 +2501,9 @@ var TeamsChannelTab = class extends LitElement {
|
|
|
2326
2501
|
render() {
|
|
2327
2502
|
if (this.hostOpened)
|
|
2328
2503
|
return html`<p>${this.detail?.attachment.name}</p>
|
|
2329
|
-
<button type="button" @click=${() => this.openInHost()}>
|
|
2504
|
+
<button type="button" @click=${() => this.openInHost()}>
|
|
2505
|
+
${this.t("tab.openDocument")}
|
|
2506
|
+
</button>`;
|
|
2330
2507
|
return html`${this.error ? html`<p role="alert">${this.error}</p>
|
|
2331
2508
|
<button
|
|
2332
2509
|
type="button"
|
|
@@ -2335,12 +2512,12 @@ var TeamsChannelTab = class extends LitElement {
|
|
|
2335
2512
|
void this.resolve();
|
|
2336
2513
|
}}
|
|
2337
2514
|
>
|
|
2338
|
-
|
|
2515
|
+
${this.t("common.retry")}
|
|
2339
2516
|
</button>` : this.detail ? html`<teams-content-preview
|
|
2340
2517
|
.detail=${this.detail}
|
|
2341
2518
|
.embeds=${this.embeds}
|
|
2342
2519
|
.saveCopy=${this.saveCopy()}
|
|
2343
|
-
></teams-content-preview>` : html`<p role="status"
|
|
2520
|
+
></teams-content-preview>` : html`<p role="status">${this.t("tab.opening")}</p>`}`;
|
|
2344
2521
|
}
|
|
2345
2522
|
};
|
|
2346
2523
|
function defineTeamsChannelTab() {
|
|
@@ -2373,7 +2550,7 @@ function toggleAnchoredPopover(panel, trigger) {
|
|
|
2373
2550
|
|
|
2374
2551
|
// src/teams/app/file-actions.ts
|
|
2375
2552
|
var fileKey = (file) => JSON.stringify([file?.channelId, file?.messageId, file?.url, file?.name]);
|
|
2376
|
-
var TeamsFileActions = class extends
|
|
2553
|
+
var TeamsFileActions = class extends TeamsLitElement {
|
|
2377
2554
|
static styles = unsafeCSS(file_actions_default);
|
|
2378
2555
|
static properties = {
|
|
2379
2556
|
file: { attribute: false },
|
|
@@ -2442,7 +2619,7 @@ var TeamsFileActions = class extends LitElement {
|
|
|
2442
2619
|
try {
|
|
2443
2620
|
const url = contentUrl(await client.fileUrl(file), this.ownerDocument.baseURI);
|
|
2444
2621
|
if (!this.isConnected || abort.signal.aborted) return;
|
|
2445
|
-
if (!url) throw new Error("
|
|
2622
|
+
if (!url) throw new Error(this.t("core.fileGone"));
|
|
2446
2623
|
if (action === "download") {
|
|
2447
2624
|
const bytes = await readContent(url, abort.signal, 33554432);
|
|
2448
2625
|
if (this.isConnected && !abort.signal.aborted)
|
|
@@ -2462,7 +2639,7 @@ var TeamsFileActions = class extends LitElement {
|
|
|
2462
2639
|
}
|
|
2463
2640
|
} catch (error) {
|
|
2464
2641
|
if (!abort.signal.aborted)
|
|
2465
|
-
this.error = error instanceof Error ? error.message :
|
|
2642
|
+
this.error = error instanceof Error ? localizeCoreText(error.message, this.i18n) : this.t("files.accessFailed");
|
|
2466
2643
|
} finally {
|
|
2467
2644
|
if (this.abort === abort) {
|
|
2468
2645
|
this.abort = void 0;
|
|
@@ -2473,7 +2650,7 @@ var TeamsFileActions = class extends LitElement {
|
|
|
2473
2650
|
render() {
|
|
2474
2651
|
return html`<button
|
|
2475
2652
|
type="button"
|
|
2476
|
-
aria-label=${
|
|
2653
|
+
aria-label=${this.t("files.moreActions", { name: this.file?.name ?? this.t("files.fileFallback") })}
|
|
2477
2654
|
?disabled=${!this.file?.url}
|
|
2478
2655
|
aria-controls="actions"
|
|
2479
2656
|
aria-expanded=${String(this.menuOpen)}
|
|
@@ -2484,23 +2661,29 @@ var TeamsFileActions = class extends LitElement {
|
|
|
2484
2661
|
<div
|
|
2485
2662
|
id="actions"
|
|
2486
2663
|
popover="auto"
|
|
2487
|
-
aria-label
|
|
2664
|
+
aria-label=${this.t("files.actions")}
|
|
2488
2665
|
@toggle=${() => this.menuOpen = this.renderRoot.querySelector("[popover]").matches(":popover-open")}
|
|
2489
2666
|
>
|
|
2490
|
-
<button type="button" @click=${() => this.open("open")}>
|
|
2491
|
-
|
|
2667
|
+
<button type="button" @click=${() => this.open("open")}>
|
|
2668
|
+
${this.t("files.openInTeams")}
|
|
2669
|
+
</button>
|
|
2670
|
+
<button type="button" @click=${() => this.open("browser")}>
|
|
2671
|
+
${this.t("files.openInBrowser")}
|
|
2672
|
+
</button>
|
|
2492
2673
|
<button type="button" ?disabled=${this.busy} @click=${() => void this.transfer("download")}>
|
|
2493
|
-
|
|
2674
|
+
${this.t("files.download")}
|
|
2494
2675
|
</button>
|
|
2495
2676
|
<button type="button" ?disabled=${this.busy} @click=${() => void this.transfer("copy")}>
|
|
2496
|
-
|
|
2677
|
+
${this.t("files.copyLink")}
|
|
2497
2678
|
</button>
|
|
2498
|
-
<button type="button" @click=${() => this.open("pin")}
|
|
2499
|
-
${this.busy ? html`<p role="status"
|
|
2500
|
-
<button type="button" @click=${() => this.abort?.abort()}>
|
|
2679
|
+
<button type="button" @click=${() => this.open("pin")}>${this.t("files.pinAsTab")}</button>
|
|
2680
|
+
${this.busy ? html`<p role="status">${this.t("files.preparingFile")}</p>
|
|
2681
|
+
<button type="button" @click=${() => this.abort?.abort()}>
|
|
2682
|
+
${this.t("common.cancel")}
|
|
2683
|
+
</button>` : nothing}
|
|
2501
2684
|
${this.error ? html`<p role="alert">${this.error}</p>` : nothing}
|
|
2502
|
-
${this.copied ? html`<p role="status"
|
|
2503
|
-
${this.copyUrl ? html`<label
|
|
2685
|
+
${this.copied ? html`<p role="status">${this.t("files.linkCopied")}</p>` : nothing}
|
|
2686
|
+
${this.copyUrl ? html`<label>${this.t("files.fileLink")}<input readonly .value=${this.copyUrl} @focus=${(event) => event.target.select()} /></label>` : nothing}
|
|
2504
2687
|
</div>`;
|
|
2505
2688
|
}
|
|
2506
2689
|
};
|
|
@@ -2510,7 +2693,7 @@ function defineTeamsFileActions() {
|
|
|
2510
2693
|
}
|
|
2511
2694
|
|
|
2512
2695
|
// src/teams/app/files-panel.ts
|
|
2513
|
-
var TeamsFilesPanel = class extends
|
|
2696
|
+
var TeamsFilesPanel = class extends TeamsLitElement {
|
|
2514
2697
|
static styles = unsafeCSS(files_panel_default);
|
|
2515
2698
|
static properties = {
|
|
2516
2699
|
client: { attribute: false },
|
|
@@ -2601,7 +2784,7 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2601
2784
|
if (this.client === client && this.active === controller && this.isConnected) {
|
|
2602
2785
|
this.canceled = controller.signal.aborted;
|
|
2603
2786
|
if (!this.canceled)
|
|
2604
|
-
this.error = error instanceof Error ? error.message : "
|
|
2787
|
+
this.error = error instanceof Error ? localizeCoreText(error.message, this.i18n) : this.t("files.shareFailed");
|
|
2605
2788
|
}
|
|
2606
2789
|
} finally {
|
|
2607
2790
|
if (this.active === controller) {
|
|
@@ -2654,10 +2837,10 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2654
2837
|
this.sortDirection
|
|
2655
2838
|
);
|
|
2656
2839
|
const disabled = this.busy || !this.canUpload || !this.channelId;
|
|
2657
|
-
return html`<div class="toolbar" role="toolbar" aria-label
|
|
2840
|
+
return html`<div class="toolbar" role="toolbar" aria-label=${this.t("files.actions")}>
|
|
2658
2841
|
<office-ui-menu-button
|
|
2659
2842
|
class="new-command"
|
|
2660
|
-
label
|
|
2843
|
+
label=${this.t("files.new")}
|
|
2661
2844
|
.disabled=${disabled}
|
|
2662
2845
|
@office-command=${async (event) => {
|
|
2663
2846
|
if (event.detail.command !== "new-workbook" || disabled) return;
|
|
@@ -2667,7 +2850,7 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2667
2850
|
}}
|
|
2668
2851
|
>
|
|
2669
2852
|
<office-ui-menu-item
|
|
2670
|
-
label
|
|
2853
|
+
label=${this.t("files.newWorkbook")}
|
|
2671
2854
|
command="new-workbook"
|
|
2672
2855
|
></office-ui-menu-item>
|
|
2673
2856
|
</office-ui-menu-button>
|
|
@@ -2676,12 +2859,12 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2676
2859
|
?disabled=${disabled}
|
|
2677
2860
|
@click=${() => this.renderRoot.querySelector('input[type="file"]')?.click()}
|
|
2678
2861
|
>
|
|
2679
|
-
${icon("upload")}
|
|
2862
|
+
${icon("upload")} ${this.t("files.upload")}
|
|
2680
2863
|
</button>
|
|
2681
2864
|
<input
|
|
2682
2865
|
type="file"
|
|
2683
2866
|
class="file-picker"
|
|
2684
|
-
aria-label
|
|
2867
|
+
aria-label=${this.t("files.uploadFiles")}
|
|
2685
2868
|
multiple
|
|
2686
2869
|
?disabled=${disabled}
|
|
2687
2870
|
@change=${this.upload}
|
|
@@ -2689,55 +2872,67 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2689
2872
|
<span class="toolbar-space"></span>
|
|
2690
2873
|
<input
|
|
2691
2874
|
type="search"
|
|
2692
|
-
aria-label
|
|
2693
|
-
placeholder
|
|
2875
|
+
aria-label=${this.t("files.search")}
|
|
2876
|
+
placeholder=${this.t("files.search")}
|
|
2694
2877
|
.value=${this.query}
|
|
2695
2878
|
@input=${(e) => this.query = e.target.value}
|
|
2696
2879
|
/>
|
|
2697
2880
|
</div>
|
|
2698
2881
|
<p class="hint">
|
|
2699
|
-
${this.canUpload ?
|
|
2882
|
+
${this.canUpload ? this.t("files.sharedIn", { channel: this.channelName }) : this.t("files.configureStorage")}
|
|
2700
2883
|
</p>
|
|
2701
|
-
${this.creating ? html`<form aria-label
|
|
2884
|
+
${this.creating ? html`<form aria-label=${this.t("files.createWorkbook")} @submit=${this.create}>
|
|
2702
2885
|
<input
|
|
2703
2886
|
name="name"
|
|
2704
|
-
aria-label
|
|
2705
|
-
placeholder
|
|
2887
|
+
aria-label=${this.t("files.workbookName")}
|
|
2888
|
+
placeholder=${this.t("files.workbookName")}
|
|
2706
2889
|
maxlength="75"
|
|
2707
2890
|
required
|
|
2708
2891
|
?disabled=${this.busy}
|
|
2709
2892
|
/>
|
|
2710
|
-
<button type="submit" ?disabled=${disabled}>
|
|
2893
|
+
<button type="submit" ?disabled=${disabled}>
|
|
2894
|
+
${this.t("files.createWorkbookButton")}
|
|
2895
|
+
</button>
|
|
2711
2896
|
<button type="button" ?disabled=${this.busy} @click=${() => this.creating = false}>
|
|
2712
|
-
|
|
2897
|
+
${this.t("common.cancel")}
|
|
2713
2898
|
</button>
|
|
2714
2899
|
</form>` : nothing}
|
|
2715
2900
|
${this.busy ? html`<div class="transfer">
|
|
2716
2901
|
<p role="status">
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2902
|
+
${this.t("files.sharing", {
|
|
2903
|
+
channel: this.destination,
|
|
2904
|
+
phase: this.t(
|
|
2905
|
+
this.transfer?.phase === "preparing" ? "files.preparing" : "files.uploading"
|
|
2906
|
+
),
|
|
2907
|
+
file: this.transfer?.fileName ?? "",
|
|
2908
|
+
completed: this.transfer?.completed ?? 0,
|
|
2909
|
+
total: this.transfer?.total ?? 0
|
|
2910
|
+
})}
|
|
2721
2911
|
</p>
|
|
2722
|
-
${this.transfer ? html`<progress aria-label
|
|
2723
|
-
<button type="button" @click=${() => this.active?.abort()}>
|
|
2912
|
+
${this.transfer ? html`<progress aria-label=${this.t("files.uploaded")} max=${this.transfer.total} value=${this.transfer.completed}></progress>` : nothing}
|
|
2913
|
+
<button type="button" @click=${() => this.active?.abort()}>
|
|
2914
|
+
${this.t("files.cancelSharing")}
|
|
2915
|
+
</button>
|
|
2724
2916
|
</div>` : nothing}
|
|
2725
|
-
${this.error || this.canceled ? html`${this.canceled ? html`<p role="status"
|
|
2917
|
+
${this.error || this.canceled ? html`${this.canceled ? html`<p role="status">${this.t("files.canceled", { channel: this.destination })}</p>` : html`<p role="alert">${this.t("files.failed", { channel: this.destination, error: this.error })}</p>`}
|
|
2726
2918
|
<button
|
|
2727
2919
|
type="button"
|
|
2728
2920
|
?disabled=${this.busy}
|
|
2729
2921
|
@click=${() => this.retry && void this.run(this.retry)}
|
|
2730
2922
|
>
|
|
2731
|
-
|
|
2923
|
+
${this.t("files.retry")}
|
|
2732
2924
|
</button>` : nothing}
|
|
2733
2925
|
<div class="file-list">
|
|
2734
|
-
<table aria-label
|
|
2926
|
+
<table aria-label=${this.t("files.shared")}>
|
|
2735
2927
|
<thead>
|
|
2736
2928
|
<tr>
|
|
2737
|
-
${this.sortHeading("name",
|
|
2738
|
-
${this.sortHeading("
|
|
2739
|
-
|
|
2740
|
-
<th scope="col"
|
|
2929
|
+
${this.sortHeading("name", this.t("files.name"))}
|
|
2930
|
+
${this.sortHeading("ts", this.t("files.sharedOn"))}
|
|
2931
|
+
${this.sortHeading("author", this.t("files.sharedBy"))}
|
|
2932
|
+
<th scope="col">${this.t("files.location")}</th>
|
|
2933
|
+
<th scope="col">
|
|
2934
|
+
<span class="visually-hidden">${this.t("files.actionsColumn")}</span>
|
|
2935
|
+
</th>
|
|
2741
2936
|
</tr>
|
|
2742
2937
|
</thead>
|
|
2743
2938
|
<tbody>
|
|
@@ -2751,7 +2946,7 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2751
2946
|
<button
|
|
2752
2947
|
class="file-open"
|
|
2753
2948
|
type="button"
|
|
2754
|
-
aria-label=${
|
|
2949
|
+
aria-label=${this.t("chat.openFile", { name: file.name })}
|
|
2755
2950
|
title=${file.name}
|
|
2756
2951
|
?disabled=${!file.url}
|
|
2757
2952
|
@click=${() => this.emit("open", file)}
|
|
@@ -2760,7 +2955,9 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2760
2955
|
</button>
|
|
2761
2956
|
</div>
|
|
2762
2957
|
</td>
|
|
2763
|
-
<td
|
|
2958
|
+
<td>
|
|
2959
|
+
<time>${new Date(file.ts).toLocaleDateString(this.i18n.intl)}</time>
|
|
2960
|
+
</td>
|
|
2764
2961
|
<td>${file.author}</td>
|
|
2765
2962
|
<td>
|
|
2766
2963
|
${file.channelName ? `# ${file.channelName}` : `# ${this.channelName}`}
|
|
@@ -2774,7 +2971,7 @@ var TeamsFilesPanel = class extends LitElement {
|
|
|
2774
2971
|
</tr>`
|
|
2775
2972
|
) : html`<tr>
|
|
2776
2973
|
<td colspan="5" class="none">
|
|
2777
|
-
${this.query.trim() ? "
|
|
2974
|
+
${this.t(this.query.trim() ? "files.noMatch" : "files.none")}
|
|
2778
2975
|
</td>
|
|
2779
2976
|
</tr>`}
|
|
2780
2977
|
</tbody>
|
|
@@ -2792,8 +2989,13 @@ var teams_settings_default = ":host {\n font: var(--office-font-size) var(--offi
|
|
|
2792
2989
|
|
|
2793
2990
|
// raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/teams/app/settings-previews.css?raw
|
|
2794
2991
|
var settings_previews_default = ".theme-options,\n.density-options {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-3);\n}\n.theme-options button {\n display: grid;\n gap: var(--office-space-3);\n padding: var(--office-space-2);\n text-align: start;\n min-width: 9em;\n}\n.theme-options button[aria-pressed='true'],\n.density-choice:has(input:checked) {\n border-color: var(--office-teams-brand);\n box-shadow: inset 0 0 0 var(--office-border-width) var(--office-teams-brand);\n}\n.theme-swatch {\n --preview-paper: var(--office-call-foreground);\n --preview-ink: var(--office-call-background);\n display: grid;\n grid-template-columns: 0.7em 2.4em 1fr;\n grid-template-rows: 0.7em 1fr;\n width: 9em;\n height: 5.5em;\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius);\n overflow: hidden;\n background: var(--preview-paper);\n}\n.theme-swatch[data-theme='dark'] {\n --preview-paper: var(--office-call-background);\n --preview-ink: var(--office-call-foreground);\n}\n.theme-swatch[data-theme='system'] {\n background: linear-gradient(\n 90deg,\n var(--office-call-foreground) 50%,\n var(--office-call-background) 50%\n );\n}\n.preview-toolbar {\n grid-column: 1 / -1;\n background: var(--office-teams-brand);\n}\n.preview-rail,\n.preview-sidebar {\n background: color-mix(in srgb, var(--preview-ink) 8%, var(--preview-paper));\n border-inline-end: var(--office-border-width) solid var(--office-teams-divider);\n}\n.preview-sidebar,\n.preview-conversation {\n display: flex;\n flex-direction: column;\n gap: var(--office-space-2);\n padding: var(--office-space-2);\n}\n.preview-sidebar i,\n.preview-conversation i {\n height: 0.4em;\n border-radius: var(--office-radius);\n background: color-mix(in srgb, var(--preview-ink) 25%, var(--preview-paper));\n}\n.preview-conversation i {\n height: 0.8em;\n width: 80%;\n}\n.preview-conversation i:nth-child(2) {\n align-self: flex-end;\n background: var(--office-teams-brand-subtle);\n}\n.density-options {\n margin: var(--office-space-5) 0 0;\n padding: var(--office-space-5) 0 0;\n border: 0;\n border-top: var(--office-border-width) solid var(--office-teams-divider);\n}\n.density-options legend {\n float: inline-start;\n width: 100%;\n font-weight: var(--office-font-weight-bold);\n margin-bottom: var(--office-space-3);\n}\n.density-choice {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--office-space-3);\n width: 13em;\n padding: var(--office-space-2);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n cursor: pointer;\n font-weight: normal;\n}\n.density-choice input {\n position: absolute;\n inset-inline-end: var(--office-space-2);\n inset-block-end: var(--office-space-2);\n accent-color: var(--office-teams-brand);\n}\n.density-caption {\n display: grid;\n gap: var(--office-space-1);\n padding-inline-end: var(--office-space-5);\n}\n.density-preview {\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: var(--office-space-3);\n height: 7em;\n padding: var(--office-space-3);\n border-radius: var(--office-radius);\n background: var(--office-teams-panel);\n}\n.preview-message {\n display: flex;\n gap: var(--office-space-2);\n align-items: flex-start;\n}\n.preview-message > i {\n width: 1.1em;\n height: 1.1em;\n border-radius: 50%;\n background: var(--office-teams-brand-subtle);\n border: var(--office-border-width) solid var(--office-teams-brand);\n}\n.preview-message > span {\n display: grid;\n gap: var(--office-space-1);\n flex: 1;\n}\n.preview-message b {\n height: 0.3em;\n width: 75%;\n background: var(--office-teams-text-subtle);\n border-radius: var(--office-radius);\n}\n.preview-message b + b {\n width: 100%;\n opacity: 0.4;\n}\n.density-preview[data-density='compact'] {\n gap: var(--office-space-1);\n}\n.density-preview[data-density='compact'] .preview-message > i {\n width: 0.7em;\n height: 0.7em;\n}\n.density-preview[data-density='compact'] .preview-message > span {\n display: flex;\n align-items: center;\n}\n@media (forced-colors: active) {\n .theme-options button[aria-pressed='true'],\n .density-choice:has(input:checked) {\n outline: var(--office-focus-width) solid Highlight;\n }\n}\n";
|
|
2795
|
-
|
|
2796
|
-
|
|
2992
|
+
var THEME_KEY = {
|
|
2993
|
+
system: "settings.themeSystem",
|
|
2994
|
+
light: "settings.themeLight",
|
|
2995
|
+
dark: "settings.themeDark"
|
|
2996
|
+
};
|
|
2997
|
+
function themeChoices(current, change, i18n = teamsI18n()) {
|
|
2998
|
+
return html`<div class="theme-options" role="group" aria-label=${i18n.t("settings.theme")}>
|
|
2797
2999
|
${["system", "light", "dark"].map(
|
|
2798
3000
|
(theme) => html`<button
|
|
2799
3001
|
type="button"
|
|
@@ -2806,9 +3008,7 @@ function themeChoices(current, change) {
|
|
|
2806
3008
|
<span class="preview-sidebar"><i></i><i></i><i></i></span>
|
|
2807
3009
|
<span class="preview-conversation"><i></i><i></i><i></i></span>
|
|
2808
3010
|
</span>
|
|
2809
|
-
<span
|
|
2810
|
-
>${theme === "system" ? "Follow system" : theme === "light" ? "Light" : "Dark"}</span
|
|
2811
|
-
>
|
|
3011
|
+
<span>${i18n.t(THEME_KEY[theme])}</span>
|
|
2812
3012
|
</button>`
|
|
2813
3013
|
)}
|
|
2814
3014
|
</div>`;
|
|
@@ -2828,9 +3028,10 @@ function parseIceLines(text) {
|
|
|
2828
3028
|
var iceToText = (config) => config.iceServers.map(
|
|
2829
3029
|
(server) => [[server.urls].flat().join(","), server.username, server.credential].filter(Boolean).join(" ")
|
|
2830
3030
|
).join("\n");
|
|
2831
|
-
function densityChoices(density, change) {
|
|
3031
|
+
function densityChoices(density, change, i18n = teamsI18n()) {
|
|
3032
|
+
const { t } = i18n;
|
|
2832
3033
|
return html`<fieldset class="density-options">
|
|
2833
|
-
<legend
|
|
3034
|
+
<legend>${t("settings.density")}</legend>
|
|
2834
3035
|
${["comfy", "compact"].map(
|
|
2835
3036
|
(value) => html`<label class="density-choice">
|
|
2836
3037
|
<input
|
|
@@ -2848,9 +3049,9 @@ function densityChoices(density, change) {
|
|
|
2848
3049
|
)}
|
|
2849
3050
|
</span>
|
|
2850
3051
|
<span class="density-caption"
|
|
2851
|
-
><strong>${value === "comfy" ? "
|
|
3052
|
+
><strong>${t(value === "comfy" ? "settings.comfy" : "settings.compact")}</strong>
|
|
2852
3053
|
<small
|
|
2853
|
-
>${value === "comfy" ? "
|
|
3054
|
+
>${t(value === "comfy" ? "settings.comfyText" : "settings.compactText")}</small
|
|
2854
3055
|
></span
|
|
2855
3056
|
>
|
|
2856
3057
|
</label>`
|
|
@@ -2858,20 +3059,21 @@ function densityChoices(density, change) {
|
|
|
2858
3059
|
</fieldset>`;
|
|
2859
3060
|
}
|
|
2860
3061
|
var LEVELS = [
|
|
2861
|
-
["all", "
|
|
2862
|
-
["mentions", "
|
|
2863
|
-
["off", "
|
|
3062
|
+
["all", "settings.levelAll", "settings.levelAllText"],
|
|
3063
|
+
["mentions", "settings.levelMentions", "settings.levelMentionsText"],
|
|
3064
|
+
["off", "settings.levelOff", "settings.levelOffText"]
|
|
2864
3065
|
];
|
|
2865
|
-
var
|
|
2866
|
-
granted: "
|
|
2867
|
-
default: "
|
|
2868
|
-
denied: "
|
|
2869
|
-
unsupported: "
|
|
3066
|
+
var PERMISSION_KEY = {
|
|
3067
|
+
granted: "settings.permissionGranted",
|
|
3068
|
+
default: "settings.permissionDefault",
|
|
3069
|
+
denied: "settings.permissionDenied",
|
|
3070
|
+
unsupported: "settings.permissionUnsupported"
|
|
2870
3071
|
};
|
|
2871
3072
|
var desktopPermission = () => globalThis.Notification?.permission ?? "unsupported";
|
|
2872
|
-
function notificationChoices(settings, permission, handlers) {
|
|
3073
|
+
function notificationChoices(settings, permission, handlers, i18n = teamsI18n()) {
|
|
3074
|
+
const { t } = i18n;
|
|
2873
3075
|
return html`<fieldset class="notification-level">
|
|
2874
|
-
<legend
|
|
3076
|
+
<legend>${t("settings.notifyAbout")}</legend>
|
|
2875
3077
|
${LEVELS.map(
|
|
2876
3078
|
([level, label, description]) => html`<label class="notification-choice">
|
|
2877
3079
|
<input
|
|
@@ -2881,102 +3083,86 @@ function notificationChoices(settings, permission, handlers) {
|
|
|
2881
3083
|
.checked=${settings.level === level}
|
|
2882
3084
|
@change=${() => handlers.change({ level })}
|
|
2883
3085
|
/>
|
|
2884
|
-
<span><strong>${label}</strong><small>${description}</small></span>
|
|
3086
|
+
<span><strong>${t(label)}</strong><small>${t(description)}</small></span>
|
|
2885
3087
|
</label>`
|
|
2886
3088
|
)}
|
|
2887
3089
|
</fieldset>
|
|
2888
|
-
<h3
|
|
3090
|
+
<h3>${t("settings.sound")}</h3>
|
|
2889
3091
|
<label class="preference"
|
|
2890
|
-
><span
|
|
3092
|
+
><span>${t("settings.soundText")}</span
|
|
2891
3093
|
><office-ui-switch
|
|
2892
|
-
aria-label
|
|
3094
|
+
aria-label=${t("settings.soundLabel")}
|
|
2893
3095
|
.checked=${settings.sound}
|
|
2894
3096
|
@change=${(event) => handlers.change({ sound: event.target.checked })}
|
|
2895
3097
|
></office-ui-switch
|
|
2896
3098
|
></label>
|
|
2897
|
-
<h3
|
|
2898
|
-
<p class="description" role="status">${
|
|
3099
|
+
<h3>${t("settings.desktop")}</h3>
|
|
3100
|
+
<p class="description" role="status">${t(PERMISSION_KEY[permission])}</p>
|
|
2899
3101
|
${permission === "default" ? html`<button type="button" class="primary" @click=${handlers.requestPermission}>
|
|
2900
|
-
|
|
3102
|
+
${t("settings.enableDesktop")}
|
|
2901
3103
|
</button>` : ""}
|
|
2902
|
-
<p class="description"
|
|
2903
|
-
Do not disturb silences every notification. Email and mobile push notifications are not
|
|
2904
|
-
available.
|
|
2905
|
-
</p>`;
|
|
3104
|
+
<p class="description">${t("settings.dndNote")}</p>`;
|
|
2906
3105
|
}
|
|
2907
3106
|
var SETTINGS_CATEGORIES = [
|
|
2908
|
-
["general", "
|
|
2909
|
-
["appearance", "
|
|
2910
|
-
["notifications", "
|
|
2911
|
-
["files", "
|
|
2912
|
-
["connection", "
|
|
3107
|
+
["general", "settings.general"],
|
|
3108
|
+
["appearance", "settings.appearance"],
|
|
3109
|
+
["notifications", "settings.notifications"],
|
|
3110
|
+
["files", "settings.files"],
|
|
3111
|
+
["connection", "settings.connection"]
|
|
2913
3112
|
];
|
|
2914
3113
|
var TOPICS = [
|
|
2915
|
-
{ category: "general", title: "
|
|
2916
|
-
{
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
description: "Follow system, light or dark appearance"
|
|
2920
|
-
},
|
|
2921
|
-
{
|
|
2922
|
-
category: "appearance",
|
|
2923
|
-
title: "Chat density",
|
|
2924
|
-
description: "Comfy or compact message spacing"
|
|
2925
|
-
},
|
|
2926
|
-
{
|
|
2927
|
-
category: "appearance",
|
|
2928
|
-
title: "Show app names",
|
|
2929
|
-
description: "Display labels beneath app bar icons"
|
|
2930
|
-
},
|
|
3114
|
+
{ category: "general", title: "settings.profile", description: "settings.topic.profile" },
|
|
3115
|
+
{ category: "appearance", title: "settings.theme", description: "settings.topic.theme" },
|
|
3116
|
+
{ category: "appearance", title: "settings.density", description: "settings.topic.density" },
|
|
3117
|
+
{ category: "appearance", title: "settings.appNames", description: "settings.appNamesText" },
|
|
2931
3118
|
{
|
|
2932
3119
|
category: "notifications",
|
|
2933
|
-
title: "
|
|
2934
|
-
description: "
|
|
3120
|
+
title: "settings.activityNotifications",
|
|
3121
|
+
description: "settings.topic.activityNotifications"
|
|
2935
3122
|
},
|
|
3123
|
+
{ category: "notifications", title: "settings.sound", description: "settings.soundText" },
|
|
2936
3124
|
{
|
|
2937
3125
|
category: "notifications",
|
|
2938
|
-
title: "
|
|
2939
|
-
description: "
|
|
3126
|
+
title: "settings.desktop",
|
|
3127
|
+
description: "settings.topic.desktop"
|
|
2940
3128
|
},
|
|
2941
3129
|
{
|
|
2942
3130
|
category: "notifications",
|
|
2943
|
-
title: "
|
|
2944
|
-
description: "
|
|
2945
|
-
},
|
|
2946
|
-
{
|
|
2947
|
-
category: "notifications",
|
|
2948
|
-
title: "Followed threads",
|
|
2949
|
-
description: "Threads I start and threads I reply to"
|
|
2950
|
-
},
|
|
2951
|
-
{
|
|
2952
|
-
category: "files",
|
|
2953
|
-
title: "File open preference",
|
|
2954
|
-
description: "Open Word, PowerPoint and Excel in OpenTeams or browser"
|
|
3131
|
+
title: "settings.followed",
|
|
3132
|
+
description: "settings.topic.followed"
|
|
2955
3133
|
},
|
|
3134
|
+
{ category: "files", title: "settings.fileOpen", description: "settings.topic.fileOpen" },
|
|
2956
3135
|
{
|
|
2957
3136
|
category: "connection",
|
|
2958
|
-
title: "
|
|
2959
|
-
description: "
|
|
3137
|
+
title: "settings.connection",
|
|
3138
|
+
description: "settings.topic.connection"
|
|
2960
3139
|
}
|
|
2961
3140
|
];
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
const
|
|
2965
|
-
|
|
2966
|
-
|
|
3141
|
+
var categoryLabel = (category, i18n) => i18n.t(SETTINGS_CATEGORIES.find(([id]) => id === category)[1]);
|
|
3142
|
+
function settingsSearch(query, select, i18n = teamsI18n()) {
|
|
3143
|
+
const { t } = i18n;
|
|
3144
|
+
const words = query.trim().toLocaleLowerCase(i18n.locale).split(/\s+/u);
|
|
3145
|
+
const topics = TOPICS.map((topic) => ({
|
|
3146
|
+
category: topic.category,
|
|
3147
|
+
title: t(topic.title),
|
|
3148
|
+
description: t(topic.description)
|
|
3149
|
+
}));
|
|
3150
|
+
const matches = topics.filter((topic) => {
|
|
3151
|
+
const text = `${categoryLabel(topic.category, i18n)} ${topic.title} ${topic.description}`.toLocaleLowerCase(
|
|
3152
|
+
i18n.locale
|
|
3153
|
+
);
|
|
2967
3154
|
return words.every((word) => text.includes(word));
|
|
2968
3155
|
});
|
|
2969
|
-
return html`<section class="settings-results" aria-label
|
|
2970
|
-
<h2
|
|
3156
|
+
return html`<section class="settings-results" aria-label=${t("settings.resultsLabel")}>
|
|
3157
|
+
<h2>${t("settings.results")}</h2>
|
|
2971
3158
|
<p role="status">
|
|
2972
|
-
${matches.length ?
|
|
3159
|
+
${matches.length ? i18n.tn("settings.found", matches.length) : t("settings.noMatch")}
|
|
2973
3160
|
</p>
|
|
2974
3161
|
<ul>
|
|
2975
3162
|
${matches.map(
|
|
2976
3163
|
(topic) => html`<li>
|
|
2977
3164
|
<button type="button" @click=${() => select(topic)}>
|
|
2978
|
-
<strong>${topic.title}</strong
|
|
2979
|
-
><span>${SETTINGS_CATEGORIES.find(([id]) => id === topic.category)[1]}</span
|
|
3165
|
+
<strong>${topic.title}</strong><span>${categoryLabel(topic.category, i18n)}</span
|
|
2980
3166
|
><small>${topic.description}</small>
|
|
2981
3167
|
</button>
|
|
2982
3168
|
</li>`
|
|
@@ -2986,7 +3172,7 @@ function settingsSearch(query, select) {
|
|
|
2986
3172
|
}
|
|
2987
3173
|
|
|
2988
3174
|
// src/teams/app/teams-settings.ts
|
|
2989
|
-
var TeamsSettings = class extends
|
|
3175
|
+
var TeamsSettings = class extends TeamsLitElement {
|
|
2990
3176
|
static styles = [unsafeCSS(teams_settings_default), unsafeCSS(settings_previews_default)];
|
|
2991
3177
|
static properties = {
|
|
2992
3178
|
config: { attribute: false },
|
|
@@ -3079,7 +3265,7 @@ var TeamsSettings = class extends LitElement {
|
|
|
3079
3265
|
const c = this.config;
|
|
3080
3266
|
return html`
|
|
3081
3267
|
<dialog
|
|
3082
|
-
aria-label
|
|
3268
|
+
aria-label=${this.t("settings.title")}
|
|
3083
3269
|
@close=${() => {
|
|
3084
3270
|
if (this.open) this.close();
|
|
3085
3271
|
}}
|
|
@@ -3095,21 +3281,26 @@ var TeamsSettings = class extends LitElement {
|
|
|
3095
3281
|
}}
|
|
3096
3282
|
>
|
|
3097
3283
|
<header>
|
|
3098
|
-
<h1
|
|
3284
|
+
<h1>${this.t("settings.title")}</h1>
|
|
3099
3285
|
<input
|
|
3100
3286
|
type="search"
|
|
3101
|
-
aria-label
|
|
3102
|
-
placeholder
|
|
3287
|
+
aria-label=${this.t("settings.search")}
|
|
3288
|
+
placeholder=${this.t("settings.search")}
|
|
3103
3289
|
.value=${this.query}
|
|
3104
3290
|
@input=${(event) => this.query = event.target.value}
|
|
3105
3291
|
/>
|
|
3106
|
-
<button
|
|
3292
|
+
<button
|
|
3293
|
+
type="button"
|
|
3294
|
+
class="close"
|
|
3295
|
+
aria-label=${this.t("settings.close")}
|
|
3296
|
+
@click=${this.close}
|
|
3297
|
+
>
|
|
3107
3298
|
×
|
|
3108
3299
|
</button>
|
|
3109
3300
|
</header>
|
|
3110
3301
|
<div class="settings-layout">
|
|
3111
3302
|
<nav
|
|
3112
|
-
aria-label
|
|
3303
|
+
aria-label=${this.t("settings.categories")}
|
|
3113
3304
|
role="tablist"
|
|
3114
3305
|
aria-orientation="vertical"
|
|
3115
3306
|
@keydown=${(event) => {
|
|
@@ -3136,40 +3327,45 @@ var TeamsSettings = class extends LitElement {
|
|
|
3136
3327
|
}}
|
|
3137
3328
|
>
|
|
3138
3329
|
${icon({ general: "settings", appearance: "formatPainter", notifications: "message", files: "folder", connection: "screenShare" }[id])}<span
|
|
3139
|
-
>${label}</span
|
|
3330
|
+
>${this.t(label)}</span
|
|
3140
3331
|
>
|
|
3141
3332
|
</button>`
|
|
3142
3333
|
)}
|
|
3143
3334
|
</nav>
|
|
3144
3335
|
<div class="settings-content">
|
|
3145
|
-
${this.query.trim() ? settingsSearch(
|
|
3146
|
-
this.
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3336
|
+
${this.query.trim() ? settingsSearch(
|
|
3337
|
+
this.query,
|
|
3338
|
+
async (topic) => {
|
|
3339
|
+
this.category = topic.category;
|
|
3340
|
+
this.query = "";
|
|
3341
|
+
await this.updateComplete;
|
|
3342
|
+
if (!this.open || this.query.trim() || this.category !== topic.category)
|
|
3343
|
+
return;
|
|
3344
|
+
const panel = this.renderRoot.querySelector(
|
|
3345
|
+
`#panel-${topic.category}`
|
|
3346
|
+
);
|
|
3347
|
+
const heading = [...panel.querySelectorAll("h2, h3, legend")].find(
|
|
3348
|
+
(element) => element.textContent?.trim() === topic.title
|
|
3349
|
+
) ?? panel;
|
|
3350
|
+
heading.tabIndex = -1;
|
|
3351
|
+
heading.focus();
|
|
3352
|
+
},
|
|
3353
|
+
this.i18n
|
|
3354
|
+
) : nothing}
|
|
3159
3355
|
<section
|
|
3160
3356
|
id="panel-general"
|
|
3161
3357
|
role="tabpanel"
|
|
3162
3358
|
aria-labelledby="settings-general"
|
|
3163
3359
|
?hidden=${!!this.query.trim() || this.category !== "general"}
|
|
3164
3360
|
>
|
|
3165
|
-
<h2
|
|
3166
|
-
<h3
|
|
3167
|
-
<p>${this.userName || "
|
|
3168
|
-
<h3
|
|
3169
|
-
<p
|
|
3170
|
-
|
|
3171
|
-
Preferences are saved for this user and workspace on this device.
|
|
3361
|
+
<h2>${this.t("settings.general")}</h2>
|
|
3362
|
+
<h3>${this.t("settings.profile")}</h3>
|
|
3363
|
+
<p>${this.userName || this.t("settings.defaultUser")}</p>
|
|
3364
|
+
<h3>${this.t("settings.workspace")}</h3>
|
|
3365
|
+
<p>
|
|
3366
|
+
${this.t(c.mode === "local" ? "profile.localWorkspace" : "settings.connectedWorkspace")}
|
|
3172
3367
|
</p>
|
|
3368
|
+
<p class="description">${this.t("settings.savedNote")}</p>
|
|
3173
3369
|
</section>
|
|
3174
3370
|
<section
|
|
3175
3371
|
id="panel-appearance"
|
|
@@ -3177,23 +3373,20 @@ var TeamsSettings = class extends LitElement {
|
|
|
3177
3373
|
aria-labelledby="settings-appearance"
|
|
3178
3374
|
?hidden=${!!this.query.trim() || this.category !== "appearance"}
|
|
3179
3375
|
>
|
|
3180
|
-
<h2
|
|
3181
|
-
<h3
|
|
3182
|
-
${themeChoices(this.theme, (theme) => this.dispatchEvent(new CustomEvent("teams-settings-theme", { detail: { theme }, bubbles: true, composed: true })))}
|
|
3183
|
-
${densityChoices(this.chatDensity, (density) => this.dispatchEvent(new CustomEvent("teams-settings-density", { detail: { density }, bubbles: true, composed: true })))}
|
|
3184
|
-
<h3
|
|
3376
|
+
<h2>${this.t("settings.appearance")}</h2>
|
|
3377
|
+
<h3>${this.t("settings.theme")}</h3>
|
|
3378
|
+
${themeChoices(this.theme, (theme) => this.dispatchEvent(new CustomEvent("teams-settings-theme", { detail: { theme }, bubbles: true, composed: true })), this.i18n)}
|
|
3379
|
+
${densityChoices(this.chatDensity, (density) => this.dispatchEvent(new CustomEvent("teams-settings-density", { detail: { density }, bubbles: true, composed: true })), this.i18n)}
|
|
3380
|
+
<h3>${this.t("settings.appNames")}</h3>
|
|
3185
3381
|
<label class="preference"
|
|
3186
|
-
><span
|
|
3382
|
+
><span>${this.t("settings.appNamesText")}</span
|
|
3187
3383
|
><office-ui-switch
|
|
3188
|
-
aria-label
|
|
3384
|
+
aria-label=${this.t("settings.appNames")}
|
|
3189
3385
|
.checked=${this.showAppNames}
|
|
3190
3386
|
@change=${(event) => this.dispatchEvent(new CustomEvent("teams-settings-app-names", { detail: { show: event.target.checked }, bubbles: true, composed: true }))}
|
|
3191
3387
|
></office-ui-switch
|
|
3192
3388
|
></label>
|
|
3193
|
-
<p class="description">
|
|
3194
|
-
Changes apply immediately to this OpenTeams workspace. Keyboard focus and system
|
|
3195
|
-
high-contrast preferences remain available.
|
|
3196
|
-
</p>
|
|
3389
|
+
<p class="description">${this.t("settings.appearanceNote")}</p>
|
|
3197
3390
|
</section>
|
|
3198
3391
|
<section
|
|
3199
3392
|
id="panel-notifications"
|
|
@@ -3201,23 +3394,28 @@ var TeamsSettings = class extends LitElement {
|
|
|
3201
3394
|
aria-labelledby="settings-notifications"
|
|
3202
3395
|
?hidden=${!!this.query.trim() || this.category !== "notifications"}
|
|
3203
3396
|
>
|
|
3204
|
-
<h2
|
|
3205
|
-
<h3
|
|
3206
|
-
${notificationChoices(
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3397
|
+
<h2>${this.t("settings.notifications")}</h2>
|
|
3398
|
+
<h3>${this.t("settings.activityNotifications")}</h3>
|
|
3399
|
+
${notificationChoices(
|
|
3400
|
+
this.notificationSettings,
|
|
3401
|
+
desktopPermission(),
|
|
3402
|
+
{
|
|
3403
|
+
change: (detail) => this.dispatchEvent(
|
|
3404
|
+
new CustomEvent("teams-settings-notifications", {
|
|
3405
|
+
detail,
|
|
3406
|
+
bubbles: true,
|
|
3407
|
+
composed: true
|
|
3408
|
+
})
|
|
3409
|
+
),
|
|
3410
|
+
requestPermission: () => void globalThis.Notification?.requestPermission().then(
|
|
3411
|
+
() => this.requestUpdate()
|
|
3412
|
+
)
|
|
3413
|
+
},
|
|
3414
|
+
this.i18n
|
|
3415
|
+
)}
|
|
3416
|
+
<h3>${this.t("settings.followed")}</h3>
|
|
3417
|
+
<p class="description">${this.t("settings.followedNote")}</p>
|
|
3418
|
+
${["started", "replied"].map((key) => html`<label class="preference"><span>${this.t(key === "started" ? "followed.started" : "followed.replied")}</span><office-ui-switch aria-label=${this.t(key === "started" ? "followed.started" : "followed.replied")} .checked=${this.followSettings[key]} @change=${(event) => this.dispatchEvent(new CustomEvent("teams-settings-follow", { detail: { [key]: event.target.checked }, bubbles: true, composed: true }))}></office-ui-switch></label>`)}
|
|
3221
3419
|
</section>
|
|
3222
3420
|
<section
|
|
3223
3421
|
id="panel-files"
|
|
@@ -3225,24 +3423,20 @@ var TeamsSettings = class extends LitElement {
|
|
|
3225
3423
|
aria-labelledby="settings-files"
|
|
3226
3424
|
?hidden=${!!this.query.trim() || this.category !== "files"}
|
|
3227
3425
|
>
|
|
3228
|
-
<h2
|
|
3229
|
-
<h3
|
|
3426
|
+
<h2>${this.t("settings.files")}</h2>
|
|
3427
|
+
<h3>${this.t("settings.fileOpen")}</h3>
|
|
3230
3428
|
<label
|
|
3231
|
-
|
|
3429
|
+
>${this.t("settings.fileOpenLabel")}
|
|
3232
3430
|
<select
|
|
3233
|
-
aria-label
|
|
3431
|
+
aria-label=${this.t("settings.fileOpenAria")}
|
|
3234
3432
|
.value=${this.fileOpenPreference}
|
|
3235
3433
|
@change=${(event) => this.dispatchEvent(new CustomEvent("teams-settings-file-open", { detail: { preference: event.target.value }, bubbles: true, composed: true }))}
|
|
3236
3434
|
>
|
|
3237
3435
|
<option value="teams">OpenTeams</option>
|
|
3238
|
-
<option value="browser"
|
|
3436
|
+
<option value="browser">${this.t("settings.browser")}</option>
|
|
3239
3437
|
</select></label
|
|
3240
3438
|
>
|
|
3241
|
-
<p class="description">
|
|
3242
|
-
Browser opens the built-in viewer in a separate tab. Hosts can provide their own
|
|
3243
|
-
viewers. Desktop-app defaults and download-location preferences are not available
|
|
3244
|
-
yet.
|
|
3245
|
-
</p>
|
|
3439
|
+
<p class="description">${this.t("settings.fileOpenNote")}</p>
|
|
3246
3440
|
</section>
|
|
3247
3441
|
<form
|
|
3248
3442
|
id="panel-connection"
|
|
@@ -3251,19 +3445,21 @@ var TeamsSettings = class extends LitElement {
|
|
|
3251
3445
|
?hidden=${!!this.query.trim() || this.category !== "connection"}
|
|
3252
3446
|
@submit=${this.apply}
|
|
3253
3447
|
>
|
|
3254
|
-
<h2
|
|
3255
|
-
<p class="description"
|
|
3448
|
+
<h2>${this.t("settings.connection")}</h2>
|
|
3449
|
+
<p class="description">${this.t("settings.connectionNote")}</p>
|
|
3256
3450
|
<label>
|
|
3257
|
-
<span
|
|
3451
|
+
<span>${this.t("settings.mode")}</span>
|
|
3258
3452
|
<select id="mode" .value=${c.mode}>
|
|
3259
3453
|
<option value="local" ?selected=${c.mode === "local"}>
|
|
3260
|
-
|
|
3454
|
+
${this.t("settings.modeLocal")}
|
|
3455
|
+
</option>
|
|
3456
|
+
<option value="server" ?selected=${c.mode === "server"}>
|
|
3457
|
+
${this.t("settings.modeServer")}
|
|
3261
3458
|
</option>
|
|
3262
|
-
<option value="server" ?selected=${c.mode === "server"}>Your server</option>
|
|
3263
3459
|
</select>
|
|
3264
3460
|
</label>
|
|
3265
3461
|
<label>
|
|
3266
|
-
<span
|
|
3462
|
+
<span>${this.t("settings.syncUrl")}</span>
|
|
3267
3463
|
<input
|
|
3268
3464
|
id="sync"
|
|
3269
3465
|
.value=${c.syncUrl ?? ""}
|
|
@@ -3271,10 +3467,10 @@ var TeamsSettings = class extends LitElement {
|
|
|
3271
3467
|
spellcheck="false"
|
|
3272
3468
|
autocomplete="off"
|
|
3273
3469
|
/>
|
|
3274
|
-
<small
|
|
3470
|
+
<small>${this.t("settings.syncHint")}</small>
|
|
3275
3471
|
</label>
|
|
3276
3472
|
<label>
|
|
3277
|
-
<span
|
|
3473
|
+
<span>${this.t("settings.signalUrl")}</span>
|
|
3278
3474
|
<input
|
|
3279
3475
|
id="signal"
|
|
3280
3476
|
.value=${c.signalingUrl ?? ""}
|
|
@@ -3282,35 +3478,35 @@ var TeamsSettings = class extends LitElement {
|
|
|
3282
3478
|
spellcheck="false"
|
|
3283
3479
|
autocomplete="off"
|
|
3284
3480
|
/>
|
|
3285
|
-
<small
|
|
3481
|
+
<small>${this.t("settings.signalHint")}</small>
|
|
3286
3482
|
</label>
|
|
3287
3483
|
<label>
|
|
3288
|
-
<span
|
|
3484
|
+
<span>${this.t("settings.token")}</span>
|
|
3289
3485
|
<input
|
|
3290
3486
|
id="token"
|
|
3291
3487
|
type="password"
|
|
3292
3488
|
.value=${c.token ?? ""}
|
|
3293
|
-
placeholder
|
|
3489
|
+
placeholder=${this.t("settings.tokenPlaceholder")}
|
|
3294
3490
|
autocomplete="off"
|
|
3295
3491
|
/>
|
|
3296
|
-
<small
|
|
3492
|
+
<small>${this.t("settings.tokenHint")}</small>
|
|
3297
3493
|
</label>
|
|
3298
3494
|
<label>
|
|
3299
|
-
<span
|
|
3495
|
+
<span>${this.t("settings.iceServers")}</span>
|
|
3300
3496
|
<textarea
|
|
3301
3497
|
id="ice"
|
|
3302
3498
|
spellcheck="false"
|
|
3303
3499
|
.value=${iceToText(c)}
|
|
3304
3500
|
placeholder="stun:stun.example.org:3478 turn:turn.example.org:3478 user password"
|
|
3305
3501
|
></textarea>
|
|
3306
|
-
<small
|
|
3502
|
+
<small>${this.t("settings.iceHint")}</small>
|
|
3307
3503
|
</label>
|
|
3308
3504
|
<label>
|
|
3309
|
-
<span
|
|
3505
|
+
<span>${this.t("settings.iceTransport")}</span>
|
|
3310
3506
|
<select id="policy" .value=${c.iceTransportPolicy ?? "all"}>
|
|
3311
|
-
<option value="all"
|
|
3507
|
+
<option value="all">${this.t("settings.iceAll")}</option>
|
|
3312
3508
|
<option value="relay" ?selected=${c.iceTransportPolicy === "relay"}>
|
|
3313
|
-
|
|
3509
|
+
${this.t("settings.iceRelay")}
|
|
3314
3510
|
</option>
|
|
3315
3511
|
</select>
|
|
3316
3512
|
</label>
|
|
@@ -3318,8 +3514,8 @@ var TeamsSettings = class extends LitElement {
|
|
|
3318
3514
|
${this.issues.map((i) => html`<li>${i}</li>`)}
|
|
3319
3515
|
</ul>` : nothing}
|
|
3320
3516
|
<div class="actions">
|
|
3321
|
-
<button type="button" @click=${this.close}
|
|
3322
|
-
<button type="submit" class="primary"
|
|
3517
|
+
<button type="button" @click=${this.close}>${this.t("common.cancel")}</button>
|
|
3518
|
+
<button type="submit" class="primary">${this.t("settings.apply")}</button>
|
|
3323
3519
|
</div>
|
|
3324
3520
|
</form>
|
|
3325
3521
|
</div>
|
|
@@ -3373,19 +3569,20 @@ var saveConfig = (config) => safeStorage.setItem("teams:config", JSON.stringify(
|
|
|
3373
3569
|
|
|
3374
3570
|
// raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/teams/app/teams-app.css?raw
|
|
3375
3571
|
var teams_app_default = "/* <teams-app>: the shell. Colours, spacing and radii come from the ooxml-ui tokens, so a host\n retheme or dark mode reaches the whole app. The elements inside bring their own styles. */\n:host {\n display: block;\n height: 100%;\n min-height: 28em;\n font: var(--office-font-size) var(--office-font);\n color: var(--office-foreground);\n background: var(--office-background);\n}\n:host([data-office-theme='dark']) {\n --office-background: var(--office-teams-panel);\n --office-surface: var(--office-teams-bubble);\n --office-popover: var(--office-teams-panel);\n}\n:host([data-chat-density='compact']) {\n --office-teams-message-gap: var(--office-space-1);\n --office-teams-message-padding: var(--office-space-1) var(--office-space-2);\n}\n@media (prefers-color-scheme: dark) {\n :host(:not([data-office-theme='light'])) {\n --office-background: var(--office-teams-panel);\n --office-surface: var(--office-teams-bubble);\n --office-popover: var(--office-teams-panel);\n }\n}\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\nbutton {\n font: inherit;\n color: inherit;\n cursor: pointer;\n}\n:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n\n.shell {\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n height: 100%;\n}\n\n/* ---- top bar ---------------------------------------------------------------------------- */\n.topbar {\n display: grid;\n grid-template-columns: 16em minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--office-space-4);\n padding: var(--office-space-2) var(--office-space-4);\n background: var(--office-teams-rail);\n border-bottom: var(--office-border-width) solid var(--office-teams-divider);\n}\n.brand {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n font-size: var(--office-font-size-lg);\n font-weight: var(--office-font-weight-bold);\n}\n.logo {\n display: inline-grid;\n place-items: center;\n width: 1.8em;\n height: 1.8em;\n border-radius: var(--office-radius-md);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font-size: 0.85em;\n}\n.search {\n position: relative;\n justify-self: center;\n width: min(34em, 100%);\n}\n.search input {\n width: 100%;\n padding: var(--office-space-2) var(--office-space-4);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-full);\n background: var(--office-background);\n color: inherit;\n font: inherit;\n}\n.results {\n position: absolute;\n inset-inline: 0;\n inset-block-start: calc(100% + var(--office-space-1));\n z-index: 5;\n max-height: 22em;\n margin: 0;\n padding: var(--office-space-1);\n overflow: auto;\n list-style: none;\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-popover);\n box-shadow: var(--office-shadow-teams);\n}\n.results button {\n display: grid;\n width: 100%;\n padding: var(--office-space-2) var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius);\n background: transparent;\n text-align: start;\n}\n.results button:hover {\n background: var(--office-selected);\n}\n.results .in,\n.results .none {\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-sm);\n}\n.results .none {\n padding: var(--office-space-3);\n}\n.snippet {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.me {\n display: flex;\n align-items: center;\n gap: var(--office-space-3);\n}\n.me office-ui-menu-button::part(caret) {\n display: none;\n}\n.channel-head office-ui-menu-button::part(caret) {\n display: none;\n}\n.channel-head svg {\n width: 1em;\n height: 1em;\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n/* ---- body ------------------------------------------------------------------------------- */\n.body {\n display: grid;\n grid-template-columns: auto 19em minmax(0, 1fr);\n min-height: 0;\n grid-template-rows: minmax(0, 1fr);\n}\n.body > office-ui-app-rail {\n grid-column: 1;\n grid-row: 1;\n}\n.body > .side {\n grid-column: 2;\n grid-row: 1;\n}\n.body > .main {\n grid-column: 3;\n grid-row: 1;\n}\n.body > teams-settings {\n grid-column: 2 / -1;\n grid-row: 1;\n min-width: 0;\n min-height: 0;\n z-index: 1;\n}\n.body > teams-settings:not([open]) {\n display: none;\n}\n.body > [inert] {\n visibility: hidden;\n}\n.side {\n min-height: 0;\n overflow: auto;\n background: var(--office-teams-panel);\n border-inline-end: var(--office-border-width) solid var(--office-teams-divider);\n}\n.side h2 {\n margin: 0;\n padding: var(--office-space-3) var(--office-space-4);\n font-size: var(--office-font-size-lg);\n}\n.main {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n}\n.popout-view {\n display: flex;\n height: 100%;\n min-height: 0;\n}\n.popout-view teams-content-preview {\n flex: 1;\n}\n.main office-ui-chat-list,\n.main office-ui-prejoin {\n flex: 1;\n}\n\nul.plain {\n margin: 0;\n padding: 0 var(--office-space-3);\n list-style: none;\n}\nul.plain li {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n padding: var(--office-space-2) var(--office-space-2);\n}\nul.plain li > :first-child:not(office-ui-avatar) {\n flex: 1;\n}\n.hint {\n padding: 0 var(--office-space-4);\n color: var(--office-teams-text-subtle);\n}\n.join {\n padding: var(--office-space-1) var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n}\n.join.live {\n border-color: transparent;\n background: var(--office-call-live);\n color: var(--office-call-foreground);\n}\n\n/* ---- conversation ----------------------------------------------------------------------- */\n.channel-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--office-space-4);\n padding: var(--office-space-2) var(--office-space-5);\n border-bottom: var(--office-border-width) solid var(--office-teams-divider);\n}\n.channel-head > button:not(.meet),\n.thread-head button {\n padding: var(--office-space-2) var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n}\n.channel-head > button:hover:not(:disabled),\n.thread-head button:hover {\n background: var(--office-selected);\n}\n.channel-head > button:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.channel-head h1 {\n margin: 0;\n font-size: var(--office-font-size-lg);\n white-space: nowrap;\n}\n.hash {\n color: var(--office-teams-text-subtle);\n}\n.tabs {\n display: flex;\n gap: var(--office-space-1);\n}\n.tabs button {\n padding: var(--office-space-2) var(--office-space-3);\n border: 0;\n border-bottom: var(--office-border-width-thick) solid transparent;\n background: transparent;\n}\n.tabs button[aria-selected='true'] {\n border-bottom-color: var(--office-teams-brand);\n font-weight: var(--office-font-weight-bold);\n}\n.topic {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n color: var(--office-teams-text-subtle);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.people {\n display: flex;\n align-items: center;\n gap: var(--office-space-0);\n}\n.more {\n margin-inline-start: var(--office-space-1);\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-sm);\n}\n.meet {\n padding: var(--office-space-2) var(--office-space-4);\n border: 0;\n border-radius: var(--office-radius-md);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font-weight: var(--office-font-weight-bold);\n}\n.meet:hover:not(:disabled) {\n background: var(--office-teams-brand-hover);\n}\n.meet:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.callbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--office-space-2) var(--office-space-5);\n background: var(--office-call-live);\n color: var(--office-call-foreground);\n}\n.callbar button {\n padding: 0 var(--office-space-3);\n border: var(--office-border-width) solid currentColor;\n border-radius: var(--office-radius);\n background: transparent;\n}\n\n/* ---- files ------------------------------------------------------------------------------ */\n/* ---- meeting ---------------------------------------------------------------------------- */\n.meeting {\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n height: 100%;\n background: var(--office-call-background);\n}\n.stage {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n min-height: 0;\n}\n.panel {\n display: flex;\n flex-direction: column;\n width: 22em;\n min-height: 0;\n background: var(--office-background);\n border-inline-start: var(--office-border-width) solid var(--office-teams-divider);\n}\n.panel office-ui-chat-list {\n flex: 1;\n padding-inline: var(--office-space-3);\n}\n.panel office-ui-chat-composer {\n padding-inline: var(--office-space-3);\n}\n.people-panel h2 {\n margin: 0;\n padding: var(--office-space-3) var(--office-space-4);\n font-size: var(--office-font-size-lg);\n}\n\n/* ---- welcome and toast ------------------------------------------------------------------ */\n.welcome {\n display: grid;\n place-items: center;\n height: 100%;\n background: var(--office-teams-panel);\n}\n.welcome form {\n display: grid;\n justify-items: center;\n gap: var(--office-space-3);\n width: min(24em, 90%);\n padding: var(--office-space-6);\n border-radius: var(--office-radius-lg);\n background: var(--office-background);\n box-shadow: var(--office-shadow-teams);\n}\n.welcome h1 {\n margin: 0;\n font-size: var(--office-font-size-xl);\n}\n.welcome p {\n margin: 0;\n color: var(--office-teams-text-subtle);\n}\n.welcome input {\n width: 100%;\n padding: var(--office-space-3);\n border: var(--office-border-width) solid var(--office-field-border);\n border-radius: var(--office-radius);\n background: var(--office-field-background);\n color: inherit;\n font: inherit;\n}\n.welcome button {\n width: 100%;\n padding: var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius-md);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font-weight: var(--office-font-weight-bold);\n}\n.toast {\n position: fixed;\n inset-block-end: var(--office-space-4);\n inset-inline-start: 50%;\n z-index: 10;\n transform: translateX(-50%);\n padding: var(--office-space-2) var(--office-space-4);\n border-radius: var(--office-radius-md);\n background: var(--office-call-background);\n color: var(--office-call-foreground);\n}\n\n.conversation-grid {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n flex: 1;\n min-height: 0;\n}\n.conversation-grid[data-thread='true'] {\n grid-template-columns: minmax(0, 1fr) minmax(18em, 0.8fr);\n}\n.conversation-main,\n.thread-pane {\n display: flex;\n flex-direction: column;\n min-height: 0;\n min-width: 0;\n}\n.tab-conversation teams-channel-tab {\n flex: 1;\n min-height: 0;\n}\n.thread-pane {\n border-inline-start: var(--office-border-width) solid var(--office-teams-divider);\n}\n.thread-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--office-space-3);\n padding: var(--office-space-3);\n}\n.thread-head h2 {\n margin: 0;\n font-size: 1em;\n}\n.followed-threads {\n overflow: auto;\n padding: var(--office-space-4);\n}\n.message-transfer {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--office-space-3);\n padding: var(--office-space-3);\n background: var(--office-teams-panel);\n border-block-end: var(--office-border-width) solid var(--office-teams-divider);\n}\n.message-transfer span {\n flex: 1;\n overflow-wrap: anywhere;\n}\n.message-transfer button {\n font: inherit;\n color: inherit;\n background: var(--office-background);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n padding: var(--office-space-2) var(--office-space-3);\n cursor: pointer;\n}\n.followed-threads ul {\n list-style: none;\n padding: 0;\n}\n.followed-threads fieldset {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-4);\n padding: var(--office-space-3);\n margin-block: var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n}\n.followed-threads li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--office-space-3);\n padding-block: var(--office-space-3);\n border-block-end: var(--office-border-width) solid var(--office-teams-divider);\n}\n.followed-threads button {\n font: inherit;\n color: inherit;\n background: var(--office-background);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n padding: var(--office-space-2) var(--office-space-3);\n cursor: pointer;\n}\n.followed-threads button:hover {\n background: var(--office-selected);\n}\n.followed-threads li button:first-child {\n display: grid;\n gap: var(--office-space-2);\n flex: 1;\n text-align: start;\n min-width: 0;\n overflow-wrap: anywhere;\n border-color: transparent;\n}\n.followed-threads li[data-unread='true'] button:first-child span {\n font-weight: var(--office-font-weight-bold);\n}\n@media (max-width: 56em) {\n .conversation-grid[data-thread='true'] {\n grid-template-columns: minmax(0, 1fr);\n }\n .conversation-grid[data-thread='true'] .conversation-main {\n display: none;\n }\n}\n.tabs {\n overflow-x: auto;\n min-width: 0;\n flex: 1 1 16em;\n}\n\n.channel-head > .back {\n display: none;\n}\n\n/* ---- compact shell ---------------------------------------------------------------------- */\n/* Below 56em the app rail is a bottom bar, the channel list is its own full-screen view and the\n conversation (or any other content) fills the width with a back button to the list. */\n@media (max-width: 56em) {\n .brand {\n display: none;\n }\n .topbar {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: var(--office-space-2);\n }\n .search {\n width: 100%;\n }\n .channel-head {\n gap: var(--office-space-2);\n padding-inline: var(--office-space-3);\n }\n .channel-head > .back {\n display: inline-flex;\n border-color: transparent;\n }\n .channel-head .topic,\n .channel-head .people {\n display: none;\n }\n .channel-head .tabs {\n flex-basis: 100%;\n order: 1;\n }\n .body {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: minmax(0, 1fr) auto;\n }\n .body > office-ui-app-rail {\n grid-column: 1;\n grid-row: 2;\n }\n .body > .side,\n .body > .main,\n .body > teams-settings {\n grid-column: 1;\n grid-row: 1;\n }\n .side {\n border-inline-end: 0;\n }\n .shell[data-mobile-view='list'] .main,\n .shell[data-mobile-view='content'] .side {\n display: none;\n }\n}\n/* Phone landscape has little height: keep the chrome to one thin row each. */\n@media (max-width: 56em) and (max-height: 30em) {\n .topbar {\n padding-block: var(--office-space-1);\n }\n .channel-head {\n flex-wrap: nowrap;\n padding-block: var(--office-space-1);\n }\n .channel-head .tabs {\n flex: 1 1 0;\n order: 0;\n }\n .channel-head h1 {\n font-size: var(--office-font-size);\n }\n}\n/* Touch: every control in the shell reaches the minimum hit target. */\n@media (pointer: coarse) {\n .channel-head > button,\n .meet,\n .tabs button,\n .join,\n .thread-head button,\n .callbar button {\n min-width: var(--office-touch-target, 44px);\n min-height: var(--office-touch-target, 44px);\n }\n}\n\n/* An application host can own the single suite-level account control. */\n:host([host-profile]) teams-profile-menu {\n display: none;\n}\n\n/* ---- activity ---------------------------------------------------------------------------- */\n.side > office-ui-activity-feed {\n height: 100%;\n}\n/* Toasts for new activity stack at the top right, under the header, so they never cover the\n compose box; on phones they are full-width banners below the header. */\n.activity-toasts {\n position: fixed;\n inset-block-start: 8em;\n inset-inline-end: var(--office-space-4);\n z-index: 10;\n display: flex;\n flex-direction: column;\n gap: var(--office-space-2);\n width: min(28em, calc(100% - var(--office-space-5)));\n pointer-events: none;\n}\n.activity-toast {\n display: flex;\n align-items: center;\n gap: var(--office-space-3);\n padding: var(--office-space-2) var(--office-space-3) var(--office-space-2) var(--office-space-4);\n border-radius: var(--office-radius-md);\n background: var(--office-call-background);\n color: var(--office-call-foreground);\n box-shadow: var(--office-shadow-teams);\n pointer-events: auto;\n}\n@media (max-width: 40em) {\n .activity-toasts {\n inset-block-start: 4.6em;\n inset-inline: var(--office-space-2);\n width: auto;\n }\n}\n.activity-toast .toast-text {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-width: 0;\n}\n.activity-toast .toast-text > * {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.activity-toast .toast-preview {\n opacity: 0.8;\n font-size: var(--office-font-size-sm);\n}\n.activity-toast button {\n flex: none;\n padding: var(--office-space-1) var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius);\n background: transparent;\n color: inherit;\n font-weight: var(--office-font-weight-bold);\n}\n.activity-toast button:hover {\n background: var(--office-selected);\n}\n.activity-toast button svg {\n width: 1em;\n height: 1em;\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n@media (pointer: coarse) {\n .activity-toast button {\n min-width: var(--office-touch-target, 44px);\n min-height: var(--office-touch-target, 44px);\n }\n}\n\n/* ---- chat and calendar ------------------------------------------------------------------ */\n.calendar-back svg,\n.show-calendar svg,\n.group-mark svg,\n.chat-head .chat-people svg {\n width: 1.25em;\n height: 1.25em;\n flex: none;\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.chat-head office-ui-avatar {\n flex: none;\n}\n.group-mark {\n display: grid;\n flex: none;\n place-items: center;\n width: 2.3em;\n height: 2.3em;\n border-radius: var(--office-radius-full);\n background: var(--office-teams-bubble);\n color: var(--office-teams-brand);\n}\n.chat-head .chat-people {\n display: inline-flex;\n align-items: center;\n gap: var(--office-space-2);\n}\n.empty-main {\n display: grid;\n flex: 1;\n place-content: center;\n justify-items: center;\n gap: var(--office-space-3);\n padding: var(--office-space-6);\n color: var(--office-teams-text-subtle);\n text-align: center;\n}\n.empty-main button {\n padding: var(--office-space-2) var(--office-space-4);\n border: 0;\n border-radius: var(--office-radius-md);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font: inherit;\n}\n.main > office-ui-calendar-view {\n flex: 1;\n min-height: 0;\n}\n.calendar-back {\n display: none;\n}\n@media (max-width: 56em) {\n .calendar-back {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n padding: var(--office-space-2) var(--office-space-3);\n border-block-end: var(--office-border-width) solid var(--office-teams-divider);\n }\n .calendar-back button {\n display: inline-flex;\n align-items: center;\n gap: var(--office-space-2);\n min-height: var(--office-touch-target, 44px);\n padding: var(--office-space-2) var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius-md);\n background: transparent;\n }\n .chat-head .chat-people {\n min-width: var(--office-touch-target, 44px);\n }\n}\n.show-calendar {\n display: none;\n}\n@media (max-width: 56em) {\n .show-calendar {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-2);\n width: calc(100% - 2 * var(--office-space-4));\n min-height: var(--office-touch-target, 44px);\n margin: var(--office-space-3) var(--office-space-4);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n }\n}\n";
|
|
3376
|
-
function threadPane(state, client, openFile, close, highlightId = "") {
|
|
3572
|
+
function threadPane(state, client, openFile, close, highlightId = "", i18n = teamsI18n()) {
|
|
3377
3573
|
const thread = state.thread;
|
|
3378
3574
|
if (!thread) return nothing;
|
|
3379
|
-
|
|
3575
|
+
const { t } = i18n;
|
|
3576
|
+
return html`<aside class="thread-pane" aria-label=${t("thread.title")}>
|
|
3380
3577
|
<header class="thread-head">
|
|
3381
|
-
<h2 tabindex="-1" data-thread-heading
|
|
3578
|
+
<h2 tabindex="-1" data-thread-heading>${t("thread.title")}</h2>
|
|
3382
3579
|
<button
|
|
3383
3580
|
type="button"
|
|
3384
3581
|
@click=${() => client.followThread(state.selectedChannelId, thread.root.id, !state.threadFollowed)}
|
|
3385
3582
|
>
|
|
3386
|
-
${state.threadFollowed ? "
|
|
3583
|
+
${t(state.threadFollowed ? "thread.unfollow" : "thread.follow")}
|
|
3387
3584
|
</button>
|
|
3388
|
-
<button type="button" @click=${close}
|
|
3585
|
+
<button type="button" @click=${close}>${t("thread.close")}</button>
|
|
3389
3586
|
</header>
|
|
3390
3587
|
<office-ui-chat-list
|
|
3391
3588
|
.messages=${[thread.root, ...thread.replies]}
|
|
@@ -3397,7 +3594,7 @@ function threadPane(state, client, openFile, close, highlightId = "") {
|
|
|
3397
3594
|
@office-chat-react=${(e) => client.toggleReaction(e.detail.messageId, e.detail.emoji)}
|
|
3398
3595
|
@office-chat-reply=${(e) => client.startReply(e.detail.messageId)}
|
|
3399
3596
|
@office-chat-edit=${(e) => client.startEdit(e.detail.messageId)}
|
|
3400
|
-
@office-chat-delete=${(e) => globalThis.confirm?.("
|
|
3597
|
+
@office-chat-delete=${(e) => globalThis.confirm?.(t("chat.confirmDelete")) !== false && client.deleteMessage(e.detail.messageId)}
|
|
3401
3598
|
@office-chat-open-file=${(e) => openFile(e.detail.attachment)}
|
|
3402
3599
|
></office-ui-chat-list>
|
|
3403
3600
|
<office-ui-chat-composer
|
|
@@ -3409,7 +3606,7 @@ function threadPane(state, client, openFile, close, highlightId = "") {
|
|
|
3409
3606
|
.missingFiles=${state.draft.missingFiles}
|
|
3410
3607
|
.mentionTargets=${state.mentionTargets}
|
|
3411
3608
|
@office-chat-draft=${(e) => client.setDraft(e.detail)}
|
|
3412
|
-
placeholder
|
|
3609
|
+
placeholder=${t("thread.replyPlaceholder")}
|
|
3413
3610
|
@office-chat-typing=${() => client.notifyTyping()}
|
|
3414
3611
|
@office-chat-cancel=${() => client.cancelCompose()}
|
|
3415
3612
|
@office-chat-send=${(e) => {
|
|
@@ -3420,23 +3617,21 @@ function threadPane(state, client, openFile, close, highlightId = "") {
|
|
|
3420
3617
|
></office-ui-chat-composer>
|
|
3421
3618
|
</aside>`;
|
|
3422
3619
|
}
|
|
3423
|
-
function followedThreads(state, client, open, unreadOnly, filter) {
|
|
3620
|
+
function followedThreads(state, client, open, unreadOnly, filter, i18n = teamsI18n()) {
|
|
3621
|
+
const { t, tn } = i18n;
|
|
3424
3622
|
const threads = state.followedThreads.filter((thread) => !unreadOnly || thread.unread > 0);
|
|
3425
|
-
return html`<section class="followed-threads" aria-label
|
|
3426
|
-
<h1
|
|
3427
|
-
<p>
|
|
3428
|
-
Threads you follow on this device. Their replies appear in Activity and notify you according
|
|
3429
|
-
to your notification settings.
|
|
3430
|
-
</p>
|
|
3623
|
+
return html`<section class="followed-threads" aria-label=${t("followed.title")}>
|
|
3624
|
+
<h1>${t("followed.title")}</h1>
|
|
3625
|
+
<p>${t("followed.intro")}</p>
|
|
3431
3626
|
<fieldset>
|
|
3432
|
-
<legend
|
|
3627
|
+
<legend>${t("followed.autoFollow")}</legend>
|
|
3433
3628
|
<label
|
|
3434
3629
|
><input
|
|
3435
3630
|
type="checkbox"
|
|
3436
3631
|
.checked=${state.threadFollowSettings.started}
|
|
3437
3632
|
@change=${(event) => client.setThreadFollowSettings({ started: event.target.checked })}
|
|
3438
3633
|
/>
|
|
3439
|
-
|
|
3634
|
+
${t("followed.started")}</label
|
|
3440
3635
|
>
|
|
3441
3636
|
<label
|
|
3442
3637
|
><input
|
|
@@ -3444,7 +3639,7 @@ function followedThreads(state, client, open, unreadOnly, filter) {
|
|
|
3444
3639
|
.checked=${state.threadFollowSettings.replied}
|
|
3445
3640
|
@change=${(event) => client.setThreadFollowSettings({ replied: event.target.checked })}
|
|
3446
3641
|
/>
|
|
3447
|
-
|
|
3642
|
+
${t("followed.replied")}</label
|
|
3448
3643
|
>
|
|
3449
3644
|
</fieldset>
|
|
3450
3645
|
<label
|
|
@@ -3453,7 +3648,7 @@ function followedThreads(state, client, open, unreadOnly, filter) {
|
|
|
3453
3648
|
.checked=${unreadOnly}
|
|
3454
3649
|
@change=${(event) => filter(event.target.checked)}
|
|
3455
3650
|
/>
|
|
3456
|
-
|
|
3651
|
+
${t("followed.unreadOnly")}</label
|
|
3457
3652
|
>
|
|
3458
3653
|
<ul>
|
|
3459
3654
|
${threads.length ? threads.map(
|
|
@@ -3461,64 +3656,72 @@ function followedThreads(state, client, open, unreadOnly, filter) {
|
|
|
3461
3656
|
<button
|
|
3462
3657
|
type="button"
|
|
3463
3658
|
@click=${() => open(thread)}
|
|
3464
|
-
aria-label=${
|
|
3659
|
+
aria-label=${t("followed.open", {
|
|
3660
|
+
channel: thread.channelName,
|
|
3661
|
+
text: thread.root.deleted ? t("followed.deletedMessage") : thread.root.text
|
|
3662
|
+
})}
|
|
3465
3663
|
>
|
|
3466
3664
|
<strong># ${thread.channelName}</strong
|
|
3467
3665
|
><span
|
|
3468
|
-
>${thread.root.deleted ? "
|
|
3666
|
+
>${thread.root.deleted ? t("chat.deleted") : thread.root.text || t("followed.sharedFile")}</span
|
|
3469
3667
|
>
|
|
3470
3668
|
<small
|
|
3471
|
-
>${
|
|
3472
|
-
${new Date(thread.updatedAt).toLocaleString()}</small
|
|
3669
|
+
>${tn("chat.replies", thread.replyCount)} ·
|
|
3670
|
+
${new Date(thread.updatedAt).toLocaleString(i18n.intl)}</small
|
|
3473
3671
|
></button
|
|
3474
|
-
><span
|
|
3672
|
+
><span
|
|
3673
|
+
>${thread.unread > 0 ? t("followed.unreadCount", { count: thread.unread }) : t("followed.read")}</span
|
|
3475
3674
|
><button
|
|
3476
3675
|
type="button"
|
|
3477
3676
|
@click=${() => client.markThreadRead(thread.channelId, thread.root.id, thread.unread > 0)}
|
|
3478
3677
|
>
|
|
3479
|
-
${thread.unread > 0 ? "
|
|
3678
|
+
${t(thread.unread > 0 ? "activity.markRead" : "activity.markUnread")}</button
|
|
3480
3679
|
><button
|
|
3481
3680
|
type="button"
|
|
3482
3681
|
@click=${() => client.followThread(thread.channelId, thread.root.id, false)}
|
|
3483
3682
|
>
|
|
3484
|
-
|
|
3683
|
+
${t("thread.unfollow")}
|
|
3485
3684
|
</button>
|
|
3486
3685
|
</li>`
|
|
3487
|
-
) : html`<li
|
|
3488
|
-
${unreadOnly ? "No unread followed threads." : "No followed threads yet. Open a thread and choose Follow thread."}
|
|
3489
|
-
</li>`}
|
|
3686
|
+
) : html`<li>${t(unreadOnly ? "followed.noneUnread" : "followed.none")}</li>`}
|
|
3490
3687
|
</ul>
|
|
3491
3688
|
</section>`;
|
|
3492
3689
|
}
|
|
3493
|
-
function draftList(state, client, open) {
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
<
|
|
3690
|
+
function draftList(state, client, open, i18n = teamsI18n()) {
|
|
3691
|
+
const { t, tn } = i18n;
|
|
3692
|
+
return html`<section class="followed-threads" aria-label=${t("drafts.title")}>
|
|
3693
|
+
<h1>${t("drafts.title")}</h1>
|
|
3694
|
+
<p>${t("drafts.intro")}</p>
|
|
3497
3695
|
<ul>
|
|
3498
3696
|
${state.drafts.length ? state.drafts.map((draft) => {
|
|
3499
3697
|
const channel = state.channels.find((item) => item.id === draft.context.channelId);
|
|
3698
|
+
const body = draft.text || t("drafts.attachments");
|
|
3500
3699
|
return html`<li>
|
|
3501
3700
|
<button
|
|
3502
3701
|
type="button"
|
|
3503
|
-
aria-label=${
|
|
3702
|
+
aria-label=${t("drafts.resume", {
|
|
3703
|
+
channel: channel.name,
|
|
3704
|
+
text: draft.text.slice(0, 80) || t("drafts.attachments")
|
|
3705
|
+
})}
|
|
3504
3706
|
@click=${() => open(draft.context)}
|
|
3505
3707
|
>
|
|
3506
|
-
<strong># ${channel.name}</strong><span>${
|
|
3708
|
+
<strong># ${channel.name}</strong><span>${body}</span
|
|
3507
3709
|
><small
|
|
3508
|
-
>${draft.context.editId ? "
|
|
3509
|
-
·
|
|
3710
|
+
>${draft.context.editId ? t("drafts.edit") : draft.context.threadId ? t("drafts.threadReply") : t("drafts.newPost")}
|
|
3711
|
+
·
|
|
3712
|
+
${tn("drafts.attachmentCount", draft.files.length + draft.missingFiles.length)}</small
|
|
3510
3713
|
></button
|
|
3511
3714
|
><button
|
|
3512
3715
|
type="button"
|
|
3513
3716
|
@click=${() => {
|
|
3514
|
-
if (globalThis.confirm?.("
|
|
3717
|
+
if (globalThis.confirm?.(t("drafts.confirmDiscard")) !== false)
|
|
3515
3718
|
client.discardDraft(draft.context);
|
|
3516
3719
|
}}
|
|
3517
3720
|
>
|
|
3518
|
-
|
|
3721
|
+
${t("drafts.discard")}
|
|
3519
3722
|
</button>
|
|
3520
3723
|
</li>`;
|
|
3521
|
-
}) : html`<li
|
|
3724
|
+
}) : html`<li>${t("drafts.none")}</li>`}
|
|
3522
3725
|
</ul>
|
|
3523
3726
|
</section>`;
|
|
3524
3727
|
}
|
|
@@ -3545,43 +3748,76 @@ function filePopoutDetail(pageUrl) {
|
|
|
3545
3748
|
return null;
|
|
3546
3749
|
}
|
|
3547
3750
|
}
|
|
3548
|
-
function messageTransfers(state, client) {
|
|
3751
|
+
function messageTransfers(state, client, i18n = teamsI18n()) {
|
|
3752
|
+
const { t } = i18n;
|
|
3549
3753
|
return state.messageTransfers.filter((transfer) => transfer.context.channelId === state.selectedChannelId).map(
|
|
3550
3754
|
(transfer) => html`<div class="message-transfer" role="status">
|
|
3551
3755
|
<span
|
|
3552
|
-
>${
|
|
3756
|
+
>${t("transfer.status", {
|
|
3757
|
+
kind: t(
|
|
3758
|
+
transfer.context.threadId || transfer.context.replyTo ? "transfer.threadReply" : "transfer.channelPost"
|
|
3759
|
+
),
|
|
3760
|
+
file: transfer.progress.fileName,
|
|
3761
|
+
completed: transfer.progress.completed,
|
|
3762
|
+
total: transfer.progress.total
|
|
3763
|
+
})}</span
|
|
3553
3764
|
><progress
|
|
3554
|
-
aria-label
|
|
3765
|
+
aria-label=${t("transfer.progress")}
|
|
3555
3766
|
max=${transfer.progress.total}
|
|
3556
3767
|
value=${transfer.progress.completed}
|
|
3557
3768
|
></progress
|
|
3558
3769
|
><button type="button" @click=${() => client.cancelSend(transfer.id)}>
|
|
3559
|
-
|
|
3770
|
+
${t("transfer.cancel")}
|
|
3560
3771
|
</button>
|
|
3561
3772
|
</div>`
|
|
3562
3773
|
);
|
|
3563
3774
|
}
|
|
3564
3775
|
|
|
3565
3776
|
// raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/teams/app/profile-menu.css?raw
|
|
3566
|
-
var profile_menu_default = ":host {\n display: inline-flex;\n font: inherit;\n color: inherit;\n}\n.profile {\n display: inline-flex;\n align-items: center;\n padding: var(--office-space-1);\n border: 0;\n border-radius: var(--office-radius-full);\n background: transparent;\n cursor: pointer;\n}\n.profile:hover {\n background: var(--office-selected);\n}\n[popover] {\n min-width: 20em;\n max-width: 90vw;\n max-height: min(80vh, 40em);\n overflow: auto;\n padding: var(--office-space-4);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-popover);\n color: var(--office-foreground);\n box-shadow: var(--office-shadow-teams);\n}\n.identity {\n display: flex;\n gap: var(--office-space-3);\n align-items: center;\n margin-bottom: var(--office-space-4);\n}\n.identity strong {\n overflow-wrap: anywhere;\n}\nlabel {\n display: grid;\n gap: var(--office-space-2);\n margin-bottom: var(--office-space-3);\n}\n.who {\n display: grid;\n min-width: 0;\n}\n.status-line,\n.message,\n.hint {\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-sm);\n overflow-wrap: anywhere;\n}\n.hint:empty {\n display: none;\n}\n.actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-2);\n margin-bottom: var(--office-space-3);\n}\n.actions button {\n padding: var(--office-space-2) var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n.actions button:hover:not(:disabled) {\n background: var(--office-selected);\n}\n.actions button:disabled {\n opacity: 0.5;\n cursor: default;\n}\n@media (pointer: coarse) {\n .actions button,\n select,\n input {\n min-height: var(--office-touch-target, 44px);\n }\n}\ninput,\nselect {\n font: inherit;\n padding: var(--office-space-2);\n color: inherit;\n border: var(--office-border-width) solid var(--office-field-border);\n border-radius: var(--office-radius);\n background: var(--office-field-background);\n}\nselect:disabled {\n opacity: 0.6;\n}\n.connection {\n color: var(--office-teams-text-subtle);\n margin-bottom: 0;\n font-size: var(--office-font-size-sm);\n}\n:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n";
|
|
3777
|
+
var profile_menu_default = ":host {\n display: inline-flex;\n font: inherit;\n color: inherit;\n}\n.profile {\n display: inline-flex;\n align-items: center;\n padding: var(--office-space-1);\n border: 0;\n border-radius: var(--office-radius-full);\n background: transparent;\n cursor: pointer;\n}\n.profile:hover {\n background: var(--office-selected);\n}\n[popover] {\n min-width: 20em;\n max-width: 90vw;\n max-height: min(80vh, 40em);\n overflow: auto;\n padding: var(--office-space-4);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-popover);\n color: var(--office-foreground);\n box-shadow: var(--office-shadow-teams);\n}\n.identity {\n display: flex;\n gap: var(--office-space-3);\n align-items: center;\n margin-bottom: var(--office-space-4);\n}\n.identity strong {\n overflow-wrap: anywhere;\n}\nlabel {\n display: grid;\n gap: var(--office-space-2);\n margin-bottom: var(--office-space-3);\n}\n.who {\n display: grid;\n min-width: 0;\n}\n.status-line,\n.message,\n.hint {\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-sm);\n overflow-wrap: anywhere;\n}\n.hint:empty {\n display: none;\n}\n.actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-2);\n margin-bottom: var(--office-space-3);\n}\n.actions button,\n.account button {\n padding: var(--office-space-2) var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n.actions button:hover:not(:disabled),\n.account button:hover {\n background: var(--office-selected);\n}\n.actions button:disabled {\n opacity: 0.5;\n cursor: default;\n}\n@media (pointer: coarse) {\n .actions button,\n .account button,\n select,\n input {\n min-height: var(--office-touch-target, 44px);\n }\n}\n.account {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--office-space-2);\n margin-bottom: var(--office-space-3);\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-sm);\n overflow-wrap: anywhere;\n}\ninput,\nselect {\n font: inherit;\n padding: var(--office-space-2);\n color: inherit;\n border: var(--office-border-width) solid var(--office-field-border);\n border-radius: var(--office-radius);\n background: var(--office-field-background);\n}\nselect:disabled {\n opacity: 0.6;\n}\n.connection {\n color: var(--office-teams-text-subtle);\n margin-bottom: 0;\n font-size: var(--office-font-size-sm);\n}\n:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n";
|
|
3567
3778
|
|
|
3568
3779
|
// src/teams/app/profile-menu.ts
|
|
3569
|
-
var
|
|
3570
|
-
|
|
3780
|
+
var STATUS_KEY = {
|
|
3781
|
+
available: "status.available",
|
|
3782
|
+
busy: "status.busy",
|
|
3783
|
+
dnd: "status.dnd",
|
|
3784
|
+
brb: "status.brb",
|
|
3785
|
+
away: "status.away",
|
|
3786
|
+
offline: "status.offline"
|
|
3787
|
+
};
|
|
3788
|
+
var CONNECTION_KEY = {
|
|
3789
|
+
connecting: "connection.connecting",
|
|
3790
|
+
connected: "connection.connected",
|
|
3791
|
+
disconnected: "connection.disconnected",
|
|
3792
|
+
error: "connection.error"
|
|
3793
|
+
};
|
|
3794
|
+
var DURATION_KEY = {
|
|
3795
|
+
never: "duration.never",
|
|
3796
|
+
"30m": "duration.30m",
|
|
3797
|
+
"1h": "duration.1h",
|
|
3798
|
+
"2h": "duration.2h",
|
|
3799
|
+
today: "duration.today",
|
|
3800
|
+
week: "duration.week"
|
|
3801
|
+
};
|
|
3802
|
+
function untilLabel(at, i18n = teamsI18n()) {
|
|
3571
3803
|
if (at === null) return "";
|
|
3804
|
+
const { t, intl } = i18n;
|
|
3572
3805
|
const d = new Date(at);
|
|
3573
3806
|
const today = (/* @__PURE__ */ new Date()).toDateString();
|
|
3574
3807
|
if (d.getHours() === 0 && d.getMinutes() === 0) {
|
|
3575
3808
|
const lastDay = new Date(at - 1);
|
|
3576
|
-
return lastDay.toDateString() === today ? "
|
|
3809
|
+
return lastDay.toDateString() === today ? t("profile.untilEndToday") : t("profile.untilEndDay", {
|
|
3810
|
+
day: lastDay.toLocaleDateString(intl, { weekday: "long" })
|
|
3811
|
+
});
|
|
3577
3812
|
}
|
|
3578
|
-
const time = d.toLocaleTimeString(
|
|
3579
|
-
return d.toDateString() === today ?
|
|
3580
|
-
}
|
|
3581
|
-
var TeamsProfileMenu = class extends
|
|
3813
|
+
const time = d.toLocaleTimeString(intl, { hour: "numeric", minute: "2-digit" });
|
|
3814
|
+
return d.toDateString() === today ? t("profile.until", { time }) : t("profile.untilDayTime", { day: d.toLocaleDateString(intl, { weekday: "long" }), time });
|
|
3815
|
+
}
|
|
3816
|
+
var TeamsProfileMenu = class extends TeamsLitElement {
|
|
3582
3817
|
static styles = unsafeCSS(profile_menu_default);
|
|
3583
3818
|
static properties = {
|
|
3584
3819
|
state: { attribute: false },
|
|
3820
|
+
account: { type: String },
|
|
3585
3821
|
open: { state: true },
|
|
3586
3822
|
draft: { state: true },
|
|
3587
3823
|
resetAfter: { state: true },
|
|
@@ -3590,6 +3826,7 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3590
3826
|
constructor() {
|
|
3591
3827
|
super();
|
|
3592
3828
|
this.state = null;
|
|
3829
|
+
this.account = "";
|
|
3593
3830
|
this.open = false;
|
|
3594
3831
|
this.draft = null;
|
|
3595
3832
|
this.resetAfter = "never";
|
|
@@ -3618,10 +3855,13 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3618
3855
|
durationOptions(selected) {
|
|
3619
3856
|
return STATUS_DURATIONS.map(
|
|
3620
3857
|
(value) => html`<option value=${value} ?selected=${selected === value}>
|
|
3621
|
-
${
|
|
3858
|
+
${this.t(DURATION_KEY[value])}
|
|
3622
3859
|
</option>`
|
|
3623
3860
|
);
|
|
3624
3861
|
}
|
|
3862
|
+
idleLabel(minutes) {
|
|
3863
|
+
return minutes === 0 ? this.t("duration.never") : this.tn("profile.idleMinutes", minutes);
|
|
3864
|
+
}
|
|
3625
3865
|
render() {
|
|
3626
3866
|
const state = this.state;
|
|
3627
3867
|
if (!state) return nothing;
|
|
@@ -3629,7 +3869,7 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3629
3869
|
return html`<button
|
|
3630
3870
|
type="button"
|
|
3631
3871
|
class="profile"
|
|
3632
|
-
aria-label=${
|
|
3872
|
+
aria-label=${this.t("profile.for", { name: state.user.name })}
|
|
3633
3873
|
aria-expanded=${String(this.open)}
|
|
3634
3874
|
aria-haspopup="dialog"
|
|
3635
3875
|
aria-controls="profile"
|
|
@@ -3645,7 +3885,7 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3645
3885
|
id="profile"
|
|
3646
3886
|
popover="auto"
|
|
3647
3887
|
role="dialog"
|
|
3648
|
-
aria-label
|
|
3888
|
+
aria-label=${this.t("profile.yours")}
|
|
3649
3889
|
@keydown=${(event) => {
|
|
3650
3890
|
if (event.key !== "Escape") return;
|
|
3651
3891
|
event.preventDefault();
|
|
@@ -3669,13 +3909,13 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3669
3909
|
<div class="who">
|
|
3670
3910
|
<strong>${state.user.name}</strong>
|
|
3671
3911
|
<span class="status-line"
|
|
3672
|
-
>${
|
|
3912
|
+
>${this.t(STATUS_KEY[state.availability])}${state.presence.idle && state.presence.status === "available" ? ` ${this.t("profile.idle")}` : ""}</span
|
|
3673
3913
|
>
|
|
3674
3914
|
${presence.message ? html`<span class="message">${presence.message}</span>` : nothing}
|
|
3675
3915
|
</div>
|
|
3676
3916
|
</div>
|
|
3677
3917
|
<label
|
|
3678
|
-
|
|
3918
|
+
>${this.t("profile.availability")}<select
|
|
3679
3919
|
.value=${presence.status}
|
|
3680
3920
|
@change=${(event) => {
|
|
3681
3921
|
const availability = event.target.value;
|
|
@@ -3683,11 +3923,11 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3683
3923
|
this.fire("teams-profile-status", { availability, duration: this.resetAfter });
|
|
3684
3924
|
}}
|
|
3685
3925
|
>
|
|
3686
|
-
${PRESENCE_STATUSES.map((value) => html`<option value=${value} ?selected=${presence.status === value}>${
|
|
3926
|
+
${PRESENCE_STATUSES.map((value) => html`<option value=${value} ?selected=${presence.status === value}>${this.t(STATUS_KEY[value])}</option>`)}
|
|
3687
3927
|
</select></label
|
|
3688
3928
|
>
|
|
3689
3929
|
<label
|
|
3690
|
-
|
|
3930
|
+
>${this.t("profile.resetAfter")}<select
|
|
3691
3931
|
name="status-duration"
|
|
3692
3932
|
@change=${(event) => {
|
|
3693
3933
|
const duration = event.target.value;
|
|
@@ -3698,14 +3938,14 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3698
3938
|
>
|
|
3699
3939
|
${this.durationOptions(this.resetAfter)}
|
|
3700
3940
|
</select>
|
|
3701
|
-
<span class="hint">${untilLabel(presence.statusExpiresAt)}</span></label
|
|
3941
|
+
<span class="hint">${untilLabel(presence.statusExpiresAt, this.i18n)}</span></label
|
|
3702
3942
|
>
|
|
3703
3943
|
<label
|
|
3704
|
-
|
|
3944
|
+
>${this.t("profile.statusMessage")}<input
|
|
3705
3945
|
type="text"
|
|
3706
3946
|
name="message"
|
|
3707
3947
|
maxlength=${MAX_STATUS_MESSAGE_CHARS}
|
|
3708
|
-
placeholder
|
|
3948
|
+
placeholder=${this.t("profile.messagePlaceholder")}
|
|
3709
3949
|
.value=${this.draft ?? presence.message}
|
|
3710
3950
|
@input=${(event) => this.draft = event.target.value}
|
|
3711
3951
|
@keydown=${(event) => {
|
|
@@ -3714,10 +3954,10 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3714
3954
|
this.saveMessage();
|
|
3715
3955
|
}}
|
|
3716
3956
|
/>
|
|
3717
|
-
<span class="hint">${untilLabel(presence.messageExpiresAt)}</span></label
|
|
3957
|
+
<span class="hint">${untilLabel(presence.messageExpiresAt, this.i18n)}</span></label
|
|
3718
3958
|
>
|
|
3719
3959
|
<label
|
|
3720
|
-
|
|
3960
|
+
>${this.t("profile.clearAfter")}<select
|
|
3721
3961
|
name="message-duration"
|
|
3722
3962
|
@change=${(event) => {
|
|
3723
3963
|
const duration = event.target.value;
|
|
@@ -3728,7 +3968,7 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3728
3968
|
</select></label
|
|
3729
3969
|
>
|
|
3730
3970
|
<div class="actions">
|
|
3731
|
-
<button type="button" @click=${this.saveMessage}
|
|
3971
|
+
<button type="button" @click=${this.saveMessage}>${this.t("profile.saveMessage")}</button>
|
|
3732
3972
|
<button
|
|
3733
3973
|
type="button"
|
|
3734
3974
|
?disabled=${!presence.message && !this.draft}
|
|
@@ -3737,11 +3977,11 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3737
3977
|
this.saveMessage();
|
|
3738
3978
|
}}
|
|
3739
3979
|
>
|
|
3740
|
-
|
|
3980
|
+
${this.t("profile.clearMessage")}
|
|
3741
3981
|
</button>
|
|
3742
3982
|
</div>
|
|
3743
3983
|
<label
|
|
3744
|
-
|
|
3984
|
+
>${this.t("profile.awayAfter")}<select
|
|
3745
3985
|
name="idle"
|
|
3746
3986
|
@change=${(event) => {
|
|
3747
3987
|
const minutes = Number(event.target.value);
|
|
@@ -3749,11 +3989,22 @@ var TeamsProfileMenu = class extends LitElement {
|
|
|
3749
3989
|
this.fire("teams-profile-idle", { minutes });
|
|
3750
3990
|
}}
|
|
3751
3991
|
>
|
|
3752
|
-
${IDLE_MINUTE_CHOICES.map((minutes) => html`<option value=${minutes} ?selected=${presence.idleMinutes === minutes}>${idleLabel(minutes)}</option>`)}
|
|
3992
|
+
${IDLE_MINUTE_CHOICES.map((minutes) => html`<option value=${minutes} ?selected=${presence.idleMinutes === minutes}>${this.idleLabel(minutes)}</option>`)}
|
|
3753
3993
|
</select></label
|
|
3754
3994
|
>
|
|
3995
|
+
${this.account ? html`<div class="account">
|
|
3996
|
+
<span>${this.t("signIn.signedInAs", { id: this.account })}</span>
|
|
3997
|
+
<button
|
|
3998
|
+
type="button"
|
|
3999
|
+
name="sign-out"
|
|
4000
|
+
@click=${() => this.fire("teams-sign-out", {})}
|
|
4001
|
+
>
|
|
4002
|
+
${this.t("signIn.signOut")}
|
|
4003
|
+
</button>
|
|
4004
|
+
</div>` : nothing}
|
|
3755
4005
|
<p class="connection">
|
|
3756
|
-
${state.mode === "local" ? "
|
|
4006
|
+
${this.t(state.mode === "local" ? "profile.localWorkspace" : "profile.workspaceServer")}:
|
|
4007
|
+
${this.t(CONNECTION_KEY[state.status])}
|
|
3757
4008
|
</p>
|
|
3758
4009
|
</div>`;
|
|
3759
4010
|
}
|
|
@@ -3763,17 +4014,302 @@ function defineTeamsProfileMenu() {
|
|
|
3763
4014
|
customElements.define("teams-profile-menu", TeamsProfileMenu);
|
|
3764
4015
|
}
|
|
3765
4016
|
|
|
4017
|
+
// src/teams/app/sign-in-strings.ts
|
|
4018
|
+
function signInErrorText(reason, retryAfterSec, i18n = teamsI18n()) {
|
|
4019
|
+
switch (reason) {
|
|
4020
|
+
case "credentials":
|
|
4021
|
+
return i18n.t("signIn.error.credentials");
|
|
4022
|
+
case "rate-limited":
|
|
4023
|
+
return retryAfterSec ? i18n.t("signIn.error.rateLimited", { seconds: retryAfterSec }) : i18n.t("signIn.error.rateLimitedMinute");
|
|
4024
|
+
case "network":
|
|
4025
|
+
return i18n.t("signIn.error.network");
|
|
4026
|
+
default:
|
|
4027
|
+
return i18n.t("signIn.error.server");
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
|
|
4031
|
+
// src/teams/app/sign-in-flow.ts
|
|
4032
|
+
var PROBE_AFTER_MS = 4e3;
|
|
4033
|
+
var PROBE_AGAIN_MS = 15e3;
|
|
4034
|
+
var MAX_TIMER_MS = 2 ** 31 - 1;
|
|
4035
|
+
var SignInFlow = class {
|
|
4036
|
+
constructor(host) {
|
|
4037
|
+
this.host = host;
|
|
4038
|
+
}
|
|
4039
|
+
host;
|
|
4040
|
+
phase = "open";
|
|
4041
|
+
session = null;
|
|
4042
|
+
/** Kept across a re-prompt so the person only retypes the password. */
|
|
4043
|
+
userId = "";
|
|
4044
|
+
notice = "";
|
|
4045
|
+
error = "";
|
|
4046
|
+
busy = false;
|
|
4047
|
+
retryAfterSec = 0;
|
|
4048
|
+
accounts = /* @__PURE__ */ new Map();
|
|
4049
|
+
probing = "";
|
|
4050
|
+
expiryTimer;
|
|
4051
|
+
checkTimer;
|
|
4052
|
+
checking = false;
|
|
4053
|
+
generation = 0;
|
|
4054
|
+
i18n() {
|
|
4055
|
+
return this.host.i18n?.() ?? teamsI18n();
|
|
4056
|
+
}
|
|
4057
|
+
key(config) {
|
|
4058
|
+
return `${serverOrigin(config) ?? ""}|${config.token ?? ""}`;
|
|
4059
|
+
}
|
|
4060
|
+
/**
|
|
4061
|
+
* Whether the client must wait: true while the server is being asked and while the sign-in
|
|
4062
|
+
* screen is showing. Call it from every (re)start with the settings-derived config.
|
|
4063
|
+
*/
|
|
4064
|
+
gate(config) {
|
|
4065
|
+
if (config.mode !== "server" || config.sessionToken || !serverOrigin(config)) {
|
|
4066
|
+
this.phase = "open";
|
|
4067
|
+
return false;
|
|
4068
|
+
}
|
|
4069
|
+
if (this.session) {
|
|
4070
|
+
this.phase = "open";
|
|
4071
|
+
return false;
|
|
4072
|
+
}
|
|
4073
|
+
const key = this.key(config);
|
|
4074
|
+
const known = this.accounts.get(key);
|
|
4075
|
+
if (known === false) {
|
|
4076
|
+
this.phase = "open";
|
|
4077
|
+
return false;
|
|
4078
|
+
}
|
|
4079
|
+
if (known === true) {
|
|
4080
|
+
this.phase = "required";
|
|
4081
|
+
return true;
|
|
4082
|
+
}
|
|
4083
|
+
this.phase = "checking";
|
|
4084
|
+
if (this.probing !== key) {
|
|
4085
|
+
this.probing = key;
|
|
4086
|
+
const generation = this.generation;
|
|
4087
|
+
void probeTeamsAccounts(config).then((accounts) => {
|
|
4088
|
+
if (generation !== this.generation || this.probing !== key) return;
|
|
4089
|
+
this.probing = "";
|
|
4090
|
+
if (accounts !== null) this.accounts.set(key, accounts);
|
|
4091
|
+
this.phase = accounts ? "required" : "open";
|
|
4092
|
+
this.host.changed();
|
|
4093
|
+
});
|
|
4094
|
+
}
|
|
4095
|
+
return true;
|
|
4096
|
+
}
|
|
4097
|
+
/** The config to start the client with: the session, when there is one, rides along. */
|
|
4098
|
+
apply(config) {
|
|
4099
|
+
return this.session && !config.sessionToken ? { ...config, sessionToken: this.session.token } : config;
|
|
4100
|
+
}
|
|
4101
|
+
async submit(config, userId, credential) {
|
|
4102
|
+
if (this.busy) return;
|
|
4103
|
+
const id = userId.trim();
|
|
4104
|
+
this.userId = id;
|
|
4105
|
+
this.error = "";
|
|
4106
|
+
this.retryAfterSec = 0;
|
|
4107
|
+
this.busy = true;
|
|
4108
|
+
this.host.changed();
|
|
4109
|
+
try {
|
|
4110
|
+
const session = await requestTeamsSession(config, { userId: id, credential });
|
|
4111
|
+
this.session = session;
|
|
4112
|
+
this.userId = session.userId;
|
|
4113
|
+
this.notice = "";
|
|
4114
|
+
this.phase = "open";
|
|
4115
|
+
this.armExpiry(session);
|
|
4116
|
+
this.host.emit("teams-signed-in", { userId: session.userId, expiresAt: session.expiresAt });
|
|
4117
|
+
} catch (error) {
|
|
4118
|
+
const failure = error instanceof TeamsSignInError ? error : null;
|
|
4119
|
+
this.error = signInErrorText(
|
|
4120
|
+
failure?.reason ?? "server",
|
|
4121
|
+
failure?.retryAfterSec,
|
|
4122
|
+
this.i18n()
|
|
4123
|
+
);
|
|
4124
|
+
this.retryAfterSec = failure?.retryAfterSec ?? 0;
|
|
4125
|
+
} finally {
|
|
4126
|
+
this.busy = false;
|
|
4127
|
+
this.host.changed();
|
|
4128
|
+
}
|
|
4129
|
+
}
|
|
4130
|
+
/** The session no longer works: back to the sign-in screen, keeping the user id. */
|
|
4131
|
+
expire(message) {
|
|
4132
|
+
if (!this.session) return;
|
|
4133
|
+
this.drop();
|
|
4134
|
+
this.notice = message;
|
|
4135
|
+
this.host.emit("teams-session-ended", { userId: this.userId });
|
|
4136
|
+
this.host.changed();
|
|
4137
|
+
}
|
|
4138
|
+
async signOut(config) {
|
|
4139
|
+
const session = this.session;
|
|
4140
|
+
if (!session) return;
|
|
4141
|
+
this.drop();
|
|
4142
|
+
this.userId = "";
|
|
4143
|
+
this.notice = this.i18n().t("signIn.signedOut");
|
|
4144
|
+
this.host.emit("teams-signed-out", { userId: session.userId });
|
|
4145
|
+
this.host.changed();
|
|
4146
|
+
await signOutTeamsSession(config, session.token);
|
|
4147
|
+
}
|
|
4148
|
+
/** Feed the connection status after every render; a session that stays unusable is checked. */
|
|
4149
|
+
watchConnection(connected, config) {
|
|
4150
|
+
if (!this.session) return;
|
|
4151
|
+
if (connected) {
|
|
4152
|
+
clearTimeout(this.checkTimer);
|
|
4153
|
+
this.checkTimer = void 0;
|
|
4154
|
+
return;
|
|
4155
|
+
}
|
|
4156
|
+
if (this.checkTimer !== void 0 || this.checking) return;
|
|
4157
|
+
this.scheduleCheck(config, PROBE_AFTER_MS);
|
|
4158
|
+
}
|
|
4159
|
+
scheduleCheck(config, delay) {
|
|
4160
|
+
const session = this.session;
|
|
4161
|
+
if (!session) return;
|
|
4162
|
+
this.checkTimer = setTimeout(() => {
|
|
4163
|
+
this.checkTimer = void 0;
|
|
4164
|
+
this.checking = true;
|
|
4165
|
+
void checkTeamsSession(config, session.token).then((result) => {
|
|
4166
|
+
this.checking = false;
|
|
4167
|
+
if (this.session !== session) return;
|
|
4168
|
+
if (result === "rejected") this.expire(this.i18n().t("signIn.ended"));
|
|
4169
|
+
else this.scheduleCheck(config, PROBE_AGAIN_MS);
|
|
4170
|
+
});
|
|
4171
|
+
}, delay);
|
|
4172
|
+
}
|
|
4173
|
+
armExpiry(session) {
|
|
4174
|
+
clearTimeout(this.expiryTimer);
|
|
4175
|
+
const wait = Math.min(Math.max(session.expiresAt - Date.now(), 0), MAX_TIMER_MS);
|
|
4176
|
+
this.expiryTimer = setTimeout(() => {
|
|
4177
|
+
if (this.session === session) this.expire(this.i18n().t("signIn.expired"));
|
|
4178
|
+
}, wait);
|
|
4179
|
+
}
|
|
4180
|
+
drop() {
|
|
4181
|
+
this.session = null;
|
|
4182
|
+
this.error = "";
|
|
4183
|
+
this.retryAfterSec = 0;
|
|
4184
|
+
clearTimeout(this.expiryTimer);
|
|
4185
|
+
clearTimeout(this.checkTimer);
|
|
4186
|
+
this.checkTimer = void 0;
|
|
4187
|
+
this.phase = "required";
|
|
4188
|
+
}
|
|
4189
|
+
/** Forget everything (the element is leaving the page). */
|
|
4190
|
+
dispose() {
|
|
4191
|
+
this.generation++;
|
|
4192
|
+
this.probing = "";
|
|
4193
|
+
clearTimeout(this.expiryTimer);
|
|
4194
|
+
clearTimeout(this.checkTimer);
|
|
4195
|
+
this.checkTimer = void 0;
|
|
4196
|
+
}
|
|
4197
|
+
};
|
|
4198
|
+
|
|
4199
|
+
// raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/teams/app/teams-sign-in.css?raw
|
|
4200
|
+
var teams_sign_in_default = ":host {\n display: grid;\n place-items: center;\n height: 100%;\n background: var(--office-teams-panel);\n color: var(--office-foreground);\n font: inherit;\n}\n.card {\n display: grid;\n justify-items: center;\n gap: var(--office-space-3);\n width: min(24em, 90%);\n padding: var(--office-space-6);\n border-radius: var(--office-radius-lg);\n background: var(--office-background);\n box-shadow: var(--office-shadow-teams);\n}\n.logo {\n display: inline-grid;\n place-items: center;\n width: 2.4em;\n height: 2.4em;\n border-radius: var(--office-radius-md);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n}\nh1 {\n margin: 0;\n font-size: var(--office-font-size-xl);\n}\np {\n margin: 0;\n text-align: center;\n overflow-wrap: anywhere;\n}\n.muted {\n color: var(--office-teams-text-subtle);\n}\nlabel {\n display: grid;\n gap: var(--office-space-2);\n width: 100%;\n}\ninput {\n width: 100%;\n box-sizing: border-box;\n padding: var(--office-space-3);\n border: var(--office-border-width) solid var(--office-field-border);\n border-radius: var(--office-radius);\n background: var(--office-field-background);\n color: inherit;\n font: inherit;\n}\ninput:focus-visible,\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n.error {\n color: var(--office-danger);\n}\nbutton {\n width: 100%;\n padding: var(--office-space-3);\n border: 0;\n border-radius: var(--office-radius-md);\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n font: inherit;\n font-weight: var(--office-font-weight-bold);\n cursor: pointer;\n}\nbutton:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n";
|
|
4201
|
+
|
|
4202
|
+
// src/teams/app/teams-sign-in.ts
|
|
4203
|
+
var TeamsSignIn = class extends TeamsLitElement {
|
|
4204
|
+
static styles = unsafeCSS(teams_sign_in_default);
|
|
4205
|
+
static properties = {
|
|
4206
|
+
userId: { type: String },
|
|
4207
|
+
notice: { type: String },
|
|
4208
|
+
error: { type: String },
|
|
4209
|
+
retryAfter: { type: Number },
|
|
4210
|
+
busy: { type: Boolean },
|
|
4211
|
+
checking: { type: Boolean },
|
|
4212
|
+
wait: { state: true }
|
|
4213
|
+
};
|
|
4214
|
+
timer;
|
|
4215
|
+
constructor() {
|
|
4216
|
+
super();
|
|
4217
|
+
this.userId = "";
|
|
4218
|
+
this.notice = "";
|
|
4219
|
+
this.error = "";
|
|
4220
|
+
this.retryAfter = 0;
|
|
4221
|
+
this.busy = false;
|
|
4222
|
+
this.checking = false;
|
|
4223
|
+
this.wait = 0;
|
|
4224
|
+
}
|
|
4225
|
+
willUpdate(changed) {
|
|
4226
|
+
if (!changed.has("retryAfter") && !changed.has("error")) return;
|
|
4227
|
+
clearInterval(this.timer);
|
|
4228
|
+
this.wait = this.error ? this.retryAfter : 0;
|
|
4229
|
+
if (this.wait <= 0) return;
|
|
4230
|
+
this.timer = setInterval(() => {
|
|
4231
|
+
this.wait = Math.max(0, this.wait - 1);
|
|
4232
|
+
if (this.wait === 0) clearInterval(this.timer);
|
|
4233
|
+
}, 1e3);
|
|
4234
|
+
}
|
|
4235
|
+
updated(changed) {
|
|
4236
|
+
if (changed.has("busy") && !this.busy && this.error)
|
|
4237
|
+
this.renderRoot.querySelector('input[name="credential"]')?.focus();
|
|
4238
|
+
}
|
|
4239
|
+
disconnectedCallback() {
|
|
4240
|
+
clearInterval(this.timer);
|
|
4241
|
+
super.disconnectedCallback();
|
|
4242
|
+
}
|
|
4243
|
+
submit(event) {
|
|
4244
|
+
event.preventDefault();
|
|
4245
|
+
if (this.busy || this.wait > 0) return;
|
|
4246
|
+
const form = event.target;
|
|
4247
|
+
const data = new FormData(form);
|
|
4248
|
+
const userId = String(data.get("user") ?? "").trim();
|
|
4249
|
+
const credential = String(data.get("credential") ?? "");
|
|
4250
|
+
form.elements.namedItem("credential").value = "";
|
|
4251
|
+
if (!userId || !credential) return;
|
|
4252
|
+
this.dispatchEvent(
|
|
4253
|
+
new CustomEvent("teams-sign-in-submit", {
|
|
4254
|
+
detail: { userId, credential },
|
|
4255
|
+
bubbles: true,
|
|
4256
|
+
composed: true
|
|
4257
|
+
})
|
|
4258
|
+
);
|
|
4259
|
+
}
|
|
4260
|
+
render() {
|
|
4261
|
+
if (this.checking)
|
|
4262
|
+
return html`<div class="card" role="status" aria-live="polite">
|
|
4263
|
+
<span class="logo" aria-hidden="true">T</span>
|
|
4264
|
+
<p class="muted">${this.t("signIn.checking")}</p>
|
|
4265
|
+
</div>`;
|
|
4266
|
+
const locked = this.busy || this.wait > 0;
|
|
4267
|
+
const error = this.error && this.wait > 0 && this.retryAfter > 0 ? this.t("signIn.error.rateLimited", { seconds: this.wait }) : this.error;
|
|
4268
|
+
return html`<form class="card" @submit=${this.submit} aria-busy=${String(this.busy)}>
|
|
4269
|
+
<span class="logo" aria-hidden="true">T</span>
|
|
4270
|
+
<h1>${this.t("signIn.title")}</h1>
|
|
4271
|
+
<p class="muted">${this.notice || this.t("signIn.intro")}</p>
|
|
4272
|
+
<label
|
|
4273
|
+
>${this.t("signIn.userLabel")}<input
|
|
4274
|
+
name="user"
|
|
4275
|
+
autocomplete="username"
|
|
4276
|
+
autocapitalize="none"
|
|
4277
|
+
spellcheck="false"
|
|
4278
|
+
maxlength="64"
|
|
4279
|
+
required
|
|
4280
|
+
.value=${this.userId}
|
|
4281
|
+
?disabled=${this.busy}
|
|
4282
|
+
/></label>
|
|
4283
|
+
<label
|
|
4284
|
+
>${this.t("signIn.credentialLabel")}<input
|
|
4285
|
+
name="credential"
|
|
4286
|
+
type="password"
|
|
4287
|
+
autocomplete="current-password"
|
|
4288
|
+
required
|
|
4289
|
+
?disabled=${this.busy}
|
|
4290
|
+
/></label>
|
|
4291
|
+
${error ? html`<p class="error" role="alert">${error}</p>` : nothing}
|
|
4292
|
+
<button type="submit" ?disabled=${locked}>
|
|
4293
|
+
${this.t(this.busy ? "signIn.submitting" : "signIn.submit")}
|
|
4294
|
+
</button>
|
|
4295
|
+
</form>`;
|
|
4296
|
+
}
|
|
4297
|
+
};
|
|
4298
|
+
function defineTeamsSignIn() {
|
|
4299
|
+
if (!customElements.get("teams-sign-in")) customElements.define("teams-sign-in", TeamsSignIn);
|
|
4300
|
+
}
|
|
4301
|
+
|
|
3766
4302
|
// raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/teams/app/pinned-bar.css?raw
|
|
3767
4303
|
var pinned_bar_default = ":host {\n display: block;\n flex: none;\n font: inherit;\n color: inherit;\n}\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\nsection {\n background: var(--office-teams-panel);\n border-block-end: var(--office-border-width) solid var(--office-teams-divider);\n}\nbutton {\n font: inherit;\n color: inherit;\n cursor: pointer;\n border: 0;\n background: transparent;\n}\n.summary {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n padding: var(--office-space-1) var(--office-space-3);\n}\n.latest {\n display: flex;\n flex: 1;\n align-items: center;\n gap: var(--office-space-2);\n min-width: 0;\n min-height: 2.2em;\n padding: var(--office-space-1) var(--office-space-2);\n border-radius: var(--office-radius);\n text-align: start;\n}\n.latest:hover,\n.count:hover,\n.jump:hover,\n.unpin:hover {\n background: var(--office-selected);\n}\n.mark {\n display: inline-grid;\n flex: none;\n color: var(--office-teams-brand);\n}\nsvg {\n width: 1.1em;\n height: 1.1em;\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.text {\n min-width: 0;\n overflow: hidden;\n color: var(--office-teams-text-subtle);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.count {\n flex: none;\n min-height: 2.2em;\n padding: var(--office-space-1) var(--office-space-3);\n border-radius: var(--office-radius);\n color: var(--office-teams-brand);\n font-weight: var(--office-font-weight-bold);\n}\nul {\n display: grid;\n gap: var(--office-space-1);\n max-height: 14em;\n margin: 0;\n padding: 0 var(--office-space-3) var(--office-space-2);\n overflow: auto;\n list-style: none;\n}\nli {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n}\n.jump {\n display: grid;\n flex: 1;\n gap: var(--office-space-0);\n min-width: 0;\n padding: var(--office-space-2) var(--office-space-3);\n border-radius: var(--office-radius-md);\n text-align: start;\n}\n.by {\n color: var(--office-teams-text-subtle);\n font-size: var(--office-font-size-xs);\n}\n.unpin {\n flex: none;\n margin-inline-end: var(--office-space-2);\n padding: var(--office-space-1) var(--office-space-3);\n border-radius: var(--office-radius);\n}\n:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n@media (pointer: coarse) {\n .latest,\n .count,\n .unpin {\n min-height: var(--office-touch-target, 44px);\n }\n .unpin {\n min-width: var(--office-touch-target, 44px);\n }\n}\n";
|
|
3768
4304
|
|
|
3769
4305
|
// src/teams/app/pinned-bar.ts
|
|
3770
4306
|
var SNIPPET = 140;
|
|
3771
|
-
var snippet = (m) => {
|
|
4307
|
+
var snippet = (m, attachment) => {
|
|
3772
4308
|
const text = m.text.replace(/\s+/gu, " ").trim();
|
|
3773
4309
|
if (text) return text.length > SNIPPET ? `${text.slice(0, SNIPPET)}...` : text;
|
|
3774
|
-
return m.attachments[0]?.name ??
|
|
4310
|
+
return m.attachments[0]?.name ?? attachment;
|
|
3775
4311
|
};
|
|
3776
|
-
var TeamsPinnedBar = class extends
|
|
4312
|
+
var TeamsPinnedBar = class extends TeamsLitElement {
|
|
3777
4313
|
static styles = unsafeCSS(pinned_bar_default);
|
|
3778
4314
|
static properties = { pinned: { attribute: false }, expanded: { state: true } };
|
|
3779
4315
|
constructor() {
|
|
@@ -3790,7 +4326,7 @@ var TeamsPinnedBar = class extends LitElement {
|
|
|
3790
4326
|
const [latest] = this.pinned;
|
|
3791
4327
|
if (!latest) return nothing;
|
|
3792
4328
|
return html`
|
|
3793
|
-
<section aria-label
|
|
4329
|
+
<section aria-label=${this.t("pinned.messages")}>
|
|
3794
4330
|
<div class="summary">
|
|
3795
4331
|
<button
|
|
3796
4332
|
type="button"
|
|
@@ -3799,7 +4335,7 @@ var TeamsPinnedBar = class extends LitElement {
|
|
|
3799
4335
|
>
|
|
3800
4336
|
<span class="mark">${icon("pin")}</span>
|
|
3801
4337
|
<strong>${latest.message.authorName}</strong>
|
|
3802
|
-
<span class="text">${snippet(latest.message)}</span>
|
|
4338
|
+
<span class="text">${snippet(latest.message, this.t("pinned.attachment"))}</span>
|
|
3803
4339
|
</button>
|
|
3804
4340
|
<button
|
|
3805
4341
|
type="button"
|
|
@@ -3808,7 +4344,7 @@ var TeamsPinnedBar = class extends LitElement {
|
|
|
3808
4344
|
aria-controls="pins"
|
|
3809
4345
|
@click=${() => this.expanded = !this.expanded}
|
|
3810
4346
|
>
|
|
3811
|
-
${this.pinned.length}
|
|
4347
|
+
${this.t("pinned.count", { count: this.pinned.length })}
|
|
3812
4348
|
</button>
|
|
3813
4349
|
</div>
|
|
3814
4350
|
${this.expanded ? html`<ul id="pins">
|
|
@@ -3820,17 +4356,19 @@ var TeamsPinnedBar = class extends LitElement {
|
|
|
3820
4356
|
@click=${() => this.emit("teams-pinned-open", pin.message.id)}
|
|
3821
4357
|
>
|
|
3822
4358
|
<strong>${pin.message.authorName}</strong>
|
|
3823
|
-
<span class="text"
|
|
3824
|
-
|
|
4359
|
+
<span class="text"
|
|
4360
|
+
>${snippet(pin.message, this.t("pinned.attachment"))}</span
|
|
4361
|
+
>
|
|
4362
|
+
<span class="by">${this.t("pinned.by", { name: pin.pinnedByName })}</span>
|
|
3825
4363
|
</button>
|
|
3826
4364
|
<button
|
|
3827
4365
|
type="button"
|
|
3828
4366
|
class="unpin"
|
|
3829
|
-
aria-label=${
|
|
3830
|
-
title
|
|
4367
|
+
aria-label=${this.t("pinned.unpinFrom", { name: pin.message.authorName })}
|
|
4368
|
+
title=${this.t("chat.unpin")}
|
|
3831
4369
|
@click=${() => this.emit("teams-pinned-unpin", pin.message.id)}
|
|
3832
4370
|
>
|
|
3833
|
-
|
|
4371
|
+
${this.t("chat.unpin")}
|
|
3834
4372
|
</button>
|
|
3835
4373
|
</li>`
|
|
3836
4374
|
)}
|
|
@@ -3859,14 +4397,16 @@ function watchActivity(target, onActivity, throttleMs = 1e3, now = Date.now) {
|
|
|
3859
4397
|
for (const name of ACTIVITY_EVENTS) target.removeEventListener(name, handler);
|
|
3860
4398
|
};
|
|
3861
4399
|
}
|
|
3862
|
-
|
|
4400
|
+
|
|
4401
|
+
// src/teams/app/notify-delivery.ts
|
|
4402
|
+
function deliverNotification(item, settings, env, actions, i18n = teamsI18n()) {
|
|
3863
4403
|
let result = "none";
|
|
3864
4404
|
if (!env.hidden()) {
|
|
3865
4405
|
actions.toast(item);
|
|
3866
4406
|
result = "toast";
|
|
3867
4407
|
} else if (env.permission() === "granted") {
|
|
3868
4408
|
env.show(
|
|
3869
|
-
|
|
4409
|
+
describeActivityIn(item, i18n),
|
|
3870
4410
|
{ body: item.preview, tag: item.id },
|
|
3871
4411
|
() => actions.open(item)
|
|
3872
4412
|
);
|
|
@@ -3919,17 +4459,17 @@ var add_tab_dialog_default = ":host {\n font: var(--office-font-size) var(--offi
|
|
|
3919
4459
|
|
|
3920
4460
|
// src/teams/app/add-tab-dialog.ts
|
|
3921
4461
|
var APPS = [
|
|
3922
|
-
{ id: "docx", label: "
|
|
3923
|
-
{ id: "xlsx", label: "
|
|
3924
|
-
{ id: "pptx", label: "
|
|
3925
|
-
{ id: "vsdx", label: "
|
|
3926
|
-
{ id: "markdown", label: "
|
|
3927
|
-
{ id: "site", label: "
|
|
3928
|
-
{ id: "text", label: "
|
|
3929
|
-
{ id: "website", label: "
|
|
4462
|
+
{ id: "docx", label: "app.word", kind: "docx", letter: "W" },
|
|
4463
|
+
{ id: "xlsx", label: "app.excel", kind: "xlsx", letter: "X" },
|
|
4464
|
+
{ id: "pptx", label: "app.powerpoint", kind: "pptx", letter: "P" },
|
|
4465
|
+
{ id: "vsdx", label: "app.visio", kind: "vsdx", letter: "V" },
|
|
4466
|
+
{ id: "markdown", label: "app.markdown", kind: "markdown", letter: "M" },
|
|
4467
|
+
{ id: "site", label: "app.site", kind: "website", letter: "H" },
|
|
4468
|
+
{ id: "text", label: "app.text", kind: "text", letter: "T" },
|
|
4469
|
+
{ id: "website", label: "app.website", kind: null, letter: "\u2197" }
|
|
3930
4470
|
];
|
|
3931
4471
|
var fileKey2 = (file) => JSON.stringify([file.messageId, file.name, file.url]);
|
|
3932
|
-
var TeamsAddTabDialog = class extends
|
|
4472
|
+
var TeamsAddTabDialog = class extends TeamsLitElement {
|
|
3933
4473
|
static styles = unsafeCSS(add_tab_dialog_default);
|
|
3934
4474
|
static properties = {
|
|
3935
4475
|
open: { type: Boolean },
|
|
@@ -4002,8 +4542,7 @@ var TeamsAddTabDialog = class extends LitElement {
|
|
|
4002
4542
|
return app?.kind ? this.eligible(app.kind).find((file) => fileKey2(file) === this.selectedKey) : void 0;
|
|
4003
4543
|
}
|
|
4004
4544
|
availableLabel(kind) {
|
|
4005
|
-
|
|
4006
|
-
return `${count} shared ${count === 1 ? "file" : "files"}`;
|
|
4545
|
+
return this.tn("addTab.sharedFiles", this.eligible(kind).length);
|
|
4007
4546
|
}
|
|
4008
4547
|
choose(app) {
|
|
4009
4548
|
this.app = app;
|
|
@@ -4017,55 +4556,59 @@ var TeamsAddTabDialog = class extends LitElement {
|
|
|
4017
4556
|
event.preventDefault();
|
|
4018
4557
|
this.error = "";
|
|
4019
4558
|
if (!this.current || !this.owner || !this.add) {
|
|
4020
|
-
this.error =
|
|
4559
|
+
this.error = this.t("addTab.channelChanged");
|
|
4021
4560
|
return;
|
|
4022
4561
|
}
|
|
4023
4562
|
if (this.app === "website" && !contentUrl(this.url, this.ownerDocument.baseURI)) {
|
|
4024
|
-
this.error = "
|
|
4563
|
+
this.error = this.t("addTab.invalidUrl");
|
|
4025
4564
|
return;
|
|
4026
4565
|
}
|
|
4027
4566
|
const content = this.app === "website" ? { type: "website", url: this.url } : this.selected ? { type: "file", attachment: this.selected } : null;
|
|
4028
4567
|
if (!content) {
|
|
4029
|
-
this.error =
|
|
4568
|
+
this.error = this.t("addTab.chooseShared");
|
|
4030
4569
|
return;
|
|
4031
4570
|
}
|
|
4032
4571
|
const result = this.add(this.name, content, this.context, this.owner, this.postToChannel);
|
|
4033
|
-
if (!result) this.error = "
|
|
4572
|
+
if (!result) this.error = this.t("addTab.invalid");
|
|
4034
4573
|
}
|
|
4035
4574
|
render() {
|
|
4036
4575
|
const app = APPS.find((entry) => entry.id === this.app);
|
|
4037
4576
|
const files = app?.kind ? filterFiles(this.eligible(app.kind), this.query) : [];
|
|
4038
|
-
return html`<dialog
|
|
4577
|
+
return html`<dialog
|
|
4578
|
+
aria-label=${this.t("addTab.title")}
|
|
4579
|
+
@cancel=${this.close}
|
|
4580
|
+
@close=${this.close}
|
|
4581
|
+
>
|
|
4039
4582
|
<header>
|
|
4040
|
-
<h1
|
|
4041
|
-
<button type="button" aria-label
|
|
4583
|
+
<h1>${this.t("addTab.title")}</h1>
|
|
4584
|
+
<button type="button" aria-label=${this.t("addTab.close")} @click=${this.close}>×</button>
|
|
4042
4585
|
</header>
|
|
4043
4586
|
${!app ? html`<section>
|
|
4044
|
-
<h2
|
|
4045
|
-
<p
|
|
4587
|
+
<h2>${this.t("addTab.chooseApp")}</h2>
|
|
4588
|
+
<p>${this.t("addTab.pinTo", { channel: this.contextName })}</p>
|
|
4046
4589
|
<div class="apps">
|
|
4047
4590
|
${APPS.map(
|
|
4048
4591
|
(entry, index) => html`<button
|
|
4049
4592
|
type="button"
|
|
4050
4593
|
class="app"
|
|
4051
|
-
aria-label=${
|
|
4594
|
+
aria-label=${this.t("addTab.choose", { app: this.t(entry.label) })}
|
|
4052
4595
|
?data-first-app=${index === 0}
|
|
4053
4596
|
?autofocus=${index === 0}
|
|
4054
4597
|
@click=${() => this.choose(entry.id)}
|
|
4055
4598
|
>
|
|
4056
4599
|
<span class="badge" data-kind=${entry.kind ?? "other"}>${entry.letter}</span
|
|
4057
|
-
><strong>${entry.label}</strong>
|
|
4600
|
+
><strong>${this.t(entry.label)}</strong>
|
|
4058
4601
|
<small
|
|
4059
|
-
>${entry.kind ? this.availableLabel(entry.kind) : "
|
|
4602
|
+
>${entry.kind ? this.availableLabel(entry.kind) : this.t("addTab.addAddress")}</small
|
|
4060
4603
|
>
|
|
4061
4604
|
</button>`
|
|
4062
4605
|
)}
|
|
4063
4606
|
</div>
|
|
4064
|
-
<p class="hint"
|
|
4607
|
+
<p class="hint">${this.t("addTab.fileHint")}</p>
|
|
4065
4608
|
</section>` : html`<form @submit=${this.submit}>
|
|
4066
4609
|
<div class="app-heading">
|
|
4067
4610
|
<span class="badge" data-kind=${app.kind ?? "other"}>${app.letter}</span>
|
|
4068
|
-
<h2>${app.label}</h2>
|
|
4611
|
+
<h2>${this.t(app.label)}</h2>
|
|
4069
4612
|
<button
|
|
4070
4613
|
type="button"
|
|
4071
4614
|
@click=${() => {
|
|
@@ -4073,11 +4616,11 @@ var TeamsAddTabDialog = class extends LitElement {
|
|
|
4073
4616
|
this.error = "";
|
|
4074
4617
|
}}
|
|
4075
4618
|
>
|
|
4076
|
-
|
|
4619
|
+
${this.t("common.back")}
|
|
4077
4620
|
</button>
|
|
4078
4621
|
</div>
|
|
4079
4622
|
<label
|
|
4080
|
-
|
|
4623
|
+
>${this.t("addTab.name")}<input
|
|
4081
4624
|
data-configure
|
|
4082
4625
|
name="name"
|
|
4083
4626
|
maxlength="80"
|
|
@@ -4089,7 +4632,7 @@ var TeamsAddTabDialog = class extends LitElement {
|
|
|
4089
4632
|
}}
|
|
4090
4633
|
/></label>
|
|
4091
4634
|
${!app.kind ? html`<label
|
|
4092
|
-
|
|
4635
|
+
>${this.t("addTab.websiteUrl")}<input
|
|
4093
4636
|
type="url"
|
|
4094
4637
|
required
|
|
4095
4638
|
maxlength="2048"
|
|
@@ -4100,17 +4643,14 @@ var TeamsAddTabDialog = class extends LitElement {
|
|
|
4100
4643
|
this.error = "";
|
|
4101
4644
|
}}
|
|
4102
4645
|
/></label>
|
|
4103
|
-
<p class="hint"
|
|
4104
|
-
|
|
4105
|
-
preview.
|
|
4106
|
-
</p>` : html`<label
|
|
4107
|
-
>Search shared files<input
|
|
4646
|
+
<p class="hint">${this.t("addTab.embedHint")}</p>` : html`<label
|
|
4647
|
+
>${this.t("addTab.searchFiles")}<input
|
|
4108
4648
|
type="search"
|
|
4109
4649
|
.value=${this.query}
|
|
4110
4650
|
@input=${(event) => this.query = event.target.value}
|
|
4111
4651
|
/></label>
|
|
4112
4652
|
<fieldset class="files">
|
|
4113
|
-
<legend
|
|
4653
|
+
<legend>${this.t("addTab.chooseFile")}</legend>
|
|
4114
4654
|
${files.map(
|
|
4115
4655
|
(file) => html`<label class="file"
|
|
4116
4656
|
><input
|
|
@@ -4125,30 +4665,32 @@ var TeamsAddTabDialog = class extends LitElement {
|
|
|
4125
4665
|
}}
|
|
4126
4666
|
/><span
|
|
4127
4667
|
><strong>${file.name}</strong
|
|
4128
|
-
><small
|
|
4668
|
+
><small
|
|
4669
|
+
>${this.t("addTab.sharedBy", { author: file.author })}</small
|
|
4670
|
+
></span
|
|
4129
4671
|
></label
|
|
4130
4672
|
>`
|
|
4131
4673
|
)}
|
|
4132
|
-
${files.length ? nothing : html`<p class="hint">${this.query ? "
|
|
4674
|
+
${files.length ? nothing : html`<p class="hint">${this.query ? this.t("files.noMatch") : this.t("addTab.noFiles", { app: this.t(app.label) })}</p>`}
|
|
4133
4675
|
</fieldset>
|
|
4134
|
-
${this.selected ? html`<p class="hint"
|
|
4135
|
-
${!this.current ? html`<p role="alert"
|
|
4676
|
+
${this.selected ? html`<p class="hint">${this.t("addTab.selected", { name: this.selected.name })}</p>` : this.selectedKey ? html`<p role="alert">${this.t("addTab.noLongerShared")}</p>` : nothing}`}
|
|
4677
|
+
${!this.current ? html`<p role="alert">${this.t("addTab.channelChanged")}</p>` : nothing}
|
|
4136
4678
|
${this.error ? html`<p role="alert">${this.error}</p>` : nothing}
|
|
4137
4679
|
<label class="post-choice"
|
|
4138
4680
|
><input
|
|
4139
4681
|
type="checkbox"
|
|
4140
4682
|
.checked=${this.postToChannel}
|
|
4141
4683
|
@change=${(event) => this.postToChannel = event.target.checked}
|
|
4142
|
-
|
|
4684
|
+
/>${this.t("addTab.postToChannel")}</label
|
|
4143
4685
|
>
|
|
4144
4686
|
<footer>
|
|
4145
|
-
<button type="button" @click=${this.close}
|
|
4687
|
+
<button type="button" @click=${this.close}>${this.t("common.cancel")}</button
|
|
4146
4688
|
><button
|
|
4147
4689
|
type="submit"
|
|
4148
4690
|
class="primary"
|
|
4149
4691
|
?disabled=${!this.current || !this.name.trim() || (app.kind ? !this.selected : !this.url.trim())}
|
|
4150
4692
|
>
|
|
4151
|
-
|
|
4693
|
+
${this.t("common.save")}
|
|
4152
4694
|
</button>
|
|
4153
4695
|
</footer>
|
|
4154
4696
|
</form>`}
|
|
@@ -4164,7 +4706,7 @@ function defineTeamsAddTabDialog() {
|
|
|
4164
4706
|
var create_channel_dialog_default = ":host {\n font: var(--office-font-size) var(--office-font);\n color: var(--office-foreground);\n}\ndialog {\n box-sizing: border-box;\n width: min(40em, 94vw);\n max-height: 90dvh;\n padding: 0;\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-lg);\n background: var(--office-popover);\n color: inherit;\n box-shadow: var(--office-shadow-teams);\n}\ndialog::backdrop {\n background: var(--office-overlay);\n}\nheader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--office-space-3);\n padding: var(--office-space-4) var(--office-space-5);\n border-block-end: var(--office-border-width) solid var(--office-teams-divider);\n}\nh2 {\n margin: 0;\n font-size: var(--office-font-size-lg);\n}\nform {\n display: grid;\n gap: var(--office-space-3);\n padding: var(--office-space-5);\n}\nlabel {\n display: grid;\n gap: var(--office-space-2);\n font-weight: var(--office-font-weight-bold);\n}\ninput,\ntextarea {\n min-width: 0;\n width: 100%;\n box-sizing: border-box;\n padding: var(--office-space-3);\n font: inherit;\n font-weight: normal;\n color: inherit;\n background: var(--office-field-background);\n border: var(--office-border-width) solid var(--office-field-border);\n border-radius: var(--office-radius-md);\n}\ntextarea {\n min-height: 6em;\n resize: vertical;\n}\np,\nsmall {\n margin: 0;\n color: var(--office-teams-text-subtle);\n line-height: 1.5;\n}\n.issue {\n color: var(--office-danger);\n}\nfooter {\n display: flex;\n justify-content: flex-end;\n gap: var(--office-space-2);\n}\nbutton {\n padding: var(--office-space-2) var(--office-space-4);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n background: var(--office-background);\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\nbutton:hover {\n background: var(--office-selected);\n}\nbutton.primary {\n background: var(--office-teams-brand);\n color: var(--office-teams-brand-foreground);\n border-color: transparent;\n}\nbutton.primary:hover {\n background: var(--office-teams-brand-hover);\n}\n:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n";
|
|
4165
4707
|
|
|
4166
4708
|
// src/teams/app/create-channel-dialog.ts
|
|
4167
|
-
var TeamsCreateChannelDialog = class extends
|
|
4709
|
+
var TeamsCreateChannelDialog = class extends TeamsLitElement {
|
|
4168
4710
|
static styles = unsafeCSS(create_channel_dialog_default);
|
|
4169
4711
|
static properties = {
|
|
4170
4712
|
open: { type: Boolean, reflect: true },
|
|
@@ -4202,12 +4744,11 @@ var TeamsCreateChannelDialog = class extends LitElement {
|
|
|
4202
4744
|
event.preventDefault();
|
|
4203
4745
|
const name = sanitizeChannelName(this.name);
|
|
4204
4746
|
if (!name) {
|
|
4205
|
-
this.issue = "
|
|
4747
|
+
this.issue = this.t("channel.enterName");
|
|
4206
4748
|
this.renderRoot.querySelector("input")?.focus();
|
|
4207
4749
|
return;
|
|
4208
4750
|
}
|
|
4209
|
-
if (!this.create?.(name, this.description))
|
|
4210
|
-
this.issue = "The channel was not created. Your details are kept here.";
|
|
4751
|
+
if (!this.create?.(name, this.description)) this.issue = this.t("channel.notCreated");
|
|
4211
4752
|
}
|
|
4212
4753
|
render() {
|
|
4213
4754
|
return html`<dialog
|
|
@@ -4218,12 +4759,14 @@ var TeamsCreateChannelDialog = class extends LitElement {
|
|
|
4218
4759
|
}}
|
|
4219
4760
|
>
|
|
4220
4761
|
<header>
|
|
4221
|
-
<h2 id="title"
|
|
4222
|
-
<button type="button" aria-label
|
|
4762
|
+
<h2 id="title">${this.t("channel.create")}</h2>
|
|
4763
|
+
<button type="button" aria-label=${this.t("channel.closeCreate")} @click=${this.close}>
|
|
4764
|
+
×
|
|
4765
|
+
</button>
|
|
4223
4766
|
</header>
|
|
4224
4767
|
<form @submit=${this.submit}>
|
|
4225
4768
|
<label
|
|
4226
|
-
|
|
4769
|
+
>${this.t("channel.name")}<input
|
|
4227
4770
|
autofocus
|
|
4228
4771
|
maxlength=${MAX_CHANNEL_NAME_CHARS}
|
|
4229
4772
|
.value=${this.name}
|
|
@@ -4231,29 +4774,28 @@ var TeamsCreateChannelDialog = class extends LitElement {
|
|
|
4231
4774
|
this.name = event.target.value;
|
|
4232
4775
|
this.issue = "";
|
|
4233
4776
|
}}
|
|
4234
|
-
placeholder
|
|
4777
|
+
placeholder=${this.t("channel.namePlaceholder")}
|
|
4235
4778
|
aria-describedby="channel-name-help"
|
|
4236
4779
|
/></label>
|
|
4237
|
-
<small id="channel-name-help"
|
|
4780
|
+
<small id="channel-name-help"
|
|
4781
|
+
>${this.t("channel.maxChars", { count: MAX_CHANNEL_NAME_CHARS })}</small
|
|
4782
|
+
>
|
|
4238
4783
|
<label
|
|
4239
|
-
|
|
4784
|
+
>${this.t("channel.description")}<textarea
|
|
4240
4785
|
maxlength=${MAX_CHANNEL_TOPIC_CHARS}
|
|
4241
4786
|
.value=${this.description}
|
|
4242
4787
|
@input=${(event) => this.description = event.target.value}
|
|
4243
|
-
placeholder
|
|
4788
|
+
placeholder=${this.t("channel.descriptionPlaceholder")}
|
|
4244
4789
|
></textarea>
|
|
4245
4790
|
</label>
|
|
4246
4791
|
<div>
|
|
4247
|
-
<strong
|
|
4248
|
-
<p>
|
|
4249
|
-
Available to everyone in this workspace. Private and shared channels are not available
|
|
4250
|
-
yet.
|
|
4251
|
-
</p>
|
|
4792
|
+
<strong>${this.t("channel.standard")}</strong>
|
|
4793
|
+
<p>${this.t("channel.standardNote")}</p>
|
|
4252
4794
|
</div>
|
|
4253
4795
|
${this.issue ? html`<p class="issue" role="alert">${this.issue}</p>` : nothing}
|
|
4254
4796
|
<footer>
|
|
4255
|
-
<button type="button" @click=${this.close}
|
|
4256
|
-
><button type="submit" class="primary"
|
|
4797
|
+
<button type="button" @click=${this.close}>${this.t("common.cancel")}</button
|
|
4798
|
+
><button type="submit" class="primary">${this.t("common.create")}</button>
|
|
4257
4799
|
</footer>
|
|
4258
4800
|
</form>
|
|
4259
4801
|
</dialog>`;
|
|
@@ -4288,7 +4830,7 @@ var TeamsDialog = class extends TeamsElement {
|
|
|
4288
4830
|
this.fire("teams-dialog-close", {});
|
|
4289
4831
|
}
|
|
4290
4832
|
/** The dialog frame with a title and a close button around `body`. */
|
|
4291
|
-
frame(title, body, closeLabel =
|
|
4833
|
+
frame(title, body, closeLabel = this.t("common.close")) {
|
|
4292
4834
|
return html`<dialog
|
|
4293
4835
|
aria-labelledby="title"
|
|
4294
4836
|
@cancel=${(event) => {
|
|
@@ -4337,21 +4879,21 @@ var TeamsNewChatDialog = class extends TeamsDialog {
|
|
|
4337
4879
|
submit(event) {
|
|
4338
4880
|
event.preventDefault();
|
|
4339
4881
|
if (this.selected.length === 0) {
|
|
4340
|
-
this.issue = "
|
|
4882
|
+
this.issue = this.t("newChat.pickOne");
|
|
4341
4883
|
return;
|
|
4342
4884
|
}
|
|
4343
4885
|
if (!this.create?.(this.selected, this.selected.length > 1 ? this.name : ""))
|
|
4344
|
-
this.issue = "
|
|
4886
|
+
this.issue = this.t("newChat.failed");
|
|
4345
4887
|
}
|
|
4346
4888
|
render() {
|
|
4347
4889
|
const group = this.selected.length > 1;
|
|
4348
4890
|
return this.frame(
|
|
4349
|
-
"
|
|
4891
|
+
this.t("chat.new"),
|
|
4350
4892
|
html`<form @submit=${this.submit}>
|
|
4351
4893
|
<div class="field">
|
|
4352
|
-
|
|
4894
|
+
${this.t("newChat.to")}
|
|
4353
4895
|
<office-ui-people-picker
|
|
4354
|
-
label
|
|
4896
|
+
label=${this.t("newChat.peopleLabel")}
|
|
4355
4897
|
.contacts=${this.contacts}
|
|
4356
4898
|
.selected=${this.selected}
|
|
4357
4899
|
@office-people-change=${(e) => {
|
|
@@ -4361,23 +4903,22 @@ var TeamsNewChatDialog = class extends TeamsDialog {
|
|
|
4361
4903
|
></office-ui-people-picker>
|
|
4362
4904
|
</div>
|
|
4363
4905
|
${group ? html`<label
|
|
4364
|
-
|
|
4906
|
+
>${this.t("chatPeople.groupNameOptional")}<input
|
|
4365
4907
|
maxlength=${MAX_CHANNEL_NAME_CHARS}
|
|
4366
4908
|
.value=${this.name}
|
|
4367
|
-
placeholder
|
|
4909
|
+
placeholder=${this.t("chatPeople.groupPlaceholder")}
|
|
4368
4910
|
@input=${(e) => this.name = e.target.value}
|
|
4369
4911
|
/></label>` : nothing}
|
|
4370
|
-
<small
|
|
4371
|
-
>${group ? "Everyone you pick joins one group chat. Only its members can read it." : "Pick one person for a 1:1 chat, or several for a group chat."}</small
|
|
4372
|
-
>
|
|
4912
|
+
<small>${group ? this.t("newChat.hintGroup") : this.t("newChat.hintOne")}</small>
|
|
4373
4913
|
${this.issue ? html`<p class="issue" role="alert">${this.issue}</p>` : nothing}
|
|
4374
4914
|
<footer>
|
|
4375
|
-
<button type="button" @click=${this.requestClose}
|
|
4915
|
+
<button type="button" @click=${this.requestClose}>${this.t("common.cancel")}</button>
|
|
4376
4916
|
<button type="submit" class="primary" ?disabled=${this.selected.length === 0}>
|
|
4377
|
-
${group ? "
|
|
4917
|
+
${this.t(group ? "newChat.startGroup" : "newChat.start")}
|
|
4378
4918
|
</button>
|
|
4379
4919
|
</footer>
|
|
4380
|
-
</form
|
|
4920
|
+
</form>`,
|
|
4921
|
+
this.t("dialog.closeNewChat")
|
|
4381
4922
|
);
|
|
4382
4923
|
}
|
|
4383
4924
|
};
|
|
@@ -4414,10 +4955,10 @@ var TeamsChatPeopleDialog = class extends TeamsDialog {
|
|
|
4414
4955
|
}
|
|
4415
4956
|
render() {
|
|
4416
4957
|
const chat = this.chat;
|
|
4417
|
-
if (!chat) return this.frame("
|
|
4958
|
+
if (!chat) return this.frame(this.t("chat.people"), html``, this.t("dialog.closePeople"));
|
|
4418
4959
|
const group = chat.kind === "group";
|
|
4419
4960
|
return this.frame(
|
|
4420
|
-
"
|
|
4961
|
+
this.t("chat.people"),
|
|
4421
4962
|
html`<div class="body">
|
|
4422
4963
|
${group ? html`<form
|
|
4423
4964
|
class="rename"
|
|
@@ -4427,15 +4968,15 @@ var TeamsChatPeopleDialog = class extends TeamsDialog {
|
|
|
4427
4968
|
}}
|
|
4428
4969
|
>
|
|
4429
4970
|
<label
|
|
4430
|
-
|
|
4971
|
+
>${this.t("chatPeople.groupName")}<input
|
|
4431
4972
|
maxlength=${MAX_CHANNEL_NAME_CHARS}
|
|
4432
4973
|
.value=${this.name}
|
|
4433
|
-
placeholder
|
|
4974
|
+
placeholder=${this.t("chatPeople.groupPlaceholder")}
|
|
4434
4975
|
@input=${(e) => this.name = e.target.value}
|
|
4435
4976
|
/></label>
|
|
4436
|
-
<button type="submit"
|
|
4977
|
+
<button type="submit">${this.t("chatPeople.rename")}</button>
|
|
4437
4978
|
</form>` : nothing}
|
|
4438
|
-
<h3
|
|
4979
|
+
<h3>${this.t("chatPeople.inChat", { count: chat.members.length })}</h3>
|
|
4439
4980
|
<ul class="members">
|
|
4440
4981
|
${chat.members.map(
|
|
4441
4982
|
(m) => html`<li>
|
|
@@ -4445,20 +4986,22 @@ var TeamsChatPeopleDialog = class extends TeamsDialog {
|
|
|
4445
4986
|
seed=${m.id}
|
|
4446
4987
|
presence=${m.availability}
|
|
4447
4988
|
></office-ui-avatar>
|
|
4448
|
-
<span class="name"
|
|
4989
|
+
<span class="name"
|
|
4990
|
+
>${m.self ? this.t("common.nameYou", { name: m.name }) : m.name}</span
|
|
4991
|
+
>
|
|
4449
4992
|
${group && !m.self && chat.members.length > 1 ? html`<button
|
|
4450
4993
|
type="button"
|
|
4451
|
-
aria-label=${
|
|
4994
|
+
aria-label=${this.t("people.remove", { name: m.name })}
|
|
4452
4995
|
@click=${() => this.fire("teams-chat-remove", { id: chat.id, userId: m.id })}
|
|
4453
4996
|
>
|
|
4454
|
-
|
|
4997
|
+
${this.t("chatPeople.remove")}
|
|
4455
4998
|
</button>` : nothing}
|
|
4456
4999
|
</li>`
|
|
4457
5000
|
)}
|
|
4458
5001
|
</ul>
|
|
4459
|
-
${group ? html`<h3
|
|
5002
|
+
${group ? html`<h3>${this.t("chatPeople.addPeople")}</h3>
|
|
4460
5003
|
<office-ui-people-picker
|
|
4461
|
-
label
|
|
5004
|
+
label=${this.t("chatPeople.peopleToAdd")}
|
|
4462
5005
|
.contacts=${this.contacts}
|
|
4463
5006
|
.exclude=${chat.members.map((m) => m.id)}
|
|
4464
5007
|
.selected=${this.adding}
|
|
@@ -4474,22 +5017,21 @@ var TeamsChatPeopleDialog = class extends TeamsDialog {
|
|
|
4474
5017
|
this.adding = [];
|
|
4475
5018
|
}}
|
|
4476
5019
|
>
|
|
4477
|
-
|
|
5020
|
+
${this.t("chatPeople.addToChat")}
|
|
4478
5021
|
</button>
|
|
4479
|
-
</footer>` : html`<p
|
|
4480
|
-
People cannot be added to or removed from a 1:1 chat. Start a group chat instead.
|
|
4481
|
-
</p>`}
|
|
5022
|
+
</footer>` : html`<p>${this.t("chatPeople.directNote")}</p>`}
|
|
4482
5023
|
<footer>
|
|
4483
5024
|
${chat.canLeave ? html`<button
|
|
4484
5025
|
type="button"
|
|
4485
5026
|
class="danger"
|
|
4486
5027
|
@click=${() => this.fire("teams-chat-leave", { id: chat.id })}
|
|
4487
5028
|
>
|
|
4488
|
-
|
|
5029
|
+
${this.t("chatPeople.leave")}
|
|
4489
5030
|
</button>` : nothing}
|
|
4490
|
-
<button type="button" @click=${this.requestClose}
|
|
5031
|
+
<button type="button" @click=${this.requestClose}>${this.t("common.done")}</button>
|
|
4491
5032
|
</footer>
|
|
4492
|
-
</div
|
|
5033
|
+
</div>`,
|
|
5034
|
+
this.t("dialog.closePeople")
|
|
4493
5035
|
);
|
|
4494
5036
|
}
|
|
4495
5037
|
};
|
|
@@ -4500,10 +5042,61 @@ function defineTeamsChatPeopleDialog(registry = globalThis.customElements) {
|
|
|
4500
5042
|
|
|
4501
5043
|
// raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/teams/app/meeting-dialog.css?raw
|
|
4502
5044
|
var meeting_dialog_default = ".times {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--office-space-3);\n}\noffice-ui-people-picker {\n font-weight: normal;\n}\n@media (max-width: 40em) {\n .times {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n";
|
|
5045
|
+
var monthDay = (month, day, i18n) => new Intl.DateTimeFormat(i18n.locale, { month: "long", day: "numeric", timeZone: "UTC" }).format(
|
|
5046
|
+
Date.UTC(2e3, month - 1, day)
|
|
5047
|
+
);
|
|
5048
|
+
var weekdayName = (weekday, i18n) => new Intl.DateTimeFormat(i18n.locale, { weekday: "long", timeZone: "UTC" }).format(
|
|
5049
|
+
Date.UTC(2e3, 0, 2 + weekday % 7)
|
|
5050
|
+
);
|
|
5051
|
+
var ORDINAL_KEYS = {
|
|
5052
|
+
1: "repeat.monthlyOrdinal.1",
|
|
5053
|
+
2: "repeat.monthlyOrdinal.2",
|
|
5054
|
+
3: "repeat.monthlyOrdinal.3",
|
|
5055
|
+
4: "repeat.monthlyOrdinal.4",
|
|
5056
|
+
[-1]: "repeat.monthlyOrdinal.last"
|
|
5057
|
+
};
|
|
5058
|
+
var monthlyWeekday = (ordinal, weekday, i18n) => i18n.t(ORDINAL_KEYS[ordinal] ?? "repeat.monthlyOrdinal.1", {
|
|
5059
|
+
weekday: weekdayName(weekday, i18n)
|
|
5060
|
+
});
|
|
5061
|
+
var NO_REPEAT = { repeat: "none", monthlyBy: "date", ordinal: 1 };
|
|
5062
|
+
var repeatValue = (r) => r.repeat === "monthly" ? r.monthlyBy === "weekday" ? `monthly-${r.ordinal}` : "monthly-date" : r.repeat;
|
|
5063
|
+
function parseRepeatValue(value) {
|
|
5064
|
+
if (value === "monthly-date") return { repeat: "monthly", monthlyBy: "date", ordinal: 1 };
|
|
5065
|
+
const m = /^monthly-(-?\d)$/u.exec(value);
|
|
5066
|
+
if (m) return { repeat: "monthly", monthlyBy: "weekday", ordinal: Number(m[1]) };
|
|
5067
|
+
if (value === "daily" || value === "weekly" || value === "yearly")
|
|
5068
|
+
return { repeat: value, monthlyBy: "date", ordinal: 1 };
|
|
5069
|
+
return NO_REPEAT;
|
|
5070
|
+
}
|
|
5071
|
+
function repeatOptions(start, zone, i18n = teamsI18n()) {
|
|
5072
|
+
const { month, day, weekday, ordinals } = repeatChoices(start, zone);
|
|
5073
|
+
return [
|
|
5074
|
+
{ value: "none", label: i18n.t("repeat.none") },
|
|
5075
|
+
{ value: "daily", label: i18n.t("repeat.daily") },
|
|
5076
|
+
{ value: "weekly", label: i18n.t("repeat.weekly") },
|
|
5077
|
+
{ value: "monthly-date", label: i18n.t("repeat.monthlyDay", { day }) },
|
|
5078
|
+
...ordinals.map((o) => ({
|
|
5079
|
+
value: `monthly-${o}`,
|
|
5080
|
+
label: monthlyWeekday(o, weekday, i18n)
|
|
5081
|
+
})),
|
|
5082
|
+
{ value: "yearly", label: i18n.t("repeat.yearlyOn", { date: monthDay(month, day, i18n) }) }
|
|
5083
|
+
];
|
|
5084
|
+
}
|
|
5085
|
+
var inSentence = (label, i18n) => label.charAt(0).toLocaleLowerCase(i18n.locale) + label.slice(1);
|
|
5086
|
+
function repeatText(m, i18n = teamsI18n()) {
|
|
5087
|
+
if (m.repeat === "none") return "";
|
|
5088
|
+
const { month, day, weekday } = repeatChoices(m.start, m.zone);
|
|
5089
|
+
const rule = m.repeat === "daily" ? i18n.t("repeat.daily") : m.repeat === "weekly" ? i18n.t("repeat.weekly") : m.repeat === "yearly" ? i18n.t("repeat.yearlyOn", { date: monthDay(month, day, i18n) }) : m.monthlyBy === "weekday" && m.ordinal !== void 0 ? monthlyWeekday(m.ordinal, weekday, i18n) : i18n.t("repeat.monthlyDay", { day });
|
|
5090
|
+
return i18n.t("repeat.sentence", { rule: inSentence(rule, i18n) });
|
|
5091
|
+
}
|
|
4503
5092
|
|
|
4504
5093
|
// src/teams/app/meeting-dialog.ts
|
|
4505
5094
|
var SLOT = 30 * MINUTE_MS;
|
|
4506
|
-
var
|
|
5095
|
+
var repeatOption = (o, current) => html`<option value=${o.value} ?selected=${o.value === current}>${o.label}</option>`;
|
|
5096
|
+
function repeatFields(r) {
|
|
5097
|
+
if (r.repeat !== "monthly") return { repeat: r.repeat };
|
|
5098
|
+
return r.monthlyBy === "weekday" ? { repeat: "monthly", monthlyBy: "weekday", ordinal: r.ordinal } : { repeat: "monthly", monthlyBy: "date" };
|
|
5099
|
+
}
|
|
4507
5100
|
function toLocalInput(ms) {
|
|
4508
5101
|
const d = new Date(ms);
|
|
4509
5102
|
const p = (n) => String(n).padStart(2, "0");
|
|
@@ -4523,7 +5116,7 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4523
5116
|
description: { state: true },
|
|
4524
5117
|
startText: { state: true },
|
|
4525
5118
|
endText: { state: true },
|
|
4526
|
-
|
|
5119
|
+
repeatChoice: { state: true },
|
|
4527
5120
|
endMode: { state: true },
|
|
4528
5121
|
untilText: { state: true },
|
|
4529
5122
|
countText: { state: true },
|
|
@@ -4543,7 +5136,7 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4543
5136
|
this.description = "";
|
|
4544
5137
|
this.startText = "";
|
|
4545
5138
|
this.endText = "";
|
|
4546
|
-
this.
|
|
5139
|
+
this.repeatChoice = NO_REPEAT;
|
|
4547
5140
|
this.endMode = "never";
|
|
4548
5141
|
this.untilText = "";
|
|
4549
5142
|
this.countText = "10";
|
|
@@ -4560,7 +5153,7 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4560
5153
|
this.description = one?.description ?? m?.description ?? "";
|
|
4561
5154
|
this.startText = toLocalInput(begin);
|
|
4562
5155
|
this.endText = toLocalInput(one?.end ?? m?.end ?? begin + SLOT);
|
|
4563
|
-
this.
|
|
5156
|
+
this.repeatChoice = m ? { repeat: m.repeat, monthlyBy: m.monthlyBy ?? "date", ordinal: m.ordinal ?? 1 } : NO_REPEAT;
|
|
4564
5157
|
this.endMode = m?.count !== void 0 ? "count" : m?.until !== void 0 ? "date" : "never";
|
|
4565
5158
|
this.countText = String(m?.count ?? 10);
|
|
4566
5159
|
this.untilText = toLocalInput(m?.until ?? begin + 28 * 864e5).slice(0, 10);
|
|
@@ -4577,6 +5170,20 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4577
5170
|
this.endText = toLocalInput(end + (after - before));
|
|
4578
5171
|
this.issue = "";
|
|
4579
5172
|
}
|
|
5173
|
+
/** The zone the series is defined in: the organizer's for an existing meeting, else this device's. */
|
|
5174
|
+
zone() {
|
|
5175
|
+
return this.meeting?.zone ?? localZone();
|
|
5176
|
+
}
|
|
5177
|
+
/**
|
|
5178
|
+
* The repeat to store. A weekday ordinal that no longer fits the start date (the start moved)
|
|
5179
|
+
* becomes the first one that does.
|
|
5180
|
+
*/
|
|
5181
|
+
repeatToStore(start) {
|
|
5182
|
+
const choice = this.repeatChoice;
|
|
5183
|
+
if (choice.repeat !== "monthly" || choice.monthlyBy !== "weekday") return choice;
|
|
5184
|
+
const fits = repeatOptions(start, this.zone(), this.i18n).map((o) => o.value);
|
|
5185
|
+
return fits.includes(repeatValue(choice)) ? choice : parseRepeatValue(fits.find((v) => v.startsWith("monthly-") && v !== "monthly-date") ?? "");
|
|
5186
|
+
}
|
|
4580
5187
|
validCount() {
|
|
4581
5188
|
const n = Number(this.countText);
|
|
4582
5189
|
return Number.isInteger(n) && n >= 1 && n <= MAX_RECURRENCE_COUNT;
|
|
@@ -4590,50 +5197,54 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4590
5197
|
}
|
|
4591
5198
|
/** The end of the repeat to store: a count, the end of a day, or none (null clears an old end). */
|
|
4592
5199
|
recurrenceEnd() {
|
|
4593
|
-
if (this.repeat === "none" || this.endMode === "never")
|
|
5200
|
+
if (this.repeatChoice.repeat === "none" || this.endMode === "never")
|
|
5201
|
+
return { count: null, until: null };
|
|
4594
5202
|
return this.endMode === "count" ? { count: Number(this.countText), until: null } : { count: null, until: this.untilTime() };
|
|
4595
5203
|
}
|
|
4596
5204
|
submit(event) {
|
|
4597
5205
|
event.preventDefault();
|
|
4598
5206
|
const start = new Date(this.startText).getTime();
|
|
4599
5207
|
const end = new Date(this.endText).getTime();
|
|
4600
|
-
if (!this.meetingTitle.trim()) this.issue = "
|
|
4601
|
-
else if (!Number.isFinite(start) || !Number.isFinite(end))
|
|
4602
|
-
|
|
4603
|
-
else if (end
|
|
5208
|
+
if (!this.meetingTitle.trim()) this.issue = this.t("meeting.addTitle");
|
|
5209
|
+
else if (!Number.isFinite(start) || !Number.isFinite(end))
|
|
5210
|
+
this.issue = this.t("meeting.pickStartEnd");
|
|
5211
|
+
else if (end <= start) this.issue = this.t("meeting.endAfterStart");
|
|
5212
|
+
else if (end - start > 24 * 60 * MINUTE_MS) this.issue = this.t("meeting.maxDuration");
|
|
4604
5213
|
else if (this.occurrence) {
|
|
4605
5214
|
const one = { title: this.meetingTitle, description: this.description, start, end };
|
|
4606
|
-
if (!this.save?.(one, this.meeting?.id, this.occurrence))
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
5215
|
+
if (!this.save?.(one, this.meeting?.id, this.occurrence))
|
|
5216
|
+
this.issue = this.t("meeting.notSaved");
|
|
5217
|
+
} else if (this.repeatChoice.repeat !== "none" && this.endMode === "count" && !this.validCount())
|
|
5218
|
+
this.issue = this.t("meeting.countRange", { max: MAX_RECURRENCE_COUNT });
|
|
5219
|
+
else if (this.repeatChoice.repeat !== "none" && this.endMode === "date" && !this.validUntil(start))
|
|
5220
|
+
this.issue = this.t("meeting.untilBeforeStart");
|
|
4611
5221
|
else if (!this.save?.(
|
|
4612
5222
|
{
|
|
4613
5223
|
title: this.meetingTitle,
|
|
4614
5224
|
description: this.description,
|
|
4615
5225
|
start,
|
|
4616
5226
|
end,
|
|
4617
|
-
|
|
5227
|
+
...repeatFields(this.repeatToStore(start)),
|
|
4618
5228
|
...this.recurrenceEnd(),
|
|
4619
5229
|
attendeeIds: this.channelId ? [] : this.attendees,
|
|
4620
5230
|
...this.channelId ? { channelId: this.channelId } : {}
|
|
4621
5231
|
},
|
|
4622
5232
|
this.meeting?.id
|
|
4623
5233
|
))
|
|
4624
|
-
this.issue =
|
|
5234
|
+
this.issue = this.t("meeting.notSaved");
|
|
4625
5235
|
}
|
|
4626
5236
|
render() {
|
|
4627
5237
|
const editing = this.meeting !== null;
|
|
4628
5238
|
const single = this.occurrence !== 0;
|
|
5239
|
+
const current = repeatValue(this.repeatToStore(new Date(this.startText).getTime()));
|
|
4629
5240
|
return this.frame(
|
|
4630
|
-
single ? "
|
|
5241
|
+
this.t(single ? "meeting.editEvent" : editing ? "meeting.edit" : "calendar.newMeeting"),
|
|
4631
5242
|
html`<form @submit=${this.submit}>
|
|
4632
5243
|
<label
|
|
4633
|
-
|
|
5244
|
+
>${this.t("meeting.title")}<input
|
|
4634
5245
|
maxlength=${MAX_MEETING_TITLE}
|
|
4635
5246
|
.value=${this.meetingTitle}
|
|
4636
|
-
placeholder
|
|
5247
|
+
placeholder=${this.t("meeting.titlePlaceholder")}
|
|
4637
5248
|
@input=${(e) => {
|
|
4638
5249
|
this.meetingTitle = e.target.value;
|
|
4639
5250
|
this.issue = "";
|
|
@@ -4641,13 +5252,13 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4641
5252
|
/></label>
|
|
4642
5253
|
<div class="times">
|
|
4643
5254
|
<label
|
|
4644
|
-
|
|
5255
|
+
>${this.t("meeting.start")}<input
|
|
4645
5256
|
type="datetime-local"
|
|
4646
5257
|
.value=${this.startText}
|
|
4647
5258
|
@change=${(e) => this.moveStart(e.target.value)}
|
|
4648
5259
|
/></label>
|
|
4649
5260
|
<label
|
|
4650
|
-
|
|
5261
|
+
>${this.t("meeting.end")}<input
|
|
4651
5262
|
type="datetime-local"
|
|
4652
5263
|
.value=${this.endText}
|
|
4653
5264
|
@change=${(e) => {
|
|
@@ -4656,29 +5267,30 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4656
5267
|
}}
|
|
4657
5268
|
/></label>
|
|
4658
5269
|
</div>
|
|
4659
|
-
${single ? html`<small
|
|
5270
|
+
${single ? html`<small>${this.t("meeting.onlyThisEvent")}</small>` : html`
|
|
4660
5271
|
<label
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
@change=${(e) => this.repeat = e.target.value}
|
|
5272
|
+
>${this.t("meeting.repeat")}<select
|
|
5273
|
+
@change=${(e) => this.repeatChoice = parseRepeatValue(e.target.value)}
|
|
4664
5274
|
>
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
5275
|
+
${repeatOptions(
|
|
5276
|
+
new Date(this.startText).getTime() || Date.now(),
|
|
5277
|
+
this.zone(),
|
|
5278
|
+
this.i18n
|
|
5279
|
+
).map((o) => repeatOption(o, current))}
|
|
4668
5280
|
</select></label
|
|
4669
5281
|
>
|
|
4670
|
-
${this.repeat === "none" ? nothing : html`<label
|
|
4671
|
-
|
|
5282
|
+
${this.repeatChoice.repeat === "none" ? nothing : html`<label
|
|
5283
|
+
>${this.t("meeting.ends")}<select
|
|
4672
5284
|
.value=${this.endMode}
|
|
4673
5285
|
@change=${(e) => this.endMode = e.target.value}
|
|
4674
5286
|
>
|
|
4675
|
-
<option value="never"
|
|
4676
|
-
<option value="date"
|
|
4677
|
-
<option value="count"
|
|
5287
|
+
<option value="never">${this.t("meeting.endsNever")}</option>
|
|
5288
|
+
<option value="date">${this.t("meeting.endsDate")}</option>
|
|
5289
|
+
<option value="count">${this.t("meeting.endsCount")}</option>
|
|
4678
5290
|
</select></label
|
|
4679
5291
|
>
|
|
4680
5292
|
${this.endMode === "date" ? html`<label
|
|
4681
|
-
|
|
5293
|
+
>${this.t("meeting.endDate")}<input
|
|
4682
5294
|
type="date"
|
|
4683
5295
|
.value=${this.untilText}
|
|
4684
5296
|
@change=${(e) => {
|
|
@@ -4687,7 +5299,7 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4687
5299
|
}}
|
|
4688
5300
|
/></label>` : nothing}
|
|
4689
5301
|
${this.endMode === "count" ? html`<label
|
|
4690
|
-
|
|
5302
|
+
>${this.t("meeting.numberOfEvents")}<input
|
|
4691
5303
|
type="number"
|
|
4692
5304
|
min="1"
|
|
4693
5305
|
max=${MAX_RECURRENCE_COUNT}
|
|
@@ -4698,22 +5310,19 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4698
5310
|
}}
|
|
4699
5311
|
/></label>` : nothing}`}
|
|
4700
5312
|
<label
|
|
4701
|
-
|
|
5313
|
+
>${this.t("meeting.channelOptional")}<select
|
|
4702
5314
|
?disabled=${editing}
|
|
4703
5315
|
.value=${this.channelId}
|
|
4704
5316
|
@change=${(e) => this.channelId = e.target.value}
|
|
4705
5317
|
>
|
|
4706
|
-
<option value=""
|
|
5318
|
+
<option value="">${this.t("meeting.noChannel")}</option>
|
|
4707
5319
|
${this.channels.map((c) => html`<option value=${c.id}># ${c.name}</option>`)}
|
|
4708
5320
|
</select></label
|
|
4709
5321
|
>
|
|
4710
|
-
${this.channelId ? html`<small
|
|
4711
|
-
|
|
4712
|
-
everyone's calendar.</small
|
|
4713
|
-
>` : html`<div class="field">
|
|
4714
|
-
Attendees
|
|
5322
|
+
${this.channelId ? html`<small>${this.t("meeting.channelNote")}</small>` : html`<div class="field">
|
|
5323
|
+
${this.t("meeting.attendees")}
|
|
4715
5324
|
<office-ui-people-picker
|
|
4716
|
-
label
|
|
5325
|
+
label=${this.t("meeting.attendees")}
|
|
4717
5326
|
.contacts=${this.contacts}
|
|
4718
5327
|
.selected=${this.attendees}
|
|
4719
5328
|
@office-people-change=${(e) => this.attendees = e.detail.selected}
|
|
@@ -4721,22 +5330,25 @@ var TeamsMeetingDialog = class extends TeamsDialog {
|
|
|
4721
5330
|
</div>`}
|
|
4722
5331
|
`}
|
|
4723
5332
|
<label
|
|
4724
|
-
|
|
5333
|
+
>${this.t("meeting.detailsOptional")}<textarea
|
|
4725
5334
|
maxlength=${MAX_MEETING_DESCRIPTION}
|
|
4726
5335
|
.value=${this.description}
|
|
4727
|
-
placeholder
|
|
5336
|
+
placeholder=${this.t("meeting.detailsPlaceholder")}
|
|
4728
5337
|
@input=${(e) => this.description = e.target.value}
|
|
4729
5338
|
></textarea>
|
|
4730
5339
|
</label>
|
|
4731
|
-
<small
|
|
4732
|
-
>Times are shown in your time zone. The organizer's zone keeps repeats on schedule.</small
|
|
4733
|
-
>
|
|
5340
|
+
<small>${this.t("meeting.zoneNote")}</small>
|
|
4734
5341
|
${this.issue ? html`<p class="issue" role="alert">${this.issue}</p>` : nothing}
|
|
4735
5342
|
<footer>
|
|
4736
|
-
<button type="button" @click=${this.requestClose}
|
|
4737
|
-
<button type="submit" class="primary"
|
|
5343
|
+
<button type="button" @click=${this.requestClose}>${this.t("common.cancel")}</button>
|
|
5344
|
+
<button type="submit" class="primary">
|
|
5345
|
+
${this.t(editing ? "common.save" : "meeting.send")}
|
|
5346
|
+
</button>
|
|
4738
5347
|
</footer>
|
|
4739
|
-
</form
|
|
5348
|
+
</form>`,
|
|
5349
|
+
this.t(
|
|
5350
|
+
single ? "dialog.closeEditEvent" : editing ? "dialog.closeEditMeeting" : "dialog.closeNewMeeting"
|
|
5351
|
+
)
|
|
4740
5352
|
);
|
|
4741
5353
|
}
|
|
4742
5354
|
};
|
|
@@ -4749,7 +5361,6 @@ function defineTeamsMeetingDialog(registry = globalThis.customElements) {
|
|
|
4749
5361
|
var meeting_details_default = ".when {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n color: var(--office-foreground);\n font-weight: var(--office-font-weight-bold);\n}\nh3 {\n margin: 0 0 var(--office-space-1);\n font-size: var(--office-font-size);\n}\n.people ul {\n margin: 0;\n padding-inline-start: var(--office-space-5);\n}\n.description {\n color: var(--office-foreground);\n white-space: pre-wrap;\n}\n.scope {\n display: grid;\n gap: var(--office-space-3);\n}\n.scope fieldset {\n display: grid;\n gap: var(--office-space-2);\n margin: 0;\n padding: var(--office-space-3);\n border: var(--office-border-width) solid var(--office-teams-divider);\n border-radius: var(--office-radius-md);\n}\n.scope label {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n}\nfooter[hidden] {\n display: none;\n}\n";
|
|
4750
5362
|
|
|
4751
5363
|
// src/teams/app/meeting-details.ts
|
|
4752
|
-
var REPEAT_TEXT = { none: "", daily: "Repeats every day", weekly: "Repeats every week" };
|
|
4753
5364
|
var TeamsMeetingDetails = class extends TeamsDialog {
|
|
4754
5365
|
static styles = dialogStyles(meeting_details_default);
|
|
4755
5366
|
static properties = {
|
|
@@ -4799,17 +5410,17 @@ var TeamsMeetingDetails = class extends TeamsDialog {
|
|
|
4799
5410
|
this.pending = null;
|
|
4800
5411
|
}
|
|
4801
5412
|
endText(m) {
|
|
4802
|
-
const date = (ms) => new Intl.DateTimeFormat(
|
|
5413
|
+
const date = (ms) => new Intl.DateTimeFormat(this.i18n.intl, {
|
|
4803
5414
|
dateStyle: "medium",
|
|
4804
5415
|
...this.zone ? { timeZone: this.zone } : {}
|
|
4805
5416
|
}).format(ms);
|
|
4806
|
-
if (m.count !== void 0) return
|
|
4807
|
-
return m.until !== void 0 ?
|
|
5417
|
+
if (m.count !== void 0) return this.tn("details.times", m.count);
|
|
5418
|
+
return m.until !== void 0 ? this.t("details.until", { date: date(m.until) }) : "";
|
|
4808
5419
|
}
|
|
4809
5420
|
scopeChoice(action) {
|
|
4810
5421
|
const options = [
|
|
4811
|
-
["occurrence", action === "edit" ? "
|
|
4812
|
-
["series",
|
|
5422
|
+
["occurrence", this.t(action === "edit" ? "details.thisEvent" : "details.thisEventOnly")],
|
|
5423
|
+
["series", this.t("details.allEvents")]
|
|
4813
5424
|
];
|
|
4814
5425
|
return html`<form
|
|
4815
5426
|
class="scope"
|
|
@@ -4820,7 +5431,7 @@ var TeamsMeetingDetails = class extends TeamsDialog {
|
|
|
4820
5431
|
>
|
|
4821
5432
|
<fieldset>
|
|
4822
5433
|
<legend>
|
|
4823
|
-
${action === "edit" ? "
|
|
5434
|
+
${this.t(action === "edit" ? "details.editRecurring" : "details.cancelRecurring")}
|
|
4824
5435
|
</legend>
|
|
4825
5436
|
${options.map(
|
|
4826
5437
|
([value, label]) => html`<label
|
|
@@ -4836,16 +5447,19 @@ var TeamsMeetingDetails = class extends TeamsDialog {
|
|
|
4836
5447
|
)}
|
|
4837
5448
|
</fieldset>
|
|
4838
5449
|
<footer>
|
|
4839
|
-
<button type="button" @click=${() => this.pending = null}>
|
|
5450
|
+
<button type="button" @click=${() => this.pending = null}>
|
|
5451
|
+
${this.t("common.back")}
|
|
5452
|
+
</button>
|
|
4840
5453
|
<button type="submit" class=${action === "cancel" ? "danger" : "primary"}>
|
|
4841
|
-
${action === "edit" ? "
|
|
5454
|
+
${this.t(action === "edit" ? "details.continue" : "details.cancelMeeting")}
|
|
4842
5455
|
</button>
|
|
4843
5456
|
</footer>
|
|
4844
5457
|
</form>`;
|
|
4845
5458
|
}
|
|
4846
5459
|
render() {
|
|
4847
5460
|
const m = this.meeting;
|
|
4848
|
-
if (!m)
|
|
5461
|
+
if (!m)
|
|
5462
|
+
return this.frame(this.t("details.meeting"), html``, this.t("dialog.closeMeetingDetails"));
|
|
4849
5463
|
const occurrence = occurrenceAt(m, this.occurrenceStart || m.start);
|
|
4850
5464
|
const start = occurrence?.start ?? (this.occurrenceStart || m.start);
|
|
4851
5465
|
const end = occurrence?.end ?? start + (m.end - m.start);
|
|
@@ -4854,17 +5468,18 @@ var TeamsMeetingDetails = class extends TeamsDialog {
|
|
|
4854
5468
|
return this.frame(
|
|
4855
5469
|
occurrence?.title ?? m.title,
|
|
4856
5470
|
html`<div class="body">
|
|
4857
|
-
<p class="when">${icon("calendar")} ${formatWhen(start, end)}</p>
|
|
4858
|
-
${m.repeat !== "none" ? html`<p>${
|
|
4859
|
-
${m.zone !== this.zone ? html`<p
|
|
4860
|
-
<p>
|
|
5471
|
+
<p class="when">${icon("calendar")} ${formatWhen(start, end, this.locale)}</p>
|
|
5472
|
+
${m.repeat !== "none" ? html`<p>${repeatText(m, this.i18n)}${this.endText(m)}</p>` : nothing}
|
|
5473
|
+
${m.zone !== this.zone ? html`<p>${this.t("details.organizerZone", { zone: m.zone.replaceAll("_", " ") })}</p>` : nothing}
|
|
5474
|
+
<p>
|
|
5475
|
+
${m.mine ? this.t("details.organizedByYou") : this.t("details.organizedBy", { name: m.organizerName })}
|
|
5476
|
+
</p>
|
|
4861
5477
|
${m.channelId ? html`<p>
|
|
4862
|
-
|
|
4863
|
-
join.
|
|
5478
|
+
${this.t("details.channelMeeting", { channel: this.channelName || this.t("details.aChannel") })}
|
|
4864
5479
|
</p>` : html`<div class="people">
|
|
4865
|
-
<h3
|
|
5480
|
+
<h3>${this.t("details.attendees", { count: m.attendees.length + 1 })}</h3>
|
|
4866
5481
|
<ul>
|
|
4867
|
-
<li>${m.organizerName}
|
|
5482
|
+
<li>${this.t("details.organizerItem", { name: m.organizerName })}</li>
|
|
4868
5483
|
${m.attendees.map((a) => html`<li>${a.name}</li>`)}
|
|
4869
5484
|
</ul>
|
|
4870
5485
|
</div>`}
|
|
@@ -4872,19 +5487,23 @@ var TeamsMeetingDetails = class extends TeamsDialog {
|
|
|
4872
5487
|
${this.pending ? this.scopeChoice(this.pending) : nothing}
|
|
4873
5488
|
<footer ?hidden=${this.pending !== null}>
|
|
4874
5489
|
<button type="button" class="primary" @click=${() => this.emit("teams-meeting-join")}>
|
|
4875
|
-
${m.live ? "
|
|
5490
|
+
${this.t(m.live ? "call.joinNow" : "call.join")}
|
|
4876
5491
|
</button>
|
|
4877
5492
|
${hasChat ? html`<button type="button" @click=${() => this.emit("teams-meeting-chat")}>
|
|
4878
|
-
|
|
5493
|
+
${this.t("details.meetingChat")}
|
|
4879
5494
|
</button>` : nothing}
|
|
4880
|
-
<button type="button" @click=${() => this.emit("teams-meeting-ics")}>
|
|
4881
|
-
|
|
5495
|
+
<button type="button" @click=${() => this.emit("teams-meeting-ics")}>
|
|
5496
|
+
${this.t("details.exportIcs")}
|
|
5497
|
+
</button>
|
|
5498
|
+
${m.mine ? html`<button type="button" @click=${() => this.change("edit")}>
|
|
5499
|
+
${this.t("common.edit")}
|
|
5500
|
+
</button>
|
|
4882
5501
|
<button type="button" class="danger" @click=${() => this.change("cancel")}>
|
|
4883
|
-
|
|
5502
|
+
${this.t("details.cancelMeeting")}
|
|
4884
5503
|
</button>` : nothing}
|
|
4885
5504
|
</footer>
|
|
4886
5505
|
</div>`,
|
|
4887
|
-
"
|
|
5506
|
+
this.t("dialog.closeMeetingDetails")
|
|
4888
5507
|
);
|
|
4889
5508
|
}
|
|
4890
5509
|
};
|
|
@@ -4892,15 +5511,25 @@ function defineTeamsMeetingDetails(registry = globalThis.customElements) {
|
|
|
4892
5511
|
if (registry && !registry.get("teams-meeting-details"))
|
|
4893
5512
|
registry.define("teams-meeting-details", TeamsMeetingDetails);
|
|
4894
5513
|
}
|
|
4895
|
-
|
|
5514
|
+
var PRESENCE_KEY2 = {
|
|
5515
|
+
available: "presence.available",
|
|
5516
|
+
busy: "presence.busy",
|
|
5517
|
+
dnd: "presence.dnd",
|
|
5518
|
+
brb: "presence.brb",
|
|
5519
|
+
away: "presence.away",
|
|
5520
|
+
offline: "presence.offline"
|
|
5521
|
+
};
|
|
5522
|
+
function chatHeader(chat, on, i18n = teamsI18n()) {
|
|
5523
|
+
const { t } = i18n;
|
|
4896
5524
|
const other = chat.kind === "direct" ? chat.members.find((m) => !m.self) : void 0;
|
|
4897
5525
|
const online = chat.members.filter((m) => !m.self && m.availability !== "offline").length;
|
|
5526
|
+
const topic = chat.kind === "direct" ? other ? t(PRESENCE_KEY2[other.availability]) : "" : online ? t("chat.peopleOnline", { count: chat.members.length, online }) : i18n.tn("chat.peopleCount", chat.members.length);
|
|
4898
5527
|
return html`<header class="channel-head chat-head">
|
|
4899
5528
|
<button
|
|
4900
5529
|
type="button"
|
|
4901
5530
|
class="back"
|
|
4902
|
-
aria-label
|
|
4903
|
-
title
|
|
5531
|
+
aria-label=${t("chat.backToChats")}
|
|
5532
|
+
title=${t("chat.backToChats")}
|
|
4904
5533
|
@click=${on.back}
|
|
4905
5534
|
>
|
|
4906
5535
|
${icon("back")}
|
|
@@ -4913,10 +5542,8 @@ function chatHeader(chat, on) {
|
|
|
4913
5542
|
>${icon(chat.meetingId ? "calendar" : "users")}</span
|
|
4914
5543
|
>`}
|
|
4915
5544
|
<h1>${chat.title}</h1>
|
|
4916
|
-
<span class="topic"
|
|
4917
|
-
|
|
4918
|
-
>
|
|
4919
|
-
<div class="people" aria-label="People in this chat">
|
|
5545
|
+
<span class="topic">${topic}</span>
|
|
5546
|
+
<div class="people" aria-label=${t("chat.peopleInChat")}>
|
|
4920
5547
|
${chat.members.slice(0, 5).map(
|
|
4921
5548
|
(m) => html`<office-ui-avatar
|
|
4922
5549
|
size="sm"
|
|
@@ -4927,9 +5554,11 @@ function chatHeader(chat, on) {
|
|
|
4927
5554
|
)}
|
|
4928
5555
|
${chat.members.length > 5 ? html`<span class="more">+${chat.members.length - 5}</span>` : nothing}
|
|
4929
5556
|
</div>
|
|
4930
|
-
<button type="button" class="chat-people" @click=${on.people}
|
|
5557
|
+
<button type="button" class="chat-people" @click=${on.people}>
|
|
5558
|
+
${icon("users")} ${t("chat.people")}
|
|
5559
|
+
</button>
|
|
4931
5560
|
<button type="button" class="meet" @click=${on.call}>
|
|
4932
|
-
${chat.live ? "
|
|
5561
|
+
${t(chat.live ? "call.joinCall" : "chat.call")}
|
|
4933
5562
|
</button>
|
|
4934
5563
|
</header>`;
|
|
4935
5564
|
}
|
|
@@ -4968,22 +5597,22 @@ var LOCAL_THEME = THEME_CSS.replaceAll(
|
|
|
4968
5597
|
':host([data-office-theme="dark"])'
|
|
4969
5598
|
).replaceAll(':root:not([data-office-theme="light"])', ':host([data-office-theme="system"])').replaceAll(":root", ":host([data-office-theme])");
|
|
4970
5599
|
var RAIL = [
|
|
4971
|
-
{ id: "activity", label: "
|
|
4972
|
-
{ id: "chat", label: "
|
|
4973
|
-
{ id: "teams", label: "
|
|
4974
|
-
{ id: "calendar", label: "
|
|
4975
|
-
{ id: "calls", label: "
|
|
4976
|
-
{ id: "files", label: "
|
|
5600
|
+
{ id: "activity", label: "rail.activity", icon: "bell" },
|
|
5601
|
+
{ id: "chat", label: "rail.chat", icon: "message" },
|
|
5602
|
+
{ id: "teams", label: "rail.teams", icon: "users" },
|
|
5603
|
+
{ id: "calendar", label: "rail.calendar", icon: "calendar" },
|
|
5604
|
+
{ id: "calls", label: "rail.calls", icon: "phone", secondary: true },
|
|
5605
|
+
{ id: "files", label: "rail.files", icon: "folder", secondary: true },
|
|
4977
5606
|
{
|
|
4978
5607
|
id: "followed",
|
|
4979
|
-
label: "
|
|
4980
|
-
shortLabel: "
|
|
5608
|
+
label: "rail.followed",
|
|
5609
|
+
shortLabel: "rail.threads",
|
|
4981
5610
|
icon: "chat",
|
|
4982
5611
|
secondary: true
|
|
4983
5612
|
},
|
|
4984
|
-
{ id: "drafts", label: "
|
|
5613
|
+
{ id: "drafts", label: "rail.drafts", icon: "chat", secondary: true }
|
|
4985
5614
|
];
|
|
4986
|
-
var TeamsApp = class extends
|
|
5615
|
+
var TeamsApp = class extends TeamsLitElement {
|
|
4987
5616
|
static styles = [unsafeCSS(LOCAL_THEME), unsafeCSS(teams_app_default)];
|
|
4988
5617
|
static properties = {
|
|
4989
5618
|
workspaceId: { type: String, attribute: "workspace-id" },
|
|
@@ -5016,11 +5645,19 @@ var TeamsApp = class extends LitElement {
|
|
|
5016
5645
|
theme: { state: true },
|
|
5017
5646
|
fileOpenPreference: { state: true },
|
|
5018
5647
|
chatDensity: { state: true },
|
|
5019
|
-
showAppNames: { state: true }
|
|
5648
|
+
showAppNames: { state: true },
|
|
5649
|
+
authRevision: { state: true }
|
|
5020
5650
|
};
|
|
5651
|
+
/** Sign-in for servers that require accounts; a server without them never gates the app. */
|
|
5652
|
+
signIn = new SignInFlow({
|
|
5653
|
+
changed: () => this.authRevision++,
|
|
5654
|
+
emit: (name, detail) => this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true })),
|
|
5655
|
+
i18n: () => this.i18n
|
|
5656
|
+
});
|
|
5657
|
+
authKey = "";
|
|
5021
5658
|
teams = new TeamsController(
|
|
5022
5659
|
this,
|
|
5023
|
-
(text) => this.notify(text),
|
|
5660
|
+
(text) => this.notify(localizeCoreText(text, this.i18n)),
|
|
5024
5661
|
(item) => this.announce(item)
|
|
5025
5662
|
);
|
|
5026
5663
|
toastTimer;
|
|
@@ -5072,6 +5709,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5072
5709
|
this.fileOpenPreference = "teams";
|
|
5073
5710
|
this.chatDensity = "comfy";
|
|
5074
5711
|
this.showAppNames = true;
|
|
5712
|
+
this.authRevision = 0;
|
|
5075
5713
|
}
|
|
5076
5714
|
/** The core client behind this element, for hosts that want the raw actions. */
|
|
5077
5715
|
get client() {
|
|
@@ -5094,8 +5732,10 @@ var TeamsApp = class extends LitElement {
|
|
|
5094
5732
|
defineTeamsChatPeopleDialog();
|
|
5095
5733
|
defineTeamsMeetingDialog();
|
|
5096
5734
|
defineTeamsMeetingDetails();
|
|
5735
|
+
defineTeamsSignIn();
|
|
5097
5736
|
this.stopActivity = watchActivity(this.ownerDocument, () => this.teams.client?.noteActivity());
|
|
5098
5737
|
super.connectedCallback();
|
|
5738
|
+
if (this.signIn.phase === "checking") this.authRevision++;
|
|
5099
5739
|
}
|
|
5100
5740
|
// ---- lifecycle --------------------------------------------------------------------------
|
|
5101
5741
|
resolveConfig() {
|
|
@@ -5110,14 +5750,13 @@ var TeamsApp = class extends LitElement {
|
|
|
5110
5750
|
}
|
|
5111
5751
|
willUpdate(changed) {
|
|
5112
5752
|
if (this.popoutRequested) return;
|
|
5113
|
-
const
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
].some((k) => changed.has(k));
|
|
5753
|
+
const base = this.resolveConfig();
|
|
5754
|
+
const waiting = this.signIn.gate(base);
|
|
5755
|
+
const authKey = `${waiting}|${this.signIn.session?.token ?? ""}`;
|
|
5756
|
+
const restart = ["workspaceId", "userName", "userId", "serverConfig", "config", "identity"].some(
|
|
5757
|
+
(k) => changed.has(k)
|
|
5758
|
+
) || changed.has("authRevision") && authKey !== this.authKey;
|
|
5759
|
+
this.authKey = authKey;
|
|
5121
5760
|
if (!restart && this.teams.client) return;
|
|
5122
5761
|
this.preview = null;
|
|
5123
5762
|
this.tab = "posts";
|
|
@@ -5127,8 +5766,14 @@ var TeamsApp = class extends LitElement {
|
|
|
5127
5766
|
this.meetingForm = this.meetingDetails = null;
|
|
5128
5767
|
this.settingsOpen = false;
|
|
5129
5768
|
this.openRequest++;
|
|
5130
|
-
|
|
5131
|
-
|
|
5769
|
+
if (waiting) return this.teams.stop();
|
|
5770
|
+
const account = this.signIn.session;
|
|
5771
|
+
const remembered = this.identity ?? loadIdentity();
|
|
5772
|
+
const named = account ? {
|
|
5773
|
+
id: account.userId,
|
|
5774
|
+
name: this.userName || (remembered?.id === account.userId ? remembered.name : account.userId)
|
|
5775
|
+
} : this.userName ? { id: this.userId || loadIdentity()?.id || crypto.randomUUID(), name: this.userName } : remembered;
|
|
5776
|
+
if (this.userName && !this.userId && !account) saveIdentity(named);
|
|
5132
5777
|
if (!named) return this.teams.stop();
|
|
5133
5778
|
const workspaceId = /^[\w-]{1,100}$/u.test(this.workspaceId) ? this.workspaceId : "demo";
|
|
5134
5779
|
this.themeStorageKey = `teams:theme:${encodeURIComponent(workspaceId)}:${encodeURIComponent(named.id)}`;
|
|
@@ -5142,7 +5787,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5142
5787
|
this.teams.start({
|
|
5143
5788
|
workspaceId,
|
|
5144
5789
|
user: named,
|
|
5145
|
-
config: this.
|
|
5790
|
+
config: this.signIn.apply(base),
|
|
5146
5791
|
storage: safeStorage,
|
|
5147
5792
|
...this.uploadFile ? { uploadFile: this.uploadFile } : {}
|
|
5148
5793
|
});
|
|
@@ -5153,6 +5798,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5153
5798
|
updated() {
|
|
5154
5799
|
this.setAttribute("data-chat-density", this.chatDensity);
|
|
5155
5800
|
const state = this.teams.state;
|
|
5801
|
+
this.signIn.watchConnection(state?.status === "connected", this.resolveConfig());
|
|
5156
5802
|
if (state?.channels.some((c) => c.id === state.selectedChannelId))
|
|
5157
5803
|
this.lastChannelId = state.selectedChannelId;
|
|
5158
5804
|
if (state?.thread && document.visibilityState === "visible" && this.renderRoot.querySelector(".thread-pane"))
|
|
@@ -5223,12 +5869,12 @@ var TeamsApp = class extends LitElement {
|
|
|
5223
5869
|
return;
|
|
5224
5870
|
}
|
|
5225
5871
|
popout?.close();
|
|
5226
|
-
this.notify(
|
|
5872
|
+
this.notify(this.t("app.allowPopups"));
|
|
5227
5873
|
return;
|
|
5228
5874
|
}
|
|
5229
5875
|
popout?.close();
|
|
5230
5876
|
if (url) this.preview = detail;
|
|
5231
|
-
else this.notify("
|
|
5877
|
+
else this.notify(this.t("app.nameOnly"));
|
|
5232
5878
|
}
|
|
5233
5879
|
/** Preview a host-provided website or file without changing shared conversation state. */
|
|
5234
5880
|
previewContent(detail) {
|
|
@@ -5258,6 +5904,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5258
5904
|
clearTimeout(this.highlightTimer);
|
|
5259
5905
|
this.stopActivity?.();
|
|
5260
5906
|
this.stopActivity = void 0;
|
|
5907
|
+
this.signIn.dispose();
|
|
5261
5908
|
super.disconnectedCallback();
|
|
5262
5909
|
}
|
|
5263
5910
|
createChannel() {
|
|
@@ -5325,7 +5972,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5325
5972
|
this.settingsOpen = false;
|
|
5326
5973
|
await this.updateComplete;
|
|
5327
5974
|
if (!this.isConnected || this.settingsOpen) return;
|
|
5328
|
-
this.renderRoot.querySelector(
|
|
5975
|
+
this.renderRoot.querySelector("office-ui-menu-button.settings-menu")?.shadowRoot?.querySelector("button")?.focus();
|
|
5329
5976
|
}
|
|
5330
5977
|
applyTheme() {
|
|
5331
5978
|
if (this.theme === "system") this.removeAttribute("data-office-theme");
|
|
@@ -5344,7 +5991,8 @@ var TeamsApp = class extends LitElement {
|
|
|
5344
5991
|
.detail=${this.popout}
|
|
5345
5992
|
@teams-preview-close=${() => globalThis.close()}
|
|
5346
5993
|
></teams-content-preview>
|
|
5347
|
-
</div>` : html`<p role="alert"
|
|
5994
|
+
</div>` : html`<p role="alert">${this.t("app.invalidPreview")}</p>`;
|
|
5995
|
+
if (this.signIn.phase !== "open") return this.signInScreen();
|
|
5348
5996
|
const s = this.teams.state;
|
|
5349
5997
|
if (!s) return this.welcome();
|
|
5350
5998
|
return html`
|
|
@@ -5354,14 +6002,14 @@ var TeamsApp = class extends LitElement {
|
|
|
5354
6002
|
@office-chat-open-tab=${(event) => {
|
|
5355
6003
|
if (this.teams.state?.tabs.some((entry) => entry.id === event.detail.tabId))
|
|
5356
6004
|
this.selectTab(event.detail.tabId);
|
|
5357
|
-
else this.notify(
|
|
6005
|
+
else this.notify(this.t("app.tabGone"));
|
|
5358
6006
|
}}
|
|
5359
6007
|
>
|
|
5360
6008
|
${this.topbar(s)}
|
|
5361
6009
|
<div class="body">
|
|
5362
6010
|
<office-ui-app-rail
|
|
5363
6011
|
.hideLabels=${!this.showAppNames}
|
|
5364
|
-
.items=${RAIL.map((i) => ({ ...i, ...i.id === "calls" && s.channels.some((c) => c.live) ? { badge: s.channels.filter((c) => c.live).length } : {}, ...i.id === "activity" && s.activityUnread ? { badge: s.activityUnread } : {}, ...i.id === "chat" && s.chats.some((c) => c.unread) ? { badge: s.chats.reduce((n, c) => n + c.unread, 0) } : {} }))}
|
|
6012
|
+
.items=${RAIL.map((i) => ({ ...i, label: this.t(i.label), ..."shortLabel" in i ? { shortLabel: this.t(i.shortLabel) } : {}, ...i.id === "calls" && s.channels.some((c) => c.live) ? { badge: s.channels.filter((c) => c.live).length } : {}, ...i.id === "activity" && s.activityUnread ? { badge: s.activityUnread } : {}, ...i.id === "chat" && s.chats.some((c) => c.unread) ? { badge: s.chats.reduce((n, c) => n + c.unread, 0) } : {} }))}
|
|
5365
6013
|
selected=${this.rail}
|
|
5366
6014
|
@office-rail-select=${(e) => {
|
|
5367
6015
|
if (!this.closePreview()) return;
|
|
@@ -5465,6 +6113,18 @@ var TeamsApp = class extends LitElement {
|
|
|
5465
6113
|
</div>
|
|
5466
6114
|
`;
|
|
5467
6115
|
}
|
|
6116
|
+
signInScreen() {
|
|
6117
|
+
const flow = this.signIn;
|
|
6118
|
+
return html`<teams-sign-in
|
|
6119
|
+
.userId=${flow.userId}
|
|
6120
|
+
.notice=${flow.notice}
|
|
6121
|
+
.error=${flow.error}
|
|
6122
|
+
.retryAfter=${flow.retryAfterSec}
|
|
6123
|
+
?busy=${flow.busy}
|
|
6124
|
+
?checking=${flow.phase === "checking"}
|
|
6125
|
+
@teams-sign-in-submit=${(event) => void flow.submit(this.resolveConfig(), event.detail.userId, event.detail.credential)}
|
|
6126
|
+
></teams-sign-in>`;
|
|
6127
|
+
}
|
|
5468
6128
|
welcome() {
|
|
5469
6129
|
return html`
|
|
5470
6130
|
<div class="welcome">
|
|
@@ -5479,17 +6139,17 @@ var TeamsApp = class extends LitElement {
|
|
|
5479
6139
|
}}
|
|
5480
6140
|
>
|
|
5481
6141
|
<span class="logo">T</span>
|
|
5482
|
-
<h1
|
|
5483
|
-
<p
|
|
6142
|
+
<h1>${this.t("welcome.title")}</h1>
|
|
6143
|
+
<p>${this.t("welcome.pickName")}</p>
|
|
5484
6144
|
<input
|
|
5485
6145
|
name="name"
|
|
5486
|
-
placeholder
|
|
5487
|
-
aria-label
|
|
6146
|
+
placeholder=${this.t("welcome.yourName")}
|
|
6147
|
+
aria-label=${this.t("welcome.yourName")}
|
|
5488
6148
|
maxlength="40"
|
|
5489
6149
|
autocomplete="name"
|
|
5490
6150
|
required
|
|
5491
6151
|
/>
|
|
5492
|
-
<button type="submit"
|
|
6152
|
+
<button type="submit">${this.t("welcome.continue")}</button>
|
|
5493
6153
|
</form>
|
|
5494
6154
|
</div>
|
|
5495
6155
|
`;
|
|
@@ -5497,17 +6157,17 @@ var TeamsApp = class extends LitElement {
|
|
|
5497
6157
|
topbar(s) {
|
|
5498
6158
|
return html`
|
|
5499
6159
|
<header class="topbar">
|
|
5500
|
-
<div class="brand"><span class="logo">T</span><span
|
|
6160
|
+
<div class="brand"><span class="logo">T</span><span>${this.t("rail.teams")}</span></div>
|
|
5501
6161
|
<div class="search">
|
|
5502
6162
|
<input
|
|
5503
6163
|
type="search"
|
|
5504
|
-
placeholder
|
|
5505
|
-
aria-label
|
|
6164
|
+
placeholder=${this.t("search.messages")}
|
|
6165
|
+
aria-label=${this.t("search.messages")}
|
|
5506
6166
|
.value=${s.searchQuery}
|
|
5507
6167
|
@input=${(e) => this.teams.client?.search(e.target.value)}
|
|
5508
6168
|
/>
|
|
5509
|
-
${s.searchQuery ? html`<ul class="results" role="listbox" aria-label
|
|
5510
|
-
${s.searchResults.length === 0 ? html`<li class="none"
|
|
6169
|
+
${s.searchQuery ? html`<ul class="results" role="listbox" aria-label=${this.t("search.results")}>
|
|
6170
|
+
${s.searchResults.length === 0 ? html`<li class="none">${this.t("search.none")}</li>` : s.searchResults.map(
|
|
5511
6171
|
(h) => html`<li>
|
|
5512
6172
|
<button
|
|
5513
6173
|
type="button"
|
|
@@ -5520,8 +6180,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5520
6180
|
>
|
|
5521
6181
|
<strong>${h.message.authorName}</strong>
|
|
5522
6182
|
<span class="in"
|
|
5523
|
-
|
|
5524
|
-
${s.chats.some((c) => c.id === h.channelId) ? "" : "# "}${h.channelName}</span
|
|
6183
|
+
>${this.t("search.in", { where: `${s.chats.some((c) => c.id === h.channelId) ? "" : "# "}${h.channelName}` })}</span
|
|
5525
6184
|
>
|
|
5526
6185
|
<span class="snippet">${h.message.text.slice(0, 100)}</span>
|
|
5527
6186
|
</button>
|
|
@@ -5531,17 +6190,23 @@ var TeamsApp = class extends LitElement {
|
|
|
5531
6190
|
</div>
|
|
5532
6191
|
<div class="me">
|
|
5533
6192
|
<office-ui-menu-button
|
|
5534
|
-
|
|
6193
|
+
class="settings-menu"
|
|
6194
|
+
label=${this.t("app.settingsAndMore")}
|
|
5535
6195
|
icon="more"
|
|
5536
6196
|
icon-only
|
|
5537
6197
|
@office-command=${(event) => {
|
|
5538
6198
|
if (event.detail.command === "teams-settings") this.askSettings();
|
|
5539
6199
|
}}
|
|
5540
6200
|
>
|
|
5541
|
-
<office-ui-menu-item
|
|
6201
|
+
<office-ui-menu-item
|
|
6202
|
+
label=${this.t("settings.title")}
|
|
6203
|
+
command="teams-settings"
|
|
6204
|
+
></office-ui-menu-item>
|
|
5542
6205
|
</office-ui-menu-button>
|
|
5543
6206
|
<teams-profile-menu
|
|
5544
6207
|
.state=${s}
|
|
6208
|
+
.account=${this.signIn.session?.userId ?? ""}
|
|
6209
|
+
@teams-sign-out=${() => void this.signIn.signOut(this.resolveConfig())}
|
|
5545
6210
|
@teams-profile-status=${(event) => {
|
|
5546
6211
|
const { availability, duration } = event.detail;
|
|
5547
6212
|
if (isPresenceStatus(availability))
|
|
@@ -5568,7 +6233,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5568
6233
|
activityToastView(item) {
|
|
5569
6234
|
return html`<div class="activity-toast" role="status" data-kind=${item.kind}>
|
|
5570
6235
|
<span class="toast-text"
|
|
5571
|
-
><strong>${
|
|
6236
|
+
><strong>${describeActivityIn(item, this.i18n)}</strong
|
|
5572
6237
|
><span class="toast-preview">${item.preview}</span></span
|
|
5573
6238
|
>
|
|
5574
6239
|
<button
|
|
@@ -5579,9 +6244,13 @@ var TeamsApp = class extends LitElement {
|
|
|
5579
6244
|
else void this.openActivity(item.id);
|
|
5580
6245
|
}}
|
|
5581
6246
|
>
|
|
5582
|
-
|
|
6247
|
+
${this.t("app.view")}
|
|
5583
6248
|
</button>
|
|
5584
|
-
<button
|
|
6249
|
+
<button
|
|
6250
|
+
type="button"
|
|
6251
|
+
aria-label=${this.t("app.dismiss")}
|
|
6252
|
+
@click=${() => this.dismissToast(item.id)}
|
|
6253
|
+
>
|
|
5585
6254
|
${icon("close")}
|
|
5586
6255
|
</button>
|
|
5587
6256
|
</div>`;
|
|
@@ -5607,7 +6276,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5607
6276
|
class="show-calendar"
|
|
5608
6277
|
@click=${() => this.mobileView = "conversation"}
|
|
5609
6278
|
>
|
|
5610
|
-
${icon("calendar")}
|
|
6279
|
+
${icon("calendar")} ${this.t("app.openCalendar")}
|
|
5611
6280
|
</button>`;
|
|
5612
6281
|
if (this.rail === "activity")
|
|
5613
6282
|
return html`<office-ui-activity-feed
|
|
@@ -5621,7 +6290,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5621
6290
|
if (this.rail === "calls") {
|
|
5622
6291
|
const live2 = s.channels.filter((c) => c.live);
|
|
5623
6292
|
return html`
|
|
5624
|
-
<h2
|
|
6293
|
+
<h2>${this.t("rail.calls")}</h2>
|
|
5625
6294
|
<ul class="plain">
|
|
5626
6295
|
${s.channels.map(
|
|
5627
6296
|
(c) => html`<li>
|
|
@@ -5631,17 +6300,16 @@ var TeamsApp = class extends LitElement {
|
|
|
5631
6300
|
class=${c.live ? "join live" : "join"}
|
|
5632
6301
|
@click=${() => this.startMeeting(c.id)}
|
|
5633
6302
|
>
|
|
5634
|
-
${c.live ? "
|
|
6303
|
+
${this.t(c.live ? "call.join" : "call.meetNow")}
|
|
5635
6304
|
</button>
|
|
5636
6305
|
</li>`
|
|
5637
6306
|
)}
|
|
5638
6307
|
</ul>
|
|
5639
|
-
${live2.length === 0 ? html`<p class="hint"
|
|
6308
|
+
${live2.length === 0 ? html`<p class="hint">${this.t("app.nobodyInCall")}</p>` : nothing}
|
|
5640
6309
|
`;
|
|
5641
6310
|
}
|
|
5642
6311
|
return html`
|
|
5643
6312
|
<office-ui-channel-list
|
|
5644
|
-
heading="Channels"
|
|
5645
6313
|
selected-id=${s.selectedChannelId}
|
|
5646
6314
|
.channels=${s.channels}
|
|
5647
6315
|
@office-channel-select=${(e) => this.selectChannel(e.detail.id)}
|
|
@@ -5651,7 +6319,12 @@ var TeamsApp = class extends LitElement {
|
|
|
5651
6319
|
}
|
|
5652
6320
|
main(s) {
|
|
5653
6321
|
if (this.rail === "drafts" && this.teams.client)
|
|
5654
|
-
return draftList(
|
|
6322
|
+
return draftList(
|
|
6323
|
+
s,
|
|
6324
|
+
this.teams.client,
|
|
6325
|
+
(context) => void this.resumeDraft(context),
|
|
6326
|
+
this.i18n
|
|
6327
|
+
);
|
|
5655
6328
|
if (this.preview)
|
|
5656
6329
|
return html`<teams-content-preview
|
|
5657
6330
|
.detail=${this.preview}
|
|
@@ -5670,7 +6343,8 @@ var TeamsApp = class extends LitElement {
|
|
|
5670
6343
|
this.followedUnreadOnly,
|
|
5671
6344
|
(value) => {
|
|
5672
6345
|
this.followedUnreadOnly = value;
|
|
5673
|
-
}
|
|
6346
|
+
},
|
|
6347
|
+
this.i18n
|
|
5674
6348
|
);
|
|
5675
6349
|
if (s.call && this.meeting) return this.meetingView(s);
|
|
5676
6350
|
if (this.rail === "calendar") return this.calendarMain(s);
|
|
@@ -5678,7 +6352,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5678
6352
|
return this.chatEmpty();
|
|
5679
6353
|
return html`
|
|
5680
6354
|
${s.call && !this.meeting ? html`<div class="callbar">
|
|
5681
|
-
|
|
6355
|
+
${this.t("app.inCall", { where: this.callHeading(s.call) })}
|
|
5682
6356
|
<button
|
|
5683
6357
|
type="button"
|
|
5684
6358
|
@click=${() => {
|
|
@@ -5687,7 +6361,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5687
6361
|
} else if (this.selectChannel(s.call.channelId)) this.meeting = true;
|
|
5688
6362
|
}}
|
|
5689
6363
|
>
|
|
5690
|
-
|
|
6364
|
+
${this.t("app.returnToCall")}
|
|
5691
6365
|
</button>
|
|
5692
6366
|
</div>` : nothing}
|
|
5693
6367
|
${this.conversation(s)}
|
|
@@ -5702,21 +6376,25 @@ var TeamsApp = class extends LitElement {
|
|
|
5702
6376
|
if (sharedTab) this.retainedTab = sharedTab;
|
|
5703
6377
|
const activeTab = sharedTab ?? (this.retainedTab?.id === this.tab && this.retainedTab.channelId === s.selectedChannelId ? this.retainedTab : void 0);
|
|
5704
6378
|
return html`
|
|
5705
|
-
${compact ? nothing : chat ? chatHeader(
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
6379
|
+
${compact ? nothing : chat ? chatHeader(
|
|
6380
|
+
chat,
|
|
6381
|
+
{
|
|
6382
|
+
back: () => this.mobileView = "list",
|
|
6383
|
+
call: () => this.startMeeting(),
|
|
6384
|
+
people: () => this.chatPeople = true
|
|
6385
|
+
},
|
|
6386
|
+
this.i18n
|
|
6387
|
+
) : html`<header class="channel-head">
|
|
5710
6388
|
<button
|
|
5711
6389
|
type="button"
|
|
5712
6390
|
class="back"
|
|
5713
|
-
aria-label
|
|
5714
|
-
title
|
|
6391
|
+
aria-label=${this.t("app.backToChannels")}
|
|
6392
|
+
title=${this.t("app.backToChannels")}
|
|
5715
6393
|
@click=${() => this.mobileView = "list"}
|
|
5716
6394
|
>
|
|
5717
6395
|
${icon("back")}
|
|
5718
6396
|
</button>
|
|
5719
|
-
<h1><span class="hash">#</span> ${channel?.name ?? "
|
|
6397
|
+
<h1><span class="hash">#</span> ${channel?.name ?? this.t("app.noChannel")}</h1>
|
|
5720
6398
|
<nav class="tabs" role="tablist">
|
|
5721
6399
|
${["posts", "files"].map(
|
|
5722
6400
|
(t) => html`<button
|
|
@@ -5725,15 +6403,15 @@ var TeamsApp = class extends LitElement {
|
|
|
5725
6403
|
aria-selected=${String(this.tab === t)}
|
|
5726
6404
|
@click=${() => this.selectTab(t)}
|
|
5727
6405
|
>
|
|
5728
|
-
${t === "posts" ? "
|
|
6406
|
+
${this.t(t === "posts" ? "app.posts" : "app.shared")}
|
|
5729
6407
|
</button>`
|
|
5730
6408
|
)}
|
|
5731
6409
|
${s.tabs.map((t) => html`<button type="button" role="tab" aria-selected=${String(this.tab === t.id)} @click=${() => this.selectTab(t.id)}>${t.name}</button>`)}
|
|
5732
6410
|
</nav>
|
|
5733
6411
|
<button
|
|
5734
6412
|
type="button"
|
|
5735
|
-
aria-label
|
|
5736
|
-
title
|
|
6413
|
+
aria-label=${this.t("app.addTab")}
|
|
6414
|
+
title=${this.t("app.addTab")}
|
|
5737
6415
|
?disabled=${!channel}
|
|
5738
6416
|
@click=${() => this.addingTab = !this.addingTab}
|
|
5739
6417
|
>
|
|
@@ -5742,8 +6420,8 @@ var TeamsApp = class extends LitElement {
|
|
|
5742
6420
|
${sharedTab ? html`<button
|
|
5743
6421
|
type="button"
|
|
5744
6422
|
data-tab-conversation
|
|
5745
|
-
aria-label
|
|
5746
|
-
title
|
|
6423
|
+
aria-label=${this.t("app.tabConversation")}
|
|
6424
|
+
title=${this.t("app.tabConversation")}
|
|
5747
6425
|
aria-expanded=${String(s.thread?.root.tabId === sharedTab.id)}
|
|
5748
6426
|
@click=${async () => {
|
|
5749
6427
|
if (s.thread?.root.tabId === sharedTab.id) {
|
|
@@ -5751,7 +6429,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5751
6429
|
return;
|
|
5752
6430
|
}
|
|
5753
6431
|
if (!c?.openTabConversation(sharedTab.id)) {
|
|
5754
|
-
this.notify(
|
|
6432
|
+
this.notify(this.t("app.tabConversationFailed"));
|
|
5755
6433
|
return;
|
|
5756
6434
|
}
|
|
5757
6435
|
await Promise.resolve();
|
|
@@ -5762,17 +6440,17 @@ var TeamsApp = class extends LitElement {
|
|
|
5762
6440
|
${icon("chat")}
|
|
5763
6441
|
</button>` : nothing}
|
|
5764
6442
|
${sharedTab?.createdBy === s.user.id ? html`<office-ui-menu-button
|
|
5765
|
-
label
|
|
6443
|
+
label=${this.t("app.tabOptions")}
|
|
5766
6444
|
icon="more"
|
|
5767
6445
|
icon-only
|
|
5768
6446
|
@office-command=${(event) => {
|
|
5769
6447
|
if (event.detail.command === "rename-tab") {
|
|
5770
|
-
const name = globalThis.prompt?.("
|
|
6448
|
+
const name = globalThis.prompt?.(this.t("app.tabNamePrompt"), sharedTab.name)?.trim();
|
|
5771
6449
|
if (name) c?.renameTab(sharedTab.id, name);
|
|
5772
6450
|
} else if (event.detail.command === "remove-tab") {
|
|
5773
6451
|
if (!this.canLeaveContent()) return;
|
|
5774
6452
|
if (globalThis.confirm?.(
|
|
5775
|
-
|
|
6453
|
+
this.t("app.confirmRemoveTab", { name: sharedTab.name })
|
|
5776
6454
|
) === true && c?.removeTab(sharedTab.id)) {
|
|
5777
6455
|
this.openRequest++;
|
|
5778
6456
|
this.preview = null;
|
|
@@ -5781,16 +6459,16 @@ var TeamsApp = class extends LitElement {
|
|
|
5781
6459
|
}
|
|
5782
6460
|
}}
|
|
5783
6461
|
><office-ui-menu-item
|
|
5784
|
-
label
|
|
6462
|
+
label=${this.t("app.renameTab")}
|
|
5785
6463
|
command="rename-tab"
|
|
5786
6464
|
></office-ui-menu-item
|
|
5787
6465
|
><office-ui-menu-item
|
|
5788
|
-
label
|
|
6466
|
+
label=${this.t("app.removeTab")}
|
|
5789
6467
|
command="remove-tab"
|
|
5790
6468
|
></office-ui-menu-item
|
|
5791
6469
|
></office-ui-menu-button>` : nothing}
|
|
5792
6470
|
<span class="topic">${channel?.topic ?? ""}</span>
|
|
5793
|
-
<div class="people" aria-label
|
|
6471
|
+
<div class="people" aria-label=${this.t("app.peopleOnline")}>
|
|
5794
6472
|
${s.people.slice(0, 5).map((p) => html`<office-ui-avatar size="sm" name=${p.name} seed=${p.id} color=${p.color} presence=${p.availability}></office-ui-avatar>`)}
|
|
5795
6473
|
${s.people.length > 5 ? html`<span class="more">+${s.people.length - 5}</span>` : nothing}
|
|
5796
6474
|
</div>
|
|
@@ -5800,11 +6478,11 @@ var TeamsApp = class extends LitElement {
|
|
|
5800
6478
|
?disabled=${!channel}
|
|
5801
6479
|
@click=${() => this.startMeeting()}
|
|
5802
6480
|
>
|
|
5803
|
-
${s.channels.find((x) => x.id === s.selectedChannelId)?.live ? "
|
|
6481
|
+
${this.t(s.channels.find((x) => x.id === s.selectedChannelId)?.live ? "call.joinCall" : "call.meetNow")}
|
|
5804
6482
|
</button>
|
|
5805
6483
|
</header>`}
|
|
5806
|
-
${c ? messageTransfers(s, c) : nothing}
|
|
5807
|
-
${activeTab && !sharedTab && !compact ? html`<p role="status"
|
|
6484
|
+
${c ? messageTransfers(s, c, this.i18n) : nothing}
|
|
6485
|
+
${activeTab && !sharedTab && !compact ? html`<p role="status">${this.t("app.tabRemoved")}</p>` : nothing}
|
|
5808
6486
|
${activeTab && !compact ? html`<div
|
|
5809
6487
|
class="conversation-grid tab-conversation"
|
|
5810
6488
|
data-thread=${String(s.thread?.root.tabId === activeTab.id)}
|
|
@@ -5823,7 +6501,8 @@ var TeamsApp = class extends LitElement {
|
|
|
5823
6501
|
c,
|
|
5824
6502
|
(attachment) => void this.openFile(attachment),
|
|
5825
6503
|
() => void this.closeThread(),
|
|
5826
|
-
this.highlightId
|
|
6504
|
+
this.highlightId,
|
|
6505
|
+
this.i18n
|
|
5827
6506
|
) : nothing}
|
|
5828
6507
|
</div>` : this.tab === "files" && !compact ? this.fileList(s.files, s) : html`<div class="conversation-grid" data-thread=${String(!!s.thread && !compact)}>
|
|
5829
6508
|
<div class="conversation-main">
|
|
@@ -5846,7 +6525,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5846
6525
|
@office-chat-thread=${(e) => void this.openThread(e.detail.messageId)}
|
|
5847
6526
|
@office-chat-reply=${(e) => compact ? c?.startReply(e.detail.messageId) : void this.openThread(e.detail.messageId, "reply")}
|
|
5848
6527
|
@office-chat-edit=${(e) => compact ? c?.startEdit(e.detail.messageId) : void this.openThread(e.detail.messageId, "edit")}
|
|
5849
|
-
@office-chat-delete=${(e) => globalThis.confirm?.(
|
|
6528
|
+
@office-chat-delete=${(e) => globalThis.confirm?.(this.t("chat.confirmDelete")) !== false && c?.deleteMessage(e.detail.messageId)}
|
|
5850
6529
|
@office-chat-open-file=${(e) => this.openFile(e.detail.attachment)}
|
|
5851
6530
|
></office-ui-chat-list>
|
|
5852
6531
|
${s.thread && !compact ? nothing : html`<office-ui-chat-composer
|
|
@@ -5859,7 +6538,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5859
6538
|
.mentionTargets=${s.mentionTargets}
|
|
5860
6539
|
@office-chat-draft=${(e) => c?.setDraft(e.detail)}
|
|
5861
6540
|
?disabled=${!channel}
|
|
5862
|
-
placeholder=${chat ?
|
|
6541
|
+
placeholder=${chat ? this.t("app.messageTo", { name: chat.title }) : channel ? this.t("app.messageTo", { name: `# ${channel.name}` }) : this.t("app.createChannelFirst")}
|
|
5863
6542
|
@office-chat-typing=${() => c?.notifyTyping()}
|
|
5864
6543
|
@office-chat-cancel=${() => c?.cancelCompose()}
|
|
5865
6544
|
@office-chat-send=${(e) => void c?.send(e.detail)}
|
|
@@ -5871,7 +6550,8 @@ var TeamsApp = class extends LitElement {
|
|
|
5871
6550
|
c,
|
|
5872
6551
|
(attachment) => void this.openFile(attachment),
|
|
5873
6552
|
() => void this.closeThread(),
|
|
5874
|
-
this.highlightId
|
|
6553
|
+
this.highlightId,
|
|
6554
|
+
this.i18n
|
|
5875
6555
|
) : nothing}
|
|
5876
6556
|
</div>`}
|
|
5877
6557
|
`;
|
|
@@ -5941,9 +6621,9 @@ var TeamsApp = class extends LitElement {
|
|
|
5941
6621
|
}
|
|
5942
6622
|
chatEmpty() {
|
|
5943
6623
|
return html`<div class="empty-main">
|
|
5944
|
-
<h1
|
|
5945
|
-
<p
|
|
5946
|
-
<button type="button" @click=${() => this.newChat = true}
|
|
6624
|
+
<h1>${this.t("rail.chat")}</h1>
|
|
6625
|
+
<p>${this.t("app.pickChat")}</p>
|
|
6626
|
+
<button type="button" @click=${() => this.newChat = true}>${this.t("chat.new")}</button>
|
|
5947
6627
|
</div>`;
|
|
5948
6628
|
}
|
|
5949
6629
|
commitChat(ids, name) {
|
|
@@ -5976,8 +6656,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5976
6656
|
@teams-chat-add=${(e) => c?.addToChat(e.detail.id, e.detail.userIds)}
|
|
5977
6657
|
@teams-chat-remove=${(e) => c?.removeFromChat(e.detail.id, e.detail.userId)}
|
|
5978
6658
|
@teams-chat-leave=${(e) => {
|
|
5979
|
-
if (globalThis.confirm?.(
|
|
5980
|
-
return;
|
|
6659
|
+
if (globalThis.confirm?.(this.t("chatPeople.confirmLeave")) === false) return;
|
|
5981
6660
|
if (c?.leaveChat(e.detail.id)) {
|
|
5982
6661
|
this.chatPeople = false;
|
|
5983
6662
|
this.mobileView = "list";
|
|
@@ -5992,7 +6671,7 @@ var TeamsApp = class extends LitElement {
|
|
|
5992
6671
|
return html`
|
|
5993
6672
|
<div class="calendar-back">
|
|
5994
6673
|
<button type="button" @click=${() => this.mobileView = "list"}>
|
|
5995
|
-
${icon("back")}
|
|
6674
|
+
${icon("back")} ${this.t("app.upcoming")}
|
|
5996
6675
|
</button>
|
|
5997
6676
|
</div>
|
|
5998
6677
|
<office-ui-calendar-view
|
|
@@ -6075,14 +6754,14 @@ var TeamsApp = class extends LitElement {
|
|
|
6075
6754
|
if (c?.cancelOccurrence(meetingId, recurrenceId)) this.meetingDetails = null;
|
|
6076
6755
|
return;
|
|
6077
6756
|
}
|
|
6078
|
-
const ask = details?.repeat === "none" ?
|
|
6757
|
+
const ask = details?.repeat === "none" ? this.t("details.confirmCancel") : this.t("details.confirmCancelSeries");
|
|
6079
6758
|
if (globalThis.confirm?.(ask) === false) return;
|
|
6080
6759
|
if (c?.cancelMeeting(meetingId)) this.meetingDetails = null;
|
|
6081
6760
|
}}
|
|
6082
6761
|
@teams-meeting-ics=${(e) => {
|
|
6083
6762
|
const file = c?.meetingIcs(e.detail.meetingId);
|
|
6084
6763
|
if (file && !downloadText(file.name, file.text))
|
|
6085
|
-
this.notify("
|
|
6764
|
+
this.notify(this.t("app.downloadFailed"));
|
|
6086
6765
|
}}
|
|
6087
6766
|
@teams-dialog-close=${() => this.meetingDetails = null}
|
|
6088
6767
|
></teams-meeting-details>
|
|
@@ -6112,7 +6791,7 @@ var TeamsApp = class extends LitElement {
|
|
|
6112
6791
|
const message = Array.from(
|
|
6113
6792
|
list?.shadowRoot?.querySelectorAll("[data-message-id]") ?? []
|
|
6114
6793
|
).find((element) => element.dataset.messageId === root);
|
|
6115
|
-
message?.querySelector('.thread-link,
|
|
6794
|
+
message?.querySelector('.thread-link, [data-action="reply"]')?.focus();
|
|
6116
6795
|
}
|
|
6117
6796
|
pinFile(file) {
|
|
6118
6797
|
if (!this.selectChannel(file.channelId ?? this.teams.state?.selectedChannelId ?? "")) return;
|
|
@@ -6122,7 +6801,7 @@ var TeamsApp = class extends LitElement {
|
|
|
6122
6801
|
{ postToChannel: true }
|
|
6123
6802
|
);
|
|
6124
6803
|
if (tab) this.selectTab(tab.id);
|
|
6125
|
-
else this.notify("
|
|
6804
|
+
else this.notify(this.t("app.pinNeedsUrl"));
|
|
6126
6805
|
}
|
|
6127
6806
|
saveCopyFor(detail, state) {
|
|
6128
6807
|
const client = this.teams.client;
|
|
@@ -6146,8 +6825,8 @@ var TeamsApp = class extends LitElement {
|
|
|
6146
6825
|
}
|
|
6147
6826
|
allFiles(s) {
|
|
6148
6827
|
return html`<header class="channel-head">
|
|
6149
|
-
<h1
|
|
6150
|
-
<span class="topic"
|
|
6828
|
+
<h1>${this.t("rail.files")}</h1>
|
|
6829
|
+
<span class="topic">${this.t("app.sharedAcross")}</span>
|
|
6151
6830
|
</header>
|
|
6152
6831
|
${this.fileList(s.allFiles, s)}`;
|
|
6153
6832
|
}
|
|
@@ -6195,7 +6874,7 @@ var TeamsApp = class extends LitElement {
|
|
|
6195
6874
|
}))}
|
|
6196
6875
|
></office-ui-call-grid>
|
|
6197
6876
|
${this.panel === "chat" ? html`<aside class="panel chat">${this.conversation(s, true)}</aside>` : this.panel === "people" ? html`<aside class="panel people-panel">
|
|
6198
|
-
<h2
|
|
6877
|
+
<h2>${this.t("app.peopleCount", { count: call.participants.length })}</h2>
|
|
6199
6878
|
<ul class="plain">
|
|
6200
6879
|
${call.participants.map(
|
|
6201
6880
|
(p) => html`<li>
|
|
@@ -6204,8 +6883,10 @@ var TeamsApp = class extends LitElement {
|
|
|
6204
6883
|
name=${p.name}
|
|
6205
6884
|
seed=${p.id}
|
|
6206
6885
|
></office-ui-avatar>
|
|
6207
|
-
<span
|
|
6208
|
-
|
|
6886
|
+
<span
|
|
6887
|
+
>${p.self ? this.t("common.nameYou", { name: p.name }) : p.name}</span
|
|
6888
|
+
>
|
|
6889
|
+
${p.state.hand ? html`<span title=${this.t("call.handRaised")}>✋</span>` : nothing}
|
|
6209
6890
|
</li>`
|
|
6210
6891
|
)}
|
|
6211
6892
|
</ul>
|
|
@@ -6220,7 +6901,7 @@ function defineTeamsApp(registry = globalThis.customElements) {
|
|
|
6220
6901
|
}
|
|
6221
6902
|
|
|
6222
6903
|
// src/teams/app/bind.ts
|
|
6223
|
-
var SCALARS = ["workspaceId", "userName", "userId"];
|
|
6904
|
+
var SCALARS = ["workspaceId", "userName", "userId", "locale"];
|
|
6224
6905
|
function applyTeamsProps(el, props, prev = {}) {
|
|
6225
6906
|
for (const key of SCALARS) {
|
|
6226
6907
|
if (props[key] === prev[key]) continue;
|
|
@@ -6283,4 +6964,4 @@ function registerTeams() {
|
|
|
6283
6964
|
defineCalendarAgenda();
|
|
6284
6965
|
}
|
|
6285
6966
|
|
|
6286
|
-
export { EMOJI, OfficeUiActivityFeed, OfficeUiAppRail, OfficeUiAvatar, OfficeUiCalendarAgenda, OfficeUiCalendarView, OfficeUiCallControls, OfficeUiCallGrid, OfficeUiChannelList, OfficeUiChatComposer, OfficeUiChatList, OfficeUiChatSidebar, OfficeUiPeoplePicker, OfficeUiPrejoin, QUICK_REACTIONS, TEAMS_TAGS, TeamsApp, TeamsChannelTab, TeamsContentPreview, TeamsController, TeamsElement, TeamsFilesPanel, TeamsSettings, XLSX_EDITOR_EVENTS, activityTime, announceFileCommand, applyTeamsProps, blobFor, colorFor, createTeams, dayLabel, defineActivityFeed, defineAppRail, defineAvatar, defineCalendarAgenda, defineCalendarView, defineCallControls, defineCallGrid, defineChannelList, defineChatComposer, defineChatList, defineChatSidebar, definePeoplePicker, definePrejoin, defineTeamsApp, defineTeamsChannelTab, defineTeamsContentPreview, defineTeamsFilesPanel, defineTeamsSettings, downloadBytes, emit, emitEvent, formatElapsed, formatSize, formatTime, formatWhen, icon, listenTeamsEvents, loadConfig, loadIdentity, parseIceLines, pickFile, registerTeams, safeStorage, saveConfig, saveExtension, saveIdentity, withExtension, withStyles };
|
|
6967
|
+
export { EMOJI, OfficeUiActivityFeed, OfficeUiAppRail, OfficeUiAvatar, OfficeUiCalendarAgenda, OfficeUiCalendarView, OfficeUiCallControls, OfficeUiCallGrid, OfficeUiChannelList, OfficeUiChatComposer, OfficeUiChatList, OfficeUiChatSidebar, OfficeUiPeoplePicker, OfficeUiPrejoin, QUICK_REACTIONS, TEAMS_TAGS, TeamsApp, TeamsChannelTab, TeamsContentPreview, TeamsController, TeamsElement, TeamsFilesPanel, TeamsSettings, XLSX_EDITOR_EVENTS, activityTime, announceFileCommand, applyTeamsProps, blobFor, colorFor, createTeams, dayKind, dayLabel, defineActivityFeed, defineAppRail, defineAvatar, defineCalendarAgenda, defineCalendarView, defineCallControls, defineCallGrid, defineChannelList, defineChatComposer, defineChatList, defineChatSidebar, definePeoplePicker, definePrejoin, defineTeamsApp, defineTeamsChannelTab, defineTeamsContentPreview, defineTeamsFilesPanel, defineTeamsSettings, downloadBytes, emit, emitEvent, formatElapsed, formatSize, formatTime, formatWhen, icon, listenTeamsEvents, loadConfig, loadIdentity, parseIceLines, pickFile, registerTeams, safeStorage, saveConfig, saveExtension, saveIdentity, withExtension, withStyles };
|