domma-cms 0.116.6 → 0.116.8
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/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
#view-container.mail-fullbleed{max-width:none}.mail-layout [hidden],.dm-slideover [hidden]{display:none!important}.mail-reader-summary{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}.mail-header-toggle,.mail-extras-toggle{padding:0!important;font-size:.78rem;opacity:.75;text-decoration:underline}.mail-header-toggle:hover,.mail-extras-toggle:hover{opacity:1}.mail-header-details{display:grid;grid-template-columns:max-content 1fr;gap:.15rem .75rem;margin:.5rem 0 0;font-size:.8rem}.mail-header-details dt{opacity:.65}.mail-header-details dd{margin:0;overflow-wrap:anywhere}.mail-layout{display:grid;grid-template-columns:var(--mail-col-1, 190px) auto var(--mail-col-2, 340px) auto 1fr;height:calc(100vh - 140px);min-height:320px;border:1px solid var(--dm-border, #e2e8f0);border-radius:var(--dm-radius-md, 8px);overflow:hidden;background:var(--dm-surface, #fff)}.mail-folders-pane,.mail-list-pane{display:flex;flex-direction:column;border-right:1px solid var(--dm-border, #e2e8f0);min-width:0;min-height:0}.mail-reader-pane{display:flex;flex-direction:column;min-width:0;min-height:0}.mail-pane-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.5rem .75rem;font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--dm-text-muted, #64748b);border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-folders-list,.mail-list{overflow-y:auto;flex:1;min-height:0}.mail-search{display:flex;align-items:center;gap:.4rem;padding:.4rem .6rem;border-bottom:1px solid var(--dm-border, #e2e8f0);color:var(--dm-text-muted, #64748b);flex-shrink:0}.mail-search input{flex:1;min-width:0;font-size:.85rem;padding:.25rem .4rem}.mail-search-note{padding:.3rem .6rem;font-size:.74rem;color:var(--dm-text-muted, #64748b);border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-slideover-resizer{padding:0;position:absolute;left:0;top:0;bottom:0;width:6px;cursor:col-resize;z-index:2;background:transparent}.mail-slideover-resizer:hover,.is-resizing>.mail-slideover-resizer{background:var(--dm-primary, #2563eb);opacity:.7}.is-resizing{user-select:none;transition:none!important}.mail-selection{display:flex;align-items:center;gap:.35rem;flex-wrap:wrap;padding:.35rem .6rem;font-size:.78rem;background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);flex-shrink:0}.mail-selection span{flex:1;min-width:0}.mail-selection .btn{color:var(--dm-primary-text, #fff);border:1px solid currentColor;background:transparent}.mail-selection .btn:hover{background:color-mix(in srgb,var(--dm-primary-text, #fff) 15%,transparent)}.mail-item.is-selected{background:var(--dm-active-bg, rgba(15, 23, 42, .07));box-shadow:inset 3px 0 0 var(--dm-primary, #2563eb)}.mail-undo{display:flex;align-items:center;gap:.5rem;padding:.4rem .6rem;font-size:.78rem;background:var(--dm-active-bg, rgba(15, 23, 42, .07));border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-undo span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-splitter{width:5px;cursor:col-resize;background:var(--dm-border, #e2e8f0);flex-shrink:0;background-clip:content-box;border-left:2px solid transparent;border-right:2px solid transparent;box-sizing:content-box}.mail-splitter:hover,.mail-layout.is-resizing .mail-splitter{background-color:var(--dm-primary, #2563eb)}.mail-layout.is-resizing{user-select:none}.mail-layout.is-resizing .mail-folders-pane,.mail-layout.is-resizing .mail-list-pane,.mail-layout.is-resizing .mail-reader-pane,.mail-layout.is-resizing iframe{pointer-events:none}.mail-unread-filter{display:flex;align-items:center;gap:.3rem;font-size:.7rem;text-transform:none;letter-spacing:0;cursor:pointer;margin-left:auto;margin-right:.25rem}.mail-unread-pill{flex-shrink:0;min-width:1.15rem;padding:0 .3rem;border-radius:999px;background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);font-size:.66rem;font-weight:700;line-height:1.35;text-align:center}.mail-folder.is-context .mail-folder-name{opacity:.6}.mail-account{display:flex;align-items:center;gap:.4rem;width:100%;padding:.45rem .6rem;border:none;background:var(--dm-surface, #fff);cursor:pointer;text-align:left;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--dm-text-muted, #64748b)}.mail-account:hover{background:var(--dm-hover-bg, rgba(15, 23, 42, .04))}.mail-account.is-active{color:var(--dm-text, #1e293b);position:sticky;top:0;z-index:1;background:var(--dm-surface, #fff)}.mail-account-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-folder{display:flex;align-items:center;gap:.5rem;padding:.45rem .75rem;font-size:.875rem;cursor:pointer;border:none;background:none;width:100%;text-align:left;color:var(--dm-text, #1e293b)}.mail-folder:hover{background:var(--dm-hover-bg, rgba(15, 23, 42, .04))}.mail-folder.is-active{background:var(--dm-active-bg, rgba(15, 23, 42, .07));color:var(--dm-primary, #2563eb);font-weight:600}.mail-folder.is-unselectable{opacity:.6;cursor:default}.mail-folder.is-unselectable:hover{background:none}.mail-folder-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-item{display:block;width:100%;text-align:left;padding:.55rem .75rem;border:none;border-bottom:1px solid var(--dm-border, #e2e8f0);background:none;cursor:pointer;color:var(--dm-text, #1e293b)}.mail-item:hover{background:var(--dm-hover-bg, rgba(15, 23, 42, .04))}.mail-item.is-active{background:var(--dm-active-bg, rgba(15, 23, 42, .07))}.mail-item-top{display:flex;justify-content:space-between;gap:.5rem;align-items:baseline}.mail-item-from{font-size:.85rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-item.is-unread .mail-item-from,.mail-item.is-unread .mail-item-subject{font-weight:700}.mail-item-date{font-size:.72rem;color:var(--dm-text-muted, #64748b);flex-shrink:0}.mail-item-subject{font-size:.82rem;margin-top:.1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-item-meta{display:flex;align-items:center;gap:.35rem;margin-top:.15rem;color:var(--dm-text-muted, #64748b)}.mail-pager{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.4rem .6rem;border-top:1px solid var(--dm-border, #e2e8f0);font-size:.75rem;color:var(--dm-text-muted, #64748b);flex-shrink:0}.mail-reader-head{padding:.75rem 1rem;border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-reader-head:empty{display:none}.mail-reader-subject{font-size:1.05rem;font-weight:600;margin:0 0 .3rem;color:var(--dm-text, #1e293b)}.mail-reader-actions{display:flex;gap:.25rem;margin:.1rem 0 .35rem;flex-wrap:wrap}.mail-reader-meta{font-size:.8rem;color:var(--dm-text-muted, #64748b)}.mail-reader-body{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;min-height:0;background:var(--dm-surface, #fff)}.mail-reader-body iframe{width:100%;flex:1;border:none;display:block;background:#fff}.mail-notice{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;padding:.4rem .75rem;font-size:.78rem;background:var(--dm-warning, #8a6d1f);color:var(--dm-warning-text, #fff);border-bottom:1px solid var(--dm-border, #e2e8f0)}.mail-notice .btn{color:var(--dm-warning-text, #fff);border:1px solid currentColor;background:transparent;opacity:.95}.mail-notice .btn:hover{background:color-mix(in srgb,var(--dm-warning-text, #fff) 15%,transparent);opacity:1}.mail-attachments{display:flex;flex-wrap:wrap;gap:.4rem;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border, #e2e8f0);background:var(--dm-background-alt, rgba(15, 23, 42, .03))}.mail-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;height:100%;color:var(--dm-text-muted, #94a3b8);text-align:center;padding:1rem}.mail-empty p{margin:0;font-size:.875rem}@media(max-width:900px){.mail-layout{grid-template-columns:1fr;height:auto!important}.mail-splitter{display:none}.mail-folders-pane,.mail-list-pane{border-right:none;border-bottom:1px solid var(--dm-border, #e2e8f0)}.mail-folders-list,.mail-list{max-height:240px}.mail-reader-body{min-height:60vh}}.mail-box-row{display:flex;align-items:center;gap:.5rem;padding:.5rem .6rem;border:1px solid var(--dm-border, #e2e8f0);border-radius:var(--dm-radius-md, 6px)}.mail-item.is-dragging{opacity:.45}.mail-folder.is-drop-target{background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);outline:2px solid var(--dm-primary, #2563eb);outline-offset:-2px}.mail-folder.is-drop-target .mail-folder-name,.mail-folder.is-drop-target .mail-unread-pill{color:inherit}.mail-item.is-dragging *{pointer-events:none}.mail-item{position:relative}.mail-item-tick{position:absolute;left:.45rem;top:.55rem;display:inline-flex;opacity:0;color:var(--dm-text-muted, #64748b);transition:opacity .12s ease;padding:2px;margin:-2px;border-radius:var(--dm-radius-sm, 3px)}.mail-item:hover .mail-item-tick,.mail-item:focus-visible .mail-item-tick,.mail-list.is-selecting .mail-item-tick,.mail-item-tick[aria-checked=true]{opacity:1}.mail-item-tick[aria-checked=true]{color:var(--dm-primary, #2563eb)}.mail-item-tick:hover{color:var(--dm-primary, #2563eb);background:var(--dm-hover-bg)}.mail-item-top,.mail-item-subject,.mail-item-meta{padding-left:1.5rem}.mail-select-all{display:inline-flex;align-items:center;margin-right:.1rem;cursor:pointer}.mail-select-all input{cursor:pointer;margin:0}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.mail-item-meta>span{display:inline-flex}.mail-item-meta .is-high{color:var(--dm-danger, #dc2626)}.mail-item-meta .is-low{color:var(--dm-text-muted, #64748b);opacity:.7}.mail-folder.is-hidden-folder .mail-folder-name{opacity:.5;font-style:italic}.mail-thread-chip{display:inline-flex;align-items:center;margin-left:.4rem;padding:0 .35rem;border-radius:999px;font-size:.68rem;font-weight:700;line-height:1.5;color:var(--dm-text-muted, #64748b);background:var(--dm-active-bg, rgba(15, 23, 42, .07));cursor:pointer}.mail-thread-chip:hover{color:var(--dm-primary, #2563eb)}.mail-thread-chip.is-unread{background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff)}.mail-item.is-in-thread{padding-left:1.6rem;box-shadow:inset 3px 0 0 var(--dm-border, #e2e8f0)}.mail-item.is-in-thread .mail-item-from{font-size:.8rem}.mail-pane-head .btn.is-on{color:var(--dm-primary, #2563eb);background:var(--dm-active-bg, rgba(15, 23, 42, .07))}#mail-outbox-btn{font-size:.72rem;font-weight:700}#mail-outbox-btn.is-failed{color:var(--dm-danger, #dc2626)}.mail-attachment{display:inline-flex;align-items:center;border:1px solid var(--dm-border, #e2e8f0);border-radius:var(--dm-radius-md, 6px);overflow:hidden}.mail-attachment .btn{border:none;border-radius:0}.mail-attachment-save{padding-left:.4rem!important;padding-right:.4rem!important;border-left:1px solid var(--dm-border, #e2e8f0)!important;opacity:.7}.mail-attachment-save:hover{opacity:1;color:var(--dm-primary, #2563eb)}.mail-section-heading{margin:1rem 0 .1rem;font-size:.8rem;text-transform:uppercase;letter-spacing:.04em;color:var(--dm-text-muted, #64748b)}.mail-section-heading:first-child{margin-top:.25rem}.mail-section-form .domma-form{margin:0}.mail-section-form .domma-form-field:last-child{margin-bottom:0}.mail-item-card{margin:0}.mail-item-card .card-header{padding:.5rem .6rem}.mail-item-card .card-body{padding:.6rem}.mail-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.mail-status{min-height:1.2em}.mail-empty-line{margin:.25rem 0}.mail-editor-fallback{min-height:8rem;font-family:inherit;resize:vertical}.mail-clause{display:flex;gap:.3rem;align-items:center;flex-wrap:wrap}.mail-clause .form-select,.mail-clause .form-input{width:auto;flex:0 1 auto}.mail-clause .mail-clause-value{flex:1 1 8rem;min-width:8rem}.mail-section-list{display:flex;flex-direction:column;gap:.5rem}.mail-scroll-sm{max-height:20vh;overflow-y:auto}.mail-scroll-md{max-height:46vh;overflow-y:auto}.mail-section-form .domma-form-field:has(select) .form-label .text-danger{display:none}.mail-compose-form{padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.6rem;height:100%}.mail-compose-body{display:flex;flex-direction:column;flex:1;min-height:0}.mail-compose-editor{flex:1;min-height:0}.mail-compose-textarea{flex:1;min-height:34vh;font-family:inherit;resize:vertical}.mail-attach-list{display:flex;flex-direction:column;gap:.2rem}.mail-template-row{margin:-.15rem 0 .35rem}.mail-template-picker{max-width:16rem}.mail-suggest-row{display:flex;flex-direction:column;line-height:1.25}.mail-suggest-detail{opacity:.7}.mail-rule-off{opacity:.55}.mail-panel{padding:.25rem 0 .5rem}.mail-panel-stack{padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:1rem}.mail-form-stack{padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem}.mail-dialog-stack{display:flex;flex-direction:column;gap:.5rem;padding:.25rem 0}.mail-hint{margin-top:.2rem}.mail-box-sub{overflow:hidden;text-overflow:ellipsis}.mail-add-btn{align-self:flex-start;margin-top:.5rem}.mail-none{margin:0;padding:.5rem .6rem}.mail-kv{padding:.5rem 0;display:flex;flex-direction:column;gap:.35rem}.mail-kv-row{display:flex;gap:.75rem}.mail-kv-key{min-width:8.5rem;flex-shrink:0}.mail-toggle-row{display:flex;align-items:center;gap:.5rem;margin-bottom:.75rem}.mail-sender-list{display:flex;flex-direction:column;gap:.2rem;max-height:40vh;overflow-y:auto}.mail-folder-pick{display:flex;align-items:center;gap:.5rem;padding:.3rem .4rem;border-radius:var(--dm-radius-md, 6px)}.mail-diag-log{width:100%;height:30vh;margin-top:.5rem;font-family:monospace;font-size:.72rem}.mail-facts{display:flex;flex-direction:column;gap:.2rem;margin-bottom:.75rem}.mail-item-more{position:absolute;right:.4rem;bottom:.35rem;display:inline-flex;align-items:center;justify-content:center;min-width:1.4rem;height:1.4rem;border-radius:var(--dm-radius-sm, 3px);font-size:1rem;line-height:1;color:var(--dm-text-muted, #64748b);background:inherit;opacity:0;transition:opacity .12s ease}.mail-item:hover .mail-item-more,.mail-item:focus-visible .mail-item-more,.mail-item.is-active .mail-item-more{opacity:1}.mail-item-more:hover{color:var(--dm-primary, #2563eb)}.mail-section-intro{display:flex;align-items:center;gap:.35rem;margin:0 0 .75rem;padding-bottom:.5rem;border-bottom:1px solid var(--dm-border, #e2e8f0)}
|
|
1
|
+
#view-container.mail-fullbleed{max-width:none}.mail-layout [hidden],.dm-slideover [hidden]{display:none!important}.mail-reader-summary{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}.mail-header-toggle,.mail-extras-toggle{padding:0!important;font-size:.78rem;opacity:.75;text-decoration:underline}.mail-header-toggle:hover,.mail-extras-toggle:hover{opacity:1}.mail-header-details{display:grid;grid-template-columns:max-content 1fr;gap:.15rem .75rem;margin:.5rem 0 0;font-size:.8rem}.mail-header-details dt{opacity:.65}.mail-header-details dd{margin:0;overflow-wrap:anywhere}.mail-layout{display:grid;grid-template-columns:var(--mail-col-1, 190px) auto var(--mail-col-2, 340px) auto 1fr;height:calc(100vh - 140px);min-height:320px;border:1px solid var(--dm-border, #e2e8f0);border-radius:var(--dm-radius-md, 8px);overflow:hidden;background:var(--dm-surface, #fff)}.mail-folders-pane,.mail-list-pane{display:flex;flex-direction:column;border-right:1px solid var(--dm-border, #e2e8f0);min-width:0;min-height:0}.mail-reader-pane{display:flex;flex-direction:column;min-width:0;min-height:0}.mail-pane-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.5rem .75rem;font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--dm-text-muted, #64748b);border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-folders-list,.mail-list{overflow-y:auto;flex:1;min-height:0}.mail-search{display:flex;align-items:center;gap:.4rem;padding:.4rem .6rem;border-bottom:1px solid var(--dm-border, #e2e8f0);color:var(--dm-text-muted, #64748b);flex-shrink:0}.mail-search input{flex:1;min-width:0;font-size:.85rem;padding:.25rem .4rem}.mail-search-note{padding:.3rem .6rem;font-size:.74rem;color:var(--dm-text-muted, #64748b);border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-slideover-resizer{padding:0;position:absolute;left:0;top:0;bottom:0;width:6px;cursor:col-resize;z-index:2;background:transparent}.mail-slideover-resizer:hover,.is-resizing>.mail-slideover-resizer{background:var(--dm-primary, #2563eb);opacity:.7}.is-resizing{user-select:none;transition:none!important}.mail-selection{display:flex;align-items:center;gap:.35rem;flex-wrap:wrap;padding:.35rem .6rem;font-size:.78rem;background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);flex-shrink:0}.mail-selection span{flex:1;min-width:0}.mail-selection .btn{color:var(--dm-primary-text, #fff);border:1px solid currentColor;background:transparent}.mail-selection .btn:hover{background:color-mix(in srgb,var(--dm-primary-text, #fff) 15%,transparent)}.mail-item.is-selected{background:var(--dm-active-bg, rgba(15, 23, 42, .07));box-shadow:inset 3px 0 0 var(--dm-primary, #2563eb)}.mail-undo{display:flex;align-items:center;gap:.5rem;padding:.4rem .6rem;font-size:.78rem;background:var(--dm-active-bg, rgba(15, 23, 42, .07));border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-undo span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-splitter{width:5px;cursor:col-resize;background:var(--dm-border, #e2e8f0);flex-shrink:0;background-clip:content-box;border-left:2px solid transparent;border-right:2px solid transparent;box-sizing:content-box}.mail-splitter:hover,.mail-layout.is-resizing .mail-splitter{background-color:var(--dm-primary, #2563eb)}.mail-layout.is-resizing{user-select:none}.mail-layout.is-resizing .mail-folders-pane,.mail-layout.is-resizing .mail-list-pane,.mail-layout.is-resizing .mail-reader-pane,.mail-layout.is-resizing iframe{pointer-events:none}.mail-unread-filter{display:flex;align-items:center;gap:.3rem;font-size:.7rem;text-transform:none;letter-spacing:0;cursor:pointer;margin-left:auto;margin-right:.25rem}.mail-unread-pill{flex-shrink:0;min-width:1.15rem;padding:0 .3rem;border-radius:999px;background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);font-size:.66rem;font-weight:700;line-height:1.35;text-align:center}.mail-folder.is-context .mail-folder-name{opacity:.6}.mail-account{display:flex;align-items:center;gap:.4rem;width:100%;padding:.45rem .6rem;border:none;background:var(--dm-surface, #fff);cursor:pointer;text-align:left;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--dm-text-muted, #64748b)}.mail-account:hover{background:var(--dm-hover-bg, rgba(15, 23, 42, .04))}.mail-account.is-active{color:var(--dm-text, #1e293b);position:sticky;top:0;z-index:1;background:var(--dm-surface, #fff)}.mail-account-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-folder{display:flex;align-items:center;gap:.5rem;padding:.45rem .75rem;font-size:.875rem;cursor:pointer;border:none;background:none;width:100%;text-align:left;color:var(--dm-text, #1e293b)}.mail-folder:hover{background:var(--dm-hover-bg, rgba(15, 23, 42, .04))}.mail-folder.is-active{background:var(--dm-active-bg, rgba(15, 23, 42, .07));color:var(--dm-primary, #2563eb);font-weight:600}.mail-folder.is-unselectable{opacity:.6;cursor:default}.mail-folder.is-unselectable:hover{background:none}.mail-folder-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-item{display:block;width:100%;text-align:left;padding:.55rem .75rem;border:none;border-bottom:1px solid var(--dm-border, #e2e8f0);background:none;cursor:pointer;color:var(--dm-text, #1e293b)}.mail-item:hover{background:var(--dm-hover-bg, rgba(15, 23, 42, .04))}.mail-item.is-active{background:var(--dm-active-bg, rgba(15, 23, 42, .07))}.mail-item-top{display:flex;justify-content:space-between;gap:.5rem;align-items:baseline}.mail-item-from{font-size:.85rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-item.is-unread .mail-item-from,.mail-item.is-unread .mail-item-subject{font-weight:700}.mail-item-date{font-size:.72rem;color:var(--dm-text-muted, #64748b);flex-shrink:0}.mail-item-subject{font-size:.82rem;margin-top:.1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-item-meta{display:flex;align-items:center;gap:.35rem;margin-top:.15rem;color:var(--dm-text-muted, #64748b)}.mail-pager{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.4rem .6rem;border-top:1px solid var(--dm-border, #e2e8f0);font-size:.75rem;color:var(--dm-text-muted, #64748b);flex-shrink:0}.mail-reader-head{padding:.75rem 1rem;border-bottom:1px solid var(--dm-border, #e2e8f0);flex-shrink:0}.mail-reader-head:empty{display:none}.mail-reader-subject{font-size:1.05rem;font-weight:600;margin:0 0 .3rem;color:var(--dm-text, #1e293b)}.mail-reader-actions{display:flex;gap:.25rem;margin:.1rem 0 .35rem;flex-wrap:wrap}.mail-reader-meta{font-size:.8rem;color:var(--dm-text-muted, #64748b)}.mail-reader-body{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;min-height:0;background:var(--dm-surface, #fff)}.mail-reader-body iframe{width:100%;flex:1;border:none;display:block;background:#fff}.mail-notice{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;padding:.4rem .75rem;font-size:.78rem;background:var(--dm-warning, #8a6d1f);color:var(--dm-warning-text, #fff);border-bottom:1px solid var(--dm-border, #e2e8f0)}.mail-notice .btn{color:var(--dm-warning-text, #fff);border:1px solid currentColor;background:transparent;opacity:.95}.mail-notice .btn:hover{background:color-mix(in srgb,var(--dm-warning-text, #fff) 15%,transparent);opacity:1}.mail-attachments{display:flex;flex-wrap:wrap;gap:.4rem;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border, #e2e8f0);background:var(--dm-background-alt, rgba(15, 23, 42, .03))}.mail-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;height:100%;color:var(--dm-text-muted, #94a3b8);text-align:center;padding:1rem}.mail-empty p{margin:0;font-size:.875rem}@media(max-width:900px){.mail-layout{grid-template-columns:1fr;height:auto!important}.mail-splitter{display:none}.mail-folders-pane,.mail-list-pane{border-right:none;border-bottom:1px solid var(--dm-border, #e2e8f0)}.mail-folders-list,.mail-list{max-height:240px}.mail-reader-body{min-height:60vh}}.mail-box-row{display:flex;align-items:center;gap:.5rem;padding:.5rem .6rem;border:1px solid var(--dm-border, #e2e8f0);border-radius:var(--dm-radius-md, 6px)}.mail-default-badge{margin-left:.4rem;font-size:.7rem;font-weight:500;vertical-align:middle}.mail-item.is-dragging{opacity:.45}.mail-folder.is-drop-target{background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff);outline:2px solid var(--dm-primary, #2563eb);outline-offset:-2px}.mail-folder.is-drop-target .mail-folder-name,.mail-folder.is-drop-target .mail-unread-pill{color:inherit}.mail-item.is-dragging *{pointer-events:none}.mail-item{position:relative}.mail-item-tick{position:absolute;left:.45rem;top:.55rem;display:inline-flex;opacity:0;color:var(--dm-text-muted, #64748b);transition:opacity .12s ease;padding:2px;margin:-2px;border-radius:var(--dm-radius-sm, 3px)}.mail-item:hover .mail-item-tick,.mail-item:focus-visible .mail-item-tick,.mail-list.is-selecting .mail-item-tick,.mail-item-tick[aria-checked=true]{opacity:1}.mail-item-tick[aria-checked=true]{color:var(--dm-primary, #2563eb)}.mail-item-tick:hover{color:var(--dm-primary, #2563eb);background:var(--dm-hover-bg)}.mail-item-top,.mail-item-subject,.mail-item-meta{padding-left:1.5rem}.mail-select-all{display:inline-flex;align-items:center;margin-right:.1rem;cursor:pointer}.mail-select-all input{cursor:pointer;margin:0}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.mail-item-meta>span{display:inline-flex}.mail-item-meta .is-high{color:var(--dm-danger, #dc2626)}.mail-item-meta .is-low{color:var(--dm-text-muted, #64748b);opacity:.7}.mail-folder.is-hidden-folder .mail-folder-name{opacity:.5;font-style:italic}.mail-thread-chip{display:inline-flex;align-items:center;margin-left:.4rem;padding:0 .35rem;border-radius:999px;font-size:.68rem;font-weight:700;line-height:1.5;color:var(--dm-text-muted, #64748b);background:var(--dm-active-bg, rgba(15, 23, 42, .07));cursor:pointer}.mail-thread-chip:hover{color:var(--dm-primary, #2563eb)}.mail-thread-chip.is-unread{background:var(--dm-primary, #2563eb);color:var(--dm-primary-text, #fff)}.mail-item.is-in-thread{padding-left:1.6rem;box-shadow:inset 3px 0 0 var(--dm-border, #e2e8f0)}.mail-item.is-in-thread .mail-item-from{font-size:.8rem}.mail-pane-head .btn.is-on{color:var(--dm-primary, #2563eb);background:var(--dm-active-bg, rgba(15, 23, 42, .07))}#mail-outbox-btn{font-size:.72rem;font-weight:700}#mail-outbox-btn.is-failed{color:var(--dm-danger, #dc2626)}.mail-attachment{display:inline-flex;align-items:center;border:1px solid var(--dm-border, #e2e8f0);border-radius:var(--dm-radius-md, 6px);overflow:hidden}.mail-attachment .btn{border:none;border-radius:0}.mail-attachment-save{padding-left:.4rem!important;padding-right:.4rem!important;border-left:1px solid var(--dm-border, #e2e8f0)!important;opacity:.7}.mail-attachment-save:hover{opacity:1;color:var(--dm-primary, #2563eb)}.mail-section-heading{margin:1rem 0 .1rem;font-size:.8rem;text-transform:uppercase;letter-spacing:.04em;color:var(--dm-text-muted, #64748b)}.mail-section-heading:first-child{margin-top:.25rem}.mail-section-form .domma-form{margin:0}.mail-section-form .domma-form-field:last-child{margin-bottom:0}.mail-item-card{margin:0}.mail-item-card .card-header{padding:.5rem .6rem}.mail-item-card .card-body{padding:.6rem}.mail-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.mail-status{min-height:1.2em}.mail-empty-line{margin:.25rem 0}.mail-editor-fallback{min-height:8rem;font-family:inherit;resize:vertical}.mail-clause{display:flex;gap:.3rem;align-items:center;flex-wrap:wrap}.mail-clause .form-select,.mail-clause .form-input{width:auto;flex:0 1 auto}.mail-clause .mail-clause-value{flex:1 1 8rem;min-width:8rem}.mail-section-list{display:flex;flex-direction:column;gap:.5rem}.mail-scroll-sm{max-height:20vh;overflow-y:auto}.mail-scroll-md{max-height:46vh;overflow-y:auto}.mail-section-form .domma-form-field:has(select) .form-label .text-danger{display:none}.mail-compose-form{padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.6rem;height:100%}.mail-compose-body{display:flex;flex-direction:column;flex:1;min-height:0}.mail-compose-editor{flex:1;min-height:0}.mail-compose-textarea{flex:1;min-height:34vh;font-family:inherit;resize:vertical}.mail-attach-list{display:flex;flex-direction:column;gap:.2rem}.mail-template-row{margin:-.15rem 0 .35rem}.mail-template-picker{max-width:16rem}.mail-suggest-row{display:flex;flex-direction:column;line-height:1.25}.mail-suggest-detail{opacity:.7}.mail-rule-off{opacity:.55}.mail-panel{padding:.25rem 0 .5rem}.mail-panel-stack{padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:1rem}.mail-form-stack{padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem}.mail-dialog-stack{display:flex;flex-direction:column;gap:.5rem;padding:.25rem 0}.mail-hint{margin-top:.2rem}.mail-box-sub{overflow:hidden;text-overflow:ellipsis}.mail-add-btn{align-self:flex-start;margin-top:.5rem}.mail-none{margin:0;padding:.5rem .6rem}.mail-kv{padding:.5rem 0;display:flex;flex-direction:column;gap:.35rem}.mail-kv-row{display:flex;gap:.75rem}.mail-kv-key{min-width:8.5rem;flex-shrink:0}.mail-toggle-row{display:flex;align-items:center;gap:.5rem;margin-bottom:.75rem}.mail-sender-list{display:flex;flex-direction:column;gap:.2rem;max-height:40vh;overflow-y:auto}.mail-folder-pick{display:flex;align-items:center;gap:.5rem;padding:.3rem .4rem;border-radius:var(--dm-radius-md, 6px)}.mail-diag-log{width:100%;height:30vh;margin-top:.5rem;font-family:monospace;font-size:.72rem}.mail-facts{display:flex;flex-direction:column;gap:.2rem;margin-bottom:.75rem}.mail-item-more{position:absolute;right:.4rem;bottom:.35rem;display:inline-flex;align-items:center;justify-content:center;min-width:1.4rem;height:1.4rem;border-radius:var(--dm-radius-sm, 3px);font-size:1rem;line-height:1;color:var(--dm-text-muted, #64748b);background:inherit;opacity:0;transition:opacity .12s ease}.mail-item:hover .mail-item-more,.mail-item:focus-visible .mail-item-more,.mail-item.is-active .mail-item-more{opacity:1}.mail-item-more:hover{color:var(--dm-primary, #2563eb)}.mail-section-intro{display:flex;align-items:center;gap:.35rem;margin:0 0 .75rem;padding-bottom:.5rem;border-bottom:1px solid var(--dm-border, #e2e8f0)}.mail-pager-middle{display:flex;align-items:center;gap:.5rem;min-width:0}.mail-page-size{font:inherit;color:inherit;background:transparent;border:1px solid var(--dm-border, #e2e8f0);border-radius:4px;padding:.1rem .25rem}
|
|
@@ -34,7 +34,10 @@ const {
|
|
|
34
34
|
unreadInSubtree
|
|
35
35
|
} = await import(versioned('folder-tree.js'));
|
|
36
36
|
const {imageSendersSection} = await import(versioned('image-senders-section.js'));
|
|
37
|
-
const {
|
|
37
|
+
const {
|
|
38
|
+
createSettingsSection, READ_DELAY_KEY, readDelaySeconds, scheduleMarkRead,
|
|
39
|
+
PAGE_SIZE_KEY, PAGE_SIZES, listPageSize, pageAfterResize
|
|
40
|
+
} = await import(versioned('settings-section.js'));
|
|
38
41
|
const {createSplitters, fitToViewport} = await import(versioned('panes.js'));
|
|
39
42
|
const {createDiagnosticsSection} = await import(versioned('diagnostics-section.js'));
|
|
40
43
|
const {fmtDate, fmtDateTime} = await import(new URL(`../ui/dates.js?v=${ASSET_VERSION}`, import.meta.url).href);
|
|
@@ -303,7 +306,19 @@ return {
|
|
|
303
306
|
let threads = [];
|
|
304
307
|
let page = 1;
|
|
305
308
|
let total = 0;
|
|
306
|
-
|
|
309
|
+
/**
|
|
310
|
+
* Messages per page as chosen under the list. Remembered: a long
|
|
311
|
+
* folder is read the same way every visit.
|
|
312
|
+
*/
|
|
313
|
+
let pageSize = (() => {
|
|
314
|
+
try {
|
|
315
|
+
return listPageSize(S.get(PAGE_SIZE_KEY));
|
|
316
|
+
} catch {
|
|
317
|
+
return listPageSize(null);
|
|
318
|
+
}
|
|
319
|
+
})();
|
|
320
|
+
/** The page size the server actually used - what the pager counts in. */
|
|
321
|
+
let limit = pageSize;
|
|
307
322
|
/**
|
|
308
323
|
* The Contacts plugin's address book, or an empty list where it is not
|
|
309
324
|
* installed. Held here rather than fetched per compose window: the
|
|
@@ -923,6 +938,16 @@ return {
|
|
|
923
938
|
* @returns {void}
|
|
924
939
|
*/
|
|
925
940
|
function renderMailboxSection(container) {
|
|
941
|
+
container.appendChild(mailboxSectionBody());
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* The mailbox rows and the Add button, rebuilt whole when the
|
|
946
|
+
* default changes so the order matches the folder pane.
|
|
947
|
+
*
|
|
948
|
+
* @returns {HTMLElement}
|
|
949
|
+
*/
|
|
950
|
+
function mailboxSectionBody() {
|
|
926
951
|
const body = document.createElement('div');
|
|
927
952
|
body.className = 'flex flex-col gap-2';
|
|
928
953
|
|
|
@@ -942,6 +967,12 @@ return {
|
|
|
942
967
|
const name = document.createElement('div');
|
|
943
968
|
name.className = 'font-semibold text-sm';
|
|
944
969
|
name.textContent = box.label;
|
|
970
|
+
if (box.isDefault && mailboxes.length > 1) {
|
|
971
|
+
const badge = document.createElement('span');
|
|
972
|
+
badge.className = 'badge badge-primary mail-default-badge';
|
|
973
|
+
badge.textContent = 'Default';
|
|
974
|
+
name.appendChild(badge);
|
|
975
|
+
}
|
|
945
976
|
const sub = document.createElement('div');
|
|
946
977
|
sub.className = 'text-xs text-muted mail-box-sub';
|
|
947
978
|
sub.textContent = `${box.username} \u00b7 ${box.host}:${box.port}${box.secure ? '' : ' (no TLS)'}`;
|
|
@@ -971,6 +1002,30 @@ return {
|
|
|
971
1002
|
}
|
|
972
1003
|
});
|
|
973
1004
|
|
|
1005
|
+
// Only worth offering when there is a choice to make.
|
|
1006
|
+
if (mailboxes.length > 1) {
|
|
1007
|
+
const defaultBtn = document.createElement('button');
|
|
1008
|
+
defaultBtn.className = 'btn btn-sm btn-ghost';
|
|
1009
|
+
defaultBtn.textContent = box.isDefault ? 'Unset default' : 'Make default';
|
|
1010
|
+
defaultBtn.title = box.isDefault
|
|
1011
|
+
? 'Stop opening with this mailbox'
|
|
1012
|
+
: 'List this mailbox first and open with it';
|
|
1013
|
+
defaultBtn.addEventListener('click', async () => {
|
|
1014
|
+
try {
|
|
1015
|
+
await api(`${BASE}/accounts/${encodeURIComponent(box.id)}/default`, 'PUT',
|
|
1016
|
+
{isDefault: !box.isDefault});
|
|
1017
|
+
mailboxes = (await api(`${BASE}/accounts`)).accounts;
|
|
1018
|
+
renderFolders();
|
|
1019
|
+
body.replaceWith(mailboxSectionBody());
|
|
1020
|
+
E.toast(box.isDefault ? 'Default cleared.' : `"${box.label}" is now the default.`,
|
|
1021
|
+
{type: 'success'});
|
|
1022
|
+
} catch (err) {
|
|
1023
|
+
E.toast(err.message, {type: 'error'});
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
row.appendChild(defaultBtn);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
974
1029
|
row.appendChild(editBtn);
|
|
975
1030
|
row.appendChild(removeBtn);
|
|
976
1031
|
body.appendChild(row);
|
|
@@ -983,7 +1038,7 @@ return {
|
|
|
983
1038
|
addBtn.addEventListener('click', () => openMailboxForm(null));
|
|
984
1039
|
body.appendChild(addBtn);
|
|
985
1040
|
|
|
986
|
-
|
|
1041
|
+
return body;
|
|
987
1042
|
}
|
|
988
1043
|
|
|
989
1044
|
/**
|
|
@@ -1256,8 +1311,21 @@ return {
|
|
|
1256
1311
|
// One handler, two gestures: the chevron folds, the rest of
|
|
1257
1312
|
// the row opens the folder. A nested <button> inside a
|
|
1258
1313
|
// <button> would be invalid markup, so the target decides.
|
|
1314
|
+
// A double-click on a parent folds it too. Read from the
|
|
1315
|
+
// click count rather than a dblclick listener: the first
|
|
1316
|
+
// click opens the folder, which redraws this pane, and a
|
|
1317
|
+
// dblclick needs both clicks to land on the same element.
|
|
1259
1318
|
btn.addEventListener('click', event => {
|
|
1260
|
-
|
|
1319
|
+
const onToggle = !!event.target.closest('.mail-folder-toggle');
|
|
1320
|
+
if (event.detail >= 2) {
|
|
1321
|
+
// The first click already folded it when it hit
|
|
1322
|
+
// the chevron or a level that cannot be opened.
|
|
1323
|
+
if (folder.children.length && folder.selectable && !onToggle && event.detail === 2) {
|
|
1324
|
+
toggleFolder(folder.path);
|
|
1325
|
+
}
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
if (folder.children.length && onToggle) {
|
|
1261
1329
|
toggleFolder(folder.path);
|
|
1262
1330
|
return;
|
|
1263
1331
|
}
|
|
@@ -1303,6 +1371,10 @@ return {
|
|
|
1303
1371
|
* @returns {string|null}
|
|
1304
1372
|
*/
|
|
1305
1373
|
function preferredAccount() {
|
|
1374
|
+
// A chosen default beats the last one looked at - that is what
|
|
1375
|
+
// choosing one means.
|
|
1376
|
+
const chosen = mailboxes.find(b => b.isDefault === true);
|
|
1377
|
+
if (chosen) return chosen.id;
|
|
1306
1378
|
let saved = null;
|
|
1307
1379
|
try {
|
|
1308
1380
|
saved = S.get(ACCOUNT_KEY);
|
|
@@ -1406,7 +1478,8 @@ return {
|
|
|
1406
1478
|
const params = new URLSearchParams({
|
|
1407
1479
|
account: currentAccountId ?? '',
|
|
1408
1480
|
folder: currentFolder,
|
|
1409
|
-
page: String(page)
|
|
1481
|
+
page: String(page),
|
|
1482
|
+
limit: String(pageSize)
|
|
1410
1483
|
});
|
|
1411
1484
|
if (fresh) params.set('fresh', '1');
|
|
1412
1485
|
const result = await api(`${BASE}/messages?${params}`);
|
|
@@ -1440,7 +1513,8 @@ return {
|
|
|
1440
1513
|
const params = new URLSearchParams({
|
|
1441
1514
|
account: currentAccountId ?? '',
|
|
1442
1515
|
folder: currentFolder,
|
|
1443
|
-
page: String(page)
|
|
1516
|
+
page: String(page),
|
|
1517
|
+
limit: String(pageSize)
|
|
1444
1518
|
});
|
|
1445
1519
|
const result = await api(`${BASE}/threads?${params}`);
|
|
1446
1520
|
|
|
@@ -1565,7 +1639,8 @@ return {
|
|
|
1565
1639
|
const params = new URLSearchParams({
|
|
1566
1640
|
account: currentAccountId ?? '',
|
|
1567
1641
|
q: searchQuery,
|
|
1568
|
-
page: String(page)
|
|
1642
|
+
page: String(page),
|
|
1643
|
+
limit: String(pageSize)
|
|
1569
1644
|
});
|
|
1570
1645
|
const result = await api(`${BASE}/search?${params}`);
|
|
1571
1646
|
|
|
@@ -2124,11 +2199,49 @@ return {
|
|
|
2124
2199
|
loadMessages();
|
|
2125
2200
|
});
|
|
2126
2201
|
|
|
2202
|
+
const size = document.createElement('select');
|
|
2203
|
+
size.className = 'mail-page-size';
|
|
2204
|
+
size.title = 'Messages per page';
|
|
2205
|
+
size.setAttribute('aria-label', 'Messages per page');
|
|
2206
|
+
for (const n of PAGE_SIZES) {
|
|
2207
|
+
const option = document.createElement('option');
|
|
2208
|
+
option.value = String(n);
|
|
2209
|
+
option.textContent = `${n} per page`;
|
|
2210
|
+
size.appendChild(option);
|
|
2211
|
+
}
|
|
2212
|
+
size.value = String(pageSize);
|
|
2213
|
+
size.addEventListener('change', () => setPageSize(Number(size.value)));
|
|
2214
|
+
|
|
2215
|
+
const middle = document.createElement('span');
|
|
2216
|
+
middle.className = 'mail-pager-middle';
|
|
2217
|
+
middle.appendChild(label);
|
|
2218
|
+
middle.appendChild(size);
|
|
2219
|
+
|
|
2127
2220
|
pagerEl.appendChild(prev);
|
|
2128
|
-
pagerEl.appendChild(
|
|
2221
|
+
pagerEl.appendChild(middle);
|
|
2129
2222
|
pagerEl.appendChild(next);
|
|
2130
2223
|
}
|
|
2131
2224
|
|
|
2225
|
+
/**
|
|
2226
|
+
* Change how many messages a page holds, keeping the first message of
|
|
2227
|
+
* the current page in view.
|
|
2228
|
+
*
|
|
2229
|
+
* @param {number} size
|
|
2230
|
+
* @returns {Promise<void>}
|
|
2231
|
+
*/
|
|
2232
|
+
async function setPageSize(size) {
|
|
2233
|
+
const next = listPageSize(size);
|
|
2234
|
+
if (next === pageSize) return;
|
|
2235
|
+
page = pageAfterResize(page, limit, next);
|
|
2236
|
+
pageSize = next;
|
|
2237
|
+
try {
|
|
2238
|
+
S.set(PAGE_SIZE_KEY, pageSize);
|
|
2239
|
+
} catch {
|
|
2240
|
+
// Storage refused - the size still applies for this visit.
|
|
2241
|
+
}
|
|
2242
|
+
await loadMessages();
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2132
2245
|
// ---------------------------------------------------------------
|
|
2133
2246
|
// Reader
|
|
2134
2247
|
// ---------------------------------------------------------------
|
|
@@ -4885,7 +4998,7 @@ return {
|
|
|
4885
4998
|
const folder = currentFolder;
|
|
4886
4999
|
refreshing = true;
|
|
4887
5000
|
try {
|
|
4888
|
-
const params = new URLSearchParams({account, folder, page: '1'});
|
|
5001
|
+
const params = new URLSearchParams({account, folder, page: '1', limit: String(pageSize)});
|
|
4889
5002
|
const result = await api(`${BASE}/messages?${params}`);
|
|
4890
5003
|
if (!here() || currentAccountId !== account || currentFolder !== folder ||
|
|
4891
5004
|
page !== 1 || searchQuery || selected.size) return;
|
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
/** Browser preferences for the shared mail reader. */
|
|
2
2
|
export const READ_DELAY_KEY = 'domma-mail.mark-read-seconds';
|
|
3
3
|
export const DEFAULT_READ_DELAY_SECONDS = 1;
|
|
4
|
+
export const PAGE_SIZE_KEY = 'domma-mail.page-size';
|
|
5
|
+
/** The choices offered under the list. 200 is the server's maxListLimit. */
|
|
6
|
+
export const PAGE_SIZES = [25, 50, 100, 200];
|
|
7
|
+
export const DEFAULT_PAGE_SIZE = 50;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The remembered messages-per-page, or the default for anything that is not
|
|
11
|
+
* one of the offered sizes - a stale or hand-edited value must not ask the
|
|
12
|
+
* server for a page size the picker cannot show.
|
|
13
|
+
*
|
|
14
|
+
* @param {*} value
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
export function listPageSize(value) {
|
|
18
|
+
const size = Number(value);
|
|
19
|
+
return PAGE_SIZES.includes(size) ? size : DEFAULT_PAGE_SIZE;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The page that keeps the first message of the current page in view after the
|
|
24
|
+
* page size changes, so switching from 50 to 200 on page 3 lands on the page
|
|
25
|
+
* holding message 101 rather than jumping back to the newest.
|
|
26
|
+
*
|
|
27
|
+
* @param {number} page current 1-based page
|
|
28
|
+
* @param {number} oldSize
|
|
29
|
+
* @param {number} newSize
|
|
30
|
+
* @returns {number}
|
|
31
|
+
*/
|
|
32
|
+
export function pageAfterResize(page, oldSize, newSize) {
|
|
33
|
+
const firstIndex = (Math.max(1, page) - 1) * oldSize;
|
|
34
|
+
return Math.floor(firstIndex / newSize) + 1;
|
|
35
|
+
}
|
|
4
36
|
|
|
5
37
|
export function readDelaySeconds(value) {
|
|
6
38
|
if (value === null || value === undefined || value === '') return DEFAULT_READ_DELAY_SECONDS;
|
|
@@ -773,7 +773,7 @@ export function validate(input, existing) {
|
|
|
773
773
|
}
|
|
774
774
|
|
|
775
775
|
/**
|
|
776
|
-
* Every mailbox belonging to one user, oldest first.
|
|
776
|
+
* Every mailbox belonging to one user: the default first, then oldest first.
|
|
777
777
|
*
|
|
778
778
|
* @param {string} userId
|
|
779
779
|
* @returns {Promise<object[]>}
|
|
@@ -782,7 +782,34 @@ export async function listAccounts(userId) {
|
|
|
782
782
|
const all = await readAll();
|
|
783
783
|
return all
|
|
784
784
|
.filter(a => a.userId === userId)
|
|
785
|
-
.sort((a, b) =>
|
|
785
|
+
.sort((a, b) => (b.isDefault === true) - (a.isDefault === true)
|
|
786
|
+
|| String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Make one mailbox this user's default, or clear the default.
|
|
791
|
+
*
|
|
792
|
+
* At most one per user, so setting it takes it off every other mailbox they
|
|
793
|
+
* own. The default is listed first and is the one the reader opens with.
|
|
794
|
+
*
|
|
795
|
+
* @param {string} userId
|
|
796
|
+
* @param {string} accountId
|
|
797
|
+
* @param {boolean} isDefault - false clears it from this mailbox only
|
|
798
|
+
* @returns {Promise<object|null>} the stored record, or null if not theirs
|
|
799
|
+
*/
|
|
800
|
+
export async function setDefaultAccount(userId, accountId, isDefault) {
|
|
801
|
+
const all = await readAll();
|
|
802
|
+
const index = all.findIndex(a => a.id === accountId && a.userId === userId);
|
|
803
|
+
if (index === -1) return null;
|
|
804
|
+
|
|
805
|
+
const now = new Date().toISOString();
|
|
806
|
+
for (let i = 0; i < all.length; i++) {
|
|
807
|
+
if (all[i].userId !== userId) continue;
|
|
808
|
+
const want = i === index ? !!isDefault : (isDefault ? false : all[i].isDefault === true);
|
|
809
|
+
if ((all[i].isDefault === true) !== want) all[i] = {...all[i], isDefault: want, updatedAt: now};
|
|
810
|
+
}
|
|
811
|
+
await writeAll(all);
|
|
812
|
+
return all[index];
|
|
786
813
|
}
|
|
787
814
|
|
|
788
815
|
/**
|
|
@@ -243,6 +243,16 @@ export function registerReadRoutes(fastify, {auth, hooks, config, pool, pluginNa
|
|
|
243
243
|
return {account: accounts.toPublic(saved)};
|
|
244
244
|
});
|
|
245
245
|
|
|
246
|
+
/** PUT /accounts/:id/default - make it the default mailbox ({isDefault: false} clears it). */
|
|
247
|
+
fastify.put('/accounts/:id/default', {preHandler: [authenticate]}, async (request, reply) => {
|
|
248
|
+
const uid = userId(request);
|
|
249
|
+
if (!uid) return reply.code(401).send({error: 'Authentication required.'});
|
|
250
|
+
|
|
251
|
+
const saved = await accounts.setDefaultAccount(uid, request.params.id, request.body?.isDefault !== false);
|
|
252
|
+
if (!saved) return reply.code(404).send({error: 'That mailbox does not exist.'});
|
|
253
|
+
return {account: accounts.toPublic(saved)};
|
|
254
|
+
});
|
|
255
|
+
|
|
246
256
|
/** DELETE /accounts/:id - forget a mailbox and its password. */
|
|
247
257
|
fastify.delete('/accounts/:id', {preHandler: [authenticate]}, async (request, reply) => {
|
|
248
258
|
const uid = userId(request);
|