@propbinder/mobile-design 0.1.20 → 0.1.22

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.
@@ -2674,6 +2674,10 @@ class DsMobileCommentComponent {
2674
2674
  * Whether the comment is liked by current user
2675
2675
  */
2676
2676
  isLiked = model(false, ...(ngDevMode ? [{ debugName: "isLiked" }] : []));
2677
+ /**
2678
+ * Emits when like is toggled (after UI is opdateret)
2679
+ */
2680
+ likeToggled = output();
2677
2681
  /**
2678
2682
  * Number of likes
2679
2683
  */
@@ -2727,6 +2731,8 @@ class DsMobileCommentComponent {
2727
2731
  this.isLiked.set(newLiked);
2728
2732
  const newCount = newLiked ? this.likeCount() + 1 : this.likeCount() - 1;
2729
2733
  this.likeCount.set(Math.max(0, newCount));
2734
+ // Emit the like toggled event
2735
+ this.likeToggled.emit({ active: newLiked, count: Math.max(0, newCount) });
2730
2736
  // Trigger pulse animation only when liking
2731
2737
  if (newLiked) {
2732
2738
  this.isPulsing.set(true);
@@ -2821,64 +2827,42 @@ class DsMobileCommentComponent {
2821
2827
  this.longPress.emit();
2822
2828
  }
2823
2829
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DsMobileCommentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2824
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: DsMobileCommentComponent, isStandalone: true, selector: "ds-mobile-comment", inputs: { authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: true, transformFunction: null }, authorRole: { classPropertyName: "authorRole", publicName: "authorRole", isSignal: true, isRequired: true, transformFunction: null }, timestamp: { classPropertyName: "timestamp", publicName: "timestamp", isSignal: true, isRequired: true, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: true, transformFunction: null }, avatarInitials: { classPropertyName: "avatarInitials", publicName: "avatarInitials", isSignal: true, isRequired: false, transformFunction: null }, avatarType: { classPropertyName: "avatarType", publicName: "avatarType", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, isOwnComment: { classPropertyName: "isOwnComment", publicName: "isOwnComment", isSignal: true, isRequired: false, transformFunction: null }, isLiked: { classPropertyName: "isLiked", publicName: "isLiked", isSignal: true, isRequired: false, transformFunction: null }, likeCount: { classPropertyName: "likeCount", publicName: "likeCount", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isLiked: "isLikedChange", likeCount: "likeCountChange", commentClick: "commentClick", replyClick: "replyClick", editClick: "editClick", longPress: "longPress" }, host: { listeners: { "click": "handleCommentClick($event)", "touchstart": "handleTouchStart($event)", "touchend": "handleTouchEnd($event)", "touchmove": "handleTouchMove($event)", "contextmenu": "handleContextMenu($event)" }, properties: { "class.clickable": "clickable()" } }, ngImport: i0, template: `
2830
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: DsMobileCommentComponent, isStandalone: true, selector: "ds-mobile-comment", inputs: { authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: true, transformFunction: null }, authorRole: { classPropertyName: "authorRole", publicName: "authorRole", isSignal: true, isRequired: true, transformFunction: null }, timestamp: { classPropertyName: "timestamp", publicName: "timestamp", isSignal: true, isRequired: true, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: true, transformFunction: null }, avatarInitials: { classPropertyName: "avatarInitials", publicName: "avatarInitials", isSignal: true, isRequired: false, transformFunction: null }, avatarType: { classPropertyName: "avatarType", publicName: "avatarType", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, isOwnComment: { classPropertyName: "isOwnComment", publicName: "isOwnComment", isSignal: true, isRequired: false, transformFunction: null }, isLiked: { classPropertyName: "isLiked", publicName: "isLiked", isSignal: true, isRequired: false, transformFunction: null }, likeCount: { classPropertyName: "likeCount", publicName: "likeCount", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isLiked: "isLikedChange", likeToggled: "likeToggled", likeCount: "likeCountChange", commentClick: "commentClick", replyClick: "replyClick", editClick: "editClick", longPress: "longPress" }, host: { listeners: { "click": "handleCommentClick($event)", "touchstart": "handleTouchStart($event)", "touchend": "handleTouchEnd($event)", "touchmove": "handleTouchMove($event)", "contextmenu": "handleContextMenu($event)" }, properties: { "class.clickable": "clickable()" } }, ngImport: i0, template: `
2825
2831
  <div class="avatar-wrapper">
2826
- <ds-avatar
2827
- [initials]="avatarInitials()"
2828
- [type]="avatarType()"
2829
- size="sm" />
2832
+ <ds-avatar [initials]="avatarInitials()" [type]="avatarType()" size="sm" />
2830
2833
  </div>
2831
-
2834
+
2832
2835
  <div class="comment-content">
2833
2836
  <div class="comment-header">
2834
2837
  <span class="author-name">{{ authorName() }}</span>
2835
2838
  <span class="author-meta">{{ authorRole() }} · {{ timestamp() }}</span>
2836
-
2839
+
2837
2840
  <!-- Wrapper for like and more actions -->
2838
2841
  <div class="header-actions">
2839
- <div
2840
- class="action-like"
2841
- [class.active]="isLiked()"
2842
- (click)="toggleLike()">
2842
+ <div class="action-like" [class.active]="isLiked()" (click)="toggleLike()">
2843
2843
  <span class="like-count" [class.hidden]="likeCount() === 0">{{ likeCount() }}</span>
2844
2844
  <div class="icon-wrapper">
2845
- <ds-icon
2846
- class="icon-pulse"
2847
- [class.animating]="isPulsing()"
2848
- [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'"
2849
- size="16px" />
2850
- <ds-icon
2851
- [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'"
2852
- size="16px" />
2845
+ <ds-icon class="icon-pulse" [class.animating]="isPulsing()" [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'" size="16px" />
2846
+ <ds-icon [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'" size="16px" />
2853
2847
  </div>
2854
2848
  </div>
2855
-
2849
+
2856
2850
  <!-- Desktop more button -->
2857
- <ds-icon-button
2858
- class="desktop-more-button"
2859
- icon="remixMoreFill"
2860
- variant="secondary"
2861
- size="sm"
2862
- (clicked)="handleMoreButtonClick($event)"
2863
- aria-label="More options">
2851
+ <ds-icon-button class="desktop-more-button" icon="remixMoreFill" variant="secondary" size="sm" (clicked)="handleMoreButtonClick($event)" aria-label="More options">
2864
2852
  </ds-icon-button>
2865
2853
  </div>
2866
2854
  </div>
2867
-
2855
+
2868
2856
  <div class="comment-text" [innerHTML]="formattedContent()"></div>
2869
-
2857
+
2870
2858
  <div class="comment-actions">
2871
- <div class="action-reply" (click)="handleReply()">
2872
- Reply
2873
- </div>
2859
+ <div class="action-reply" (click)="handleReply()">Reply</div>
2874
2860
  @if (isOwnComment()) {
2875
- <div class="action-edit" (click)="handleEdit()">
2876
- Edit
2877
- </div>
2861
+ <div class="action-edit" (click)="handleEdit()">Edit</div>
2878
2862
  }
2879
2863
  </div>
2880
2864
  </div>
2881
- `, isInline: true, styles: [".author-details{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.author-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.author-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);display:flex;align-items:center;gap:6px}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.lightbox-context .author-name,.overlay-context .author-name{color:#fffffff2}.lightbox-context .author-meta,.overlay-context .author-meta{color:#ffffffb3}.lightbox-context .author-meta .separator,.overlay-context .author-meta .separator{color:#ffffff80}.section-headline{font-size:var(--font-size-sm);font-weight:600;color:var(--text-color-default-primary);padding:16px 0;margin:0;letter-spacing:-.2px;display:flex;align-items:center;gap:6px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--text-color-default-primary, #202227);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--text-color-default-secondary, #545B66);margin:0}\n", ":host{display:flex;gap:12px;padding:8px;position:relative;border-radius:16px;transition:all .2s ease;background:var(--color-background-primary, #ffffff);margin-bottom:8px;margin-left:-8px;margin-right:-8px}:host:last-child{margin-bottom:0}:host:after{content:\"\";position:absolute;bottom:-4px;left:44px;right:8px;height:1px;background:var(--border-color-default)}:host:last-child:after{display:none}:host.clickable{cursor:pointer}:host.clickable:active{background:var(--color-background-neutral-primary-hover, #f5f5f5)}.avatar-wrapper{position:relative;display:flex;align-items:flex-start;justify-content:center;flex-shrink:0}.comment-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.comment-header{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}.header-actions{display:flex;align-items:center;gap:4px;margin-left:auto}.desktop-more-button{display:none}.desktop-more-button::ng-deep button{border-radius:50%!important}@media (hover: hover) and (pointer: fine){.desktop-more-button{display:block}}.action-like{display:flex;align-items:center;gap:2px;color:var(--color-text-secondary, #737373);cursor:pointer;transition:color .2s ease;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:500;line-height:18px}.like-count{opacity:1}.like-count.hidden{opacity:0}.action-like.active{color:#f91880}.icon-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.icon-pulse{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;pointer-events:none}.icon-pulse.animating{animation:pulse .4s cubic-bezier(.4,0,.2,1)}@keyframes pulse{0%{transform:translate(-50%,-50%) scale(1);opacity:.8}to{transform:translate(-50%,-50%) scale(2.5);opacity:0}}.comment-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:22px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:pre-wrap;word-wrap:break-word}.comment-text ::ng-deep .mention{color:var(--color-brand-base, #6B5FF5)!important;font-weight:600}.comment-actions{display:flex;align-items:center;gap:12px;margin-top:4px}.action-reply{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-reply:hover{color:var(--color-text-primary, #1a1a1a)}.action-edit{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-edit:hover{color:var(--color-text-primary, #1a1a1a)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
2865
+ `, isInline: true, styles: [".author-details{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.author-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.author-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);display:flex;align-items:center;gap:6px}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.lightbox-context .author-name,.overlay-context .author-name{color:#fffffff2}.lightbox-context .author-meta,.overlay-context .author-meta{color:#ffffffb3}.lightbox-context .author-meta .separator,.overlay-context .author-meta .separator{color:#ffffff80}.section-headline{font-size:var(--font-size-sm);font-weight:600;color:var(--text-color-default-primary);padding:16px 0;margin:0;letter-spacing:-.2px;display:flex;align-items:center;gap:6px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--text-color-default-primary, #202227);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--text-color-default-secondary, #545B66);margin:0}\n", ":host{display:flex;gap:12px;padding:8px;position:relative;border-radius:16px;transition:all .2s ease;background:var(--color-background-primary, #ffffff);margin-bottom:8px;margin-left:-8px;margin-right:-8px}:host:last-child{margin-bottom:0}:host:after{content:\"\";position:absolute;bottom:-4px;left:44px;right:8px;height:1px;background:var(--border-color-default)}:host:last-child:after{display:none}:host.clickable{cursor:pointer}:host.clickable:active{background:var(--color-background-neutral-primary-hover, #f5f5f5)}.avatar-wrapper{position:relative;display:flex;align-items:flex-start;justify-content:center;flex-shrink:0}.comment-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.comment-header{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}.header-actions{display:flex;align-items:center;gap:4px;margin-left:auto}.desktop-more-button{display:none}.desktop-more-button::ng-deep button{border-radius:50%!important}@media (hover: hover) and (pointer: fine){.desktop-more-button{display:block}}.action-like{display:flex;align-items:center;gap:2px;color:var(--color-text-secondary, #737373);cursor:pointer;transition:color .2s ease;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:500;line-height:18px}.like-count{opacity:1}.like-count.hidden{opacity:0}.action-like.active{color:#f91880}.icon-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.icon-pulse{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;pointer-events:none}.icon-pulse.animating{animation:pulse .4s cubic-bezier(.4,0,.2,1)}@keyframes pulse{0%{transform:translate(-50%,-50%) scale(1);opacity:.8}to{transform:translate(-50%,-50%) scale(2.5);opacity:0}}.comment-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:22px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:pre-wrap;word-wrap:break-word}.comment-text ::ng-deep .mention{color:var(--color-brand-base, #6b5ff5)!important;font-weight:600}.comment-actions{display:flex;align-items:center;gap:12px;margin-top:4px}.action-reply{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-reply:hover{color:var(--color-text-primary, #1a1a1a)}.action-edit{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-edit:hover{color:var(--color-text-primary, #1a1a1a)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
2882
2866
  }
2883
2867
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DsMobileCommentComponent, decorators: [{
2884
2868
  type: Component,
@@ -2888,66 +2872,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
2888
2872
  '(touchstart)': 'handleTouchStart($event)',
2889
2873
  '(touchend)': 'handleTouchEnd($event)',
2890
2874
  '(touchmove)': 'handleTouchMove($event)',
2891
- '(contextmenu)': 'handleContextMenu($event)'
2875
+ '(contextmenu)': 'handleContextMenu($event)',
2892
2876
  }, template: `
2893
2877
  <div class="avatar-wrapper">
2894
- <ds-avatar
2895
- [initials]="avatarInitials()"
2896
- [type]="avatarType()"
2897
- size="sm" />
2878
+ <ds-avatar [initials]="avatarInitials()" [type]="avatarType()" size="sm" />
2898
2879
  </div>
2899
-
2880
+
2900
2881
  <div class="comment-content">
2901
2882
  <div class="comment-header">
2902
2883
  <span class="author-name">{{ authorName() }}</span>
2903
2884
  <span class="author-meta">{{ authorRole() }} · {{ timestamp() }}</span>
2904
-
2885
+
2905
2886
  <!-- Wrapper for like and more actions -->
2906
2887
  <div class="header-actions">
2907
- <div
2908
- class="action-like"
2909
- [class.active]="isLiked()"
2910
- (click)="toggleLike()">
2888
+ <div class="action-like" [class.active]="isLiked()" (click)="toggleLike()">
2911
2889
  <span class="like-count" [class.hidden]="likeCount() === 0">{{ likeCount() }}</span>
2912
2890
  <div class="icon-wrapper">
2913
- <ds-icon
2914
- class="icon-pulse"
2915
- [class.animating]="isPulsing()"
2916
- [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'"
2917
- size="16px" />
2918
- <ds-icon
2919
- [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'"
2920
- size="16px" />
2891
+ <ds-icon class="icon-pulse" [class.animating]="isPulsing()" [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'" size="16px" />
2892
+ <ds-icon [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'" size="16px" />
2921
2893
  </div>
2922
2894
  </div>
2923
-
2895
+
2924
2896
  <!-- Desktop more button -->
2925
- <ds-icon-button
2926
- class="desktop-more-button"
2927
- icon="remixMoreFill"
2928
- variant="secondary"
2929
- size="sm"
2930
- (clicked)="handleMoreButtonClick($event)"
2931
- aria-label="More options">
2897
+ <ds-icon-button class="desktop-more-button" icon="remixMoreFill" variant="secondary" size="sm" (clicked)="handleMoreButtonClick($event)" aria-label="More options">
2932
2898
  </ds-icon-button>
2933
2899
  </div>
2934
2900
  </div>
2935
-
2901
+
2936
2902
  <div class="comment-text" [innerHTML]="formattedContent()"></div>
2937
-
2903
+
2938
2904
  <div class="comment-actions">
2939
- <div class="action-reply" (click)="handleReply()">
2940
- Reply
2941
- </div>
2905
+ <div class="action-reply" (click)="handleReply()">Reply</div>
2942
2906
  @if (isOwnComment()) {
2943
- <div class="action-edit" (click)="handleEdit()">
2944
- Edit
2945
- </div>
2907
+ <div class="action-edit" (click)="handleEdit()">Edit</div>
2946
2908
  }
2947
2909
  </div>
2948
2910
  </div>
2949
- `, styles: [".author-details{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.author-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.author-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);display:flex;align-items:center;gap:6px}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.lightbox-context .author-name,.overlay-context .author-name{color:#fffffff2}.lightbox-context .author-meta,.overlay-context .author-meta{color:#ffffffb3}.lightbox-context .author-meta .separator,.overlay-context .author-meta .separator{color:#ffffff80}.section-headline{font-size:var(--font-size-sm);font-weight:600;color:var(--text-color-default-primary);padding:16px 0;margin:0;letter-spacing:-.2px;display:flex;align-items:center;gap:6px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--text-color-default-primary, #202227);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--text-color-default-secondary, #545B66);margin:0}\n", ":host{display:flex;gap:12px;padding:8px;position:relative;border-radius:16px;transition:all .2s ease;background:var(--color-background-primary, #ffffff);margin-bottom:8px;margin-left:-8px;margin-right:-8px}:host:last-child{margin-bottom:0}:host:after{content:\"\";position:absolute;bottom:-4px;left:44px;right:8px;height:1px;background:var(--border-color-default)}:host:last-child:after{display:none}:host.clickable{cursor:pointer}:host.clickable:active{background:var(--color-background-neutral-primary-hover, #f5f5f5)}.avatar-wrapper{position:relative;display:flex;align-items:flex-start;justify-content:center;flex-shrink:0}.comment-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.comment-header{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}.header-actions{display:flex;align-items:center;gap:4px;margin-left:auto}.desktop-more-button{display:none}.desktop-more-button::ng-deep button{border-radius:50%!important}@media (hover: hover) and (pointer: fine){.desktop-more-button{display:block}}.action-like{display:flex;align-items:center;gap:2px;color:var(--color-text-secondary, #737373);cursor:pointer;transition:color .2s ease;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:500;line-height:18px}.like-count{opacity:1}.like-count.hidden{opacity:0}.action-like.active{color:#f91880}.icon-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.icon-pulse{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;pointer-events:none}.icon-pulse.animating{animation:pulse .4s cubic-bezier(.4,0,.2,1)}@keyframes pulse{0%{transform:translate(-50%,-50%) scale(1);opacity:.8}to{transform:translate(-50%,-50%) scale(2.5);opacity:0}}.comment-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:22px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:pre-wrap;word-wrap:break-word}.comment-text ::ng-deep .mention{color:var(--color-brand-base, #6B5FF5)!important;font-weight:600}.comment-actions{display:flex;align-items:center;gap:12px;margin-top:4px}.action-reply{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-reply:hover{color:var(--color-text-primary, #1a1a1a)}.action-edit{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-edit:hover{color:var(--color-text-primary, #1a1a1a)}\n"] }]
2950
- }], propDecorators: { authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: true }] }], authorRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorRole", required: true }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: true }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: true }] }], avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarType: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarType", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], isOwnComment: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOwnComment", required: false }] }], isLiked: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLiked", required: false }] }, { type: i0.Output, args: ["isLikedChange"] }], likeCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "likeCount", required: false }] }, { type: i0.Output, args: ["likeCountChange"] }], commentClick: [{ type: i0.Output, args: ["commentClick"] }], replyClick: [{ type: i0.Output, args: ["replyClick"] }], editClick: [{ type: i0.Output, args: ["editClick"] }], longPress: [{ type: i0.Output, args: ["longPress"] }] } });
2911
+ `, styles: [".author-details{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.author-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.author-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);display:flex;align-items:center;gap:6px}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.lightbox-context .author-name,.overlay-context .author-name{color:#fffffff2}.lightbox-context .author-meta,.overlay-context .author-meta{color:#ffffffb3}.lightbox-context .author-meta .separator,.overlay-context .author-meta .separator{color:#ffffff80}.section-headline{font-size:var(--font-size-sm);font-weight:600;color:var(--text-color-default-primary);padding:16px 0;margin:0;letter-spacing:-.2px;display:flex;align-items:center;gap:6px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--text-color-default-primary, #202227);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--text-color-default-secondary, #545B66);margin:0}\n", ":host{display:flex;gap:12px;padding:8px;position:relative;border-radius:16px;transition:all .2s ease;background:var(--color-background-primary, #ffffff);margin-bottom:8px;margin-left:-8px;margin-right:-8px}:host:last-child{margin-bottom:0}:host:after{content:\"\";position:absolute;bottom:-4px;left:44px;right:8px;height:1px;background:var(--border-color-default)}:host:last-child:after{display:none}:host.clickable{cursor:pointer}:host.clickable:active{background:var(--color-background-neutral-primary-hover, #f5f5f5)}.avatar-wrapper{position:relative;display:flex;align-items:flex-start;justify-content:center;flex-shrink:0}.comment-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.comment-header{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}.header-actions{display:flex;align-items:center;gap:4px;margin-left:auto}.desktop-more-button{display:none}.desktop-more-button::ng-deep button{border-radius:50%!important}@media (hover: hover) and (pointer: fine){.desktop-more-button{display:block}}.action-like{display:flex;align-items:center;gap:2px;color:var(--color-text-secondary, #737373);cursor:pointer;transition:color .2s ease;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:500;line-height:18px}.like-count{opacity:1}.like-count.hidden{opacity:0}.action-like.active{color:#f91880}.icon-wrapper{position:relative;display:flex;align-items:center;justify-content:center}.icon-pulse{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;pointer-events:none}.icon-pulse.animating{animation:pulse .4s cubic-bezier(.4,0,.2,1)}@keyframes pulse{0%{transform:translate(-50%,-50%) scale(1);opacity:.8}to{transform:translate(-50%,-50%) scale(2.5);opacity:0}}.comment-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:22px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:pre-wrap;word-wrap:break-word}.comment-text ::ng-deep .mention{color:var(--color-brand-base, #6b5ff5)!important;font-weight:600}.comment-actions{display:flex;align-items:center;gap:12px;margin-top:4px}.action-reply{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-reply:hover{color:var(--color-text-primary, #1a1a1a)}.action-edit{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-text-secondary, #737373);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .2s ease}.action-edit:hover{color:var(--color-text-primary, #1a1a1a)}\n"] }]
2912
+ }], propDecorators: { authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: true }] }], authorRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorRole", required: true }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: true }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: true }] }], avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarType: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarType", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], isOwnComment: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOwnComment", required: false }] }], isLiked: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLiked", required: false }] }, { type: i0.Output, args: ["isLikedChange"] }], likeToggled: [{ type: i0.Output, args: ["likeToggled"] }], likeCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "likeCount", required: false }] }, { type: i0.Output, args: ["likeCountChange"] }], commentClick: [{ type: i0.Output, args: ["commentClick"] }], replyClick: [{ type: i0.Output, args: ["replyClick"] }], editClick: [{ type: i0.Output, args: ["editClick"] }], longPress: [{ type: i0.Output, args: ["longPress"] }] } });
2951
2913
 
2952
2914
  /**
2953
2915
  * DsMobilePostComposerComponent
@@ -6717,6 +6679,12 @@ class DsMobilePostDetailModalComponent {
6717
6679
  currentUserInitialsInput = '';
6718
6680
  // Callback for submitting a new comment
6719
6681
  onSubmitComment;
6682
+ // Callback for liking/unliking a comment
6683
+ onToggleCommentLike;
6684
+ // Callback for editing a comment
6685
+ onEditComment;
6686
+ // Callback for deleting a comment
6687
+ onDeleteComment;
6720
6688
  /**
6721
6689
  * Loading state - when true, shows loading indicator
6722
6690
  * Set this to true while fetching post data from your API
@@ -6740,7 +6708,7 @@ class DsMobilePostDetailModalComponent {
6740
6708
  }, ...(ngDevMode ? [{ debugName: "post" }] : []));
6741
6709
  // Comment composer state
6742
6710
  commentText = signal('', ...(ngDevMode ? [{ debugName: "commentText" }] : []));
6743
- currentUserInitials = signal('LM', ...(ngDevMode ? [{ debugName: "currentUserInitials" }] : []));
6711
+ currentUserInitials = signal('', ...(ngDevMode ? [{ debugName: "currentUserInitials" }] : []));
6744
6712
  replyingTo = signal(null, ...(ngDevMode ? [{ debugName: "replyingTo" }] : []));
6745
6713
  editingComment = signal(null, ...(ngDevMode ? [{ debugName: "editingComment" }] : []));
6746
6714
  // Mention menu state
@@ -6800,7 +6768,7 @@ class DsMobilePostDetailModalComponent {
6800
6768
  const initials = this.currentUserName
6801
6769
  .trim()
6802
6770
  .split(/\s+/)
6803
- .map(p => p[0])
6771
+ .map((p) => p[0])
6804
6772
  .join('')
6805
6773
  .substring(0, 2)
6806
6774
  .toUpperCase();
@@ -6931,17 +6899,22 @@ class DsMobilePostDetailModalComponent {
6931
6899
  /**
6932
6900
  * Handle edit comment
6933
6901
  */
6934
- handleEditComment(authorName, originalContent, timestamp) {
6902
+ handleEditComment(comment) {
6935
6903
  // Clear reply state if active
6936
6904
  this.replyingTo.set(null);
6937
6905
  // Remove @mention from the content if it exists
6938
- let contentToEdit = originalContent;
6939
- const mentionMatch = originalContent.match(/^@([A-Za-z]+(?:\s+[A-Za-z]+)?)\s+/);
6906
+ let contentToEdit = comment.content;
6907
+ const mentionMatch = contentToEdit.match(/^@([A-Za-z]+(?:\s+[A-Za-z]+)?)\s+/);
6940
6908
  if (mentionMatch) {
6941
- contentToEdit = originalContent.substring(mentionMatch[0].length);
6909
+ contentToEdit = contentToEdit.substring(mentionMatch[0].length);
6942
6910
  }
6943
6911
  // Set edit state
6944
- this.editingComment.set({ authorName, originalContent, timestamp });
6912
+ this.editingComment.set({
6913
+ id: comment.id,
6914
+ authorName: comment.authorName,
6915
+ originalContent: comment.content,
6916
+ timestamp: comment.timestamp,
6917
+ });
6945
6918
  // Populate the input with existing content
6946
6919
  this.commentText.set(contentToEdit);
6947
6920
  // Focus the input, show keyboard, and auto-resize
@@ -6956,6 +6929,27 @@ class DsMobilePostDetailModalComponent {
6956
6929
  }
6957
6930
  }, 100);
6958
6931
  }
6932
+ /**
6933
+ * Handle comment like/unlike toggle
6934
+ * @param comment The comment being liked/unliked
6935
+ * @param ev Event data with active state and new count
6936
+ */
6937
+ handleCommentLikeToggle(comment, ev) {
6938
+ // Update local state immediately for responsiveness
6939
+ const currentPost = this.post();
6940
+ const updatedComments = currentPost.comments?.map((c) => (c.id === comment.id ? { ...c, isLiked: ev.active, likeCount: ev.count } : c));
6941
+ this.post.set({
6942
+ ...currentPost,
6943
+ comments: updatedComments,
6944
+ });
6945
+ // Call the callback if provided
6946
+ if (this.onToggleCommentLike) {
6947
+ this.onToggleCommentLike({
6948
+ commentId: comment.id,
6949
+ active: ev.active,
6950
+ });
6951
+ }
6952
+ }
6959
6953
  /**
6960
6954
  * Close the modal
6961
6955
  */
@@ -6977,9 +6971,8 @@ class DsMobilePostDetailModalComponent {
6977
6971
  if (this.editingComment()) {
6978
6972
  console.log('[PostDetailModal] Updating comment:', text);
6979
6973
  const editing = this.editingComment();
6980
- // Update the existing comment
6981
6974
  const updatedComments = currentPost.comments?.map((comment) => {
6982
- if (comment.authorName === editing.authorName && comment.content === editing.originalContent && comment.timestamp === editing.timestamp) {
6975
+ if (comment.id && editing.id && comment.id === editing.id) {
6983
6976
  return {
6984
6977
  ...comment,
6985
6978
  content: text,
@@ -6992,7 +6985,13 @@ class DsMobilePostDetailModalComponent {
6992
6985
  ...currentPost,
6993
6986
  comments: updatedComments,
6994
6987
  });
6995
- // Clear edit state
6988
+ // Call the edit callback
6989
+ if (this.onEditComment && editing.id) {
6990
+ this.onEditComment({
6991
+ commentId: editing.id,
6992
+ newText: finalText, // or finalText if you want to include @mention
6993
+ });
6994
+ }
6996
6995
  this.editingComment.set(null);
6997
6996
  }
6998
6997
  else {
@@ -7091,19 +7090,29 @@ class DsMobilePostDetailModalComponent {
7091
7090
  switch (action) {
7092
7091
  case 'like':
7093
7092
  console.log('Like comment by', authorName);
7094
- // Find and toggle like on the comment
7093
+ let toggledCommentId = null;
7094
+ let newActive = false;
7095
+ // Update the comment like state locally
7095
7096
  const updatedComments = currentPost.comments?.map((comment) => {
7096
7097
  if (comment.authorName === authorName && comment.content === content) {
7097
- const isLiked = !comment.isLiked;
7098
+ newActive = !comment.isLiked;
7099
+ toggledCommentId = comment.id;
7098
7100
  return {
7099
7101
  ...comment,
7100
- isLiked,
7101
- likeCount: isLiked ? (comment.likeCount || 0) + 1 : Math.max(0, (comment.likeCount || 0) - 1),
7102
+ isLiked: newActive,
7103
+ likeCount: newActive ? (comment.likeCount || 0) + 1 : Math.max(0, (comment.likeCount || 0) - 1),
7102
7104
  };
7103
7105
  }
7104
7106
  return comment;
7105
7107
  });
7106
7108
  this.post.set({ ...currentPost, comments: updatedComments });
7109
+ // Call the like callback
7110
+ if (toggledCommentId && this.onToggleCommentLike) {
7111
+ this.onToggleCommentLike({
7112
+ commentId: toggledCommentId,
7113
+ active: newActive,
7114
+ });
7115
+ }
7107
7116
  break;
7108
7117
  case 'reply':
7109
7118
  console.log('Reply to comment by', authorName);
@@ -7114,26 +7123,31 @@ class DsMobilePostDetailModalComponent {
7114
7123
  // Find the full comment data to get timestamp
7115
7124
  const commentToEdit = currentPost.comments?.find((comment) => comment.authorName === authorName && comment.content === content);
7116
7125
  if (commentToEdit) {
7117
- this.handleEditComment(authorName, content, commentToEdit.timestamp);
7126
+ this.handleEditComment(commentToEdit);
7118
7127
  }
7119
7128
  break;
7120
7129
  case 'delete':
7121
7130
  console.log('Delete comment by', authorName);
7122
7131
  // Show confirmation before deleting
7123
7132
  if (confirm('Are you sure you want to delete this comment?')) {
7133
+ const commentToDelete = currentPost.comments?.find((comment) => comment.authorName === authorName && comment.content === content);
7124
7134
  const updatedCommentsAfterDelete = currentPost.comments?.filter((comment) => !(comment.authorName === authorName && comment.content === content));
7125
7135
  this.post.set({
7126
7136
  ...currentPost,
7127
7137
  comments: updatedCommentsAfterDelete,
7128
7138
  commentCount: updatedCommentsAfterDelete?.length || 0,
7129
7139
  });
7140
+ // Call the delete callback
7141
+ if (commentToDelete?.id && this.onDeleteComment) {
7142
+ this.onDeleteComment({ commentId: commentToDelete.id });
7143
+ }
7130
7144
  }
7131
7145
  break;
7132
7146
  }
7133
7147
  }
7134
7148
  }
7135
7149
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DsMobilePostDetailModalComponent, deps: [{ token: i1.ModalController }, { token: DsMobileLightboxService }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Component });
7136
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: DsMobilePostDetailModalComponent, isStandalone: true, selector: "ds-mobile-post-detail-modal", inputs: { postData: "postData", currentUserName: "currentUserName", currentUserInitialsInput: "currentUserInitialsInput", onSubmitComment: "onSubmitComment", loading: "loading", error: "error" }, viewQueries: [{ propertyName: "commentInput", first: true, predicate: ["commentInput"], descendants: true }], ngImport: i0, template: `
7150
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: DsMobilePostDetailModalComponent, isStandalone: true, selector: "ds-mobile-post-detail-modal", inputs: { postData: "postData", currentUserName: "currentUserName", currentUserInitialsInput: "currentUserInitialsInput", onSubmitComment: "onSubmitComment", onToggleCommentLike: "onToggleCommentLike", onEditComment: "onEditComment", onDeleteComment: "onDeleteComment", loading: "loading", error: "error" }, viewQueries: [{ propertyName: "commentInput", first: true, predicate: ["commentInput"], descendants: true }], ngImport: i0, template: `
7137
7151
  <ion-content [fullscreen]="true" [scrollY]="true" class="post-modal-content">
7138
7152
  <div class="post-modal-wrapper">
7139
7153
  <!-- Header with post author info -->
@@ -7199,7 +7213,7 @@ class DsMobilePostDetailModalComponent {
7199
7213
  <h2 class="comments-header">{{ post().comments!.length }} {{ post().comments!.length === 1 ? 'reply' : 'replies' }}</h2>
7200
7214
 
7201
7215
  <div class="comments-list">
7202
- @for (comment of post().comments!; track comment.authorName + comment.timestamp) {
7216
+ @for (comment of post().comments!; track comment.id || comment.authorName + comment.timestamp) {
7203
7217
  <ds-mobile-comment
7204
7218
  [authorName]="comment.authorName"
7205
7219
  [authorRole]="comment.authorRole"
@@ -7210,8 +7224,9 @@ class DsMobilePostDetailModalComponent {
7210
7224
  [likeCount]="comment.likeCount || 0"
7211
7225
  [clickable]="true"
7212
7226
  [isOwnComment]="comment.isOwnComment || false"
7227
+ (likeToggled)="handleCommentLikeToggle(comment, $event)"
7213
7228
  (replyClick)="handleReply(comment.authorName, comment.content)"
7214
- (editClick)="handleEditComment(comment.authorName, comment.content, comment.timestamp)"
7229
+ (editClick)="handleEditComment(comment)"
7215
7230
  (longPress)="handleCommentLongPress(comment.authorName, comment.content, comment.isOwnComment || false)" />
7216
7231
  }
7217
7232
  </div>
@@ -7284,7 +7299,8 @@ class DsMobilePostDetailModalComponent {
7284
7299
  #commentInput
7285
7300
  class="composer-input"
7286
7301
  [placeholder]="editingComment() ? 'Rediger din kommentar...' : replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...'"
7287
- [(ngModel)]="commentText"
7302
+ [ngModel]="commentText()"
7303
+ (ngModelChange)="commentText.set($event)"
7288
7304
  (input)="handleInput($event)"
7289
7305
  (focus)="showKeyboard()"
7290
7306
  (click)="showKeyboard()"
@@ -7297,7 +7313,7 @@ class DsMobilePostDetailModalComponent {
7297
7313
  </div>
7298
7314
  </div>
7299
7315
  }
7300
- `, isInline: true, styles: [".author-details{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.author-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.author-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);display:flex;align-items:center;gap:6px}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.lightbox-context .author-name,.overlay-context .author-name{color:#fffffff2}.lightbox-context .author-meta,.overlay-context .author-meta{color:#ffffffb3}.lightbox-context .author-meta .separator,.overlay-context .author-meta .separator{color:#ffffff80}.section-headline{font-size:var(--font-size-sm);font-weight:600;color:var(--text-color-default-primary);padding:16px 0;margin:0;letter-spacing:-.2px;display:flex;align-items:center;gap:6px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--text-color-default-primary, #202227);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--text-color-default-secondary, #545B66);margin:0}\n", ":host{display:block;position:relative;height:100%;width:100%}.post-modal-content{--background: var(--color-background-neutral-primary, #ffffff)}.post-modal-wrapper{display:flex;flex-direction:column;min-height:100%;min-height:100dvh;background:var(--color-background-neutral-primary, #ffffff)}.post-modal-header{position:sticky;top:0;z-index:10;background:var(--color-background-neutral-primary, #ffffff);border-bottom:1px solid var(--border-color-default);padding:0 16px}.header-content{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:72px}.post-author-info{display:flex;align-items:center;gap:12px;flex:1;min-width:0}.author-details{display:flex;flex-direction:column;min-width:0;flex:1}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.close-button{flex-shrink:0;border-radius:50%}.close-button::ng-deep button{border-radius:50%!important;width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important}.post-detail-container{display:flex;flex-direction:column;gap:16px;width:100%;max-width:640px;margin:0 auto;padding:16px 0 20px;flex:1}.post-section{width:100%;border-bottom:1px solid var(--border-color-default);padding:0 0 16px}.post-content-only{font-size:var(--font-size-sm);line-height:24px;color:var(--color-text-primary, #1a1a1a);margin-bottom:16px;padding:0 20px}.post-content-only post-media{margin-top:16px}.post-actions{display:flex;align-items:center;gap:16px;padding:0 20px}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.comments-section{display:flex;flex-direction:column;margin-left:0;margin-right:0;padding:0 20px}.comments-header{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:24px;color:var(--color-text-primary, #1a1a1a);margin:0 0 16px;padding-left:0;padding-right:0}.comments-list{display:flex;flex-direction:column}.comments-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}.composer-spacer{height:calc(81px + env(safe-area-inset-bottom,0px))}.bottom-spacer{height:0px}.comment-composer-fixed{position:fixed;bottom:0;left:0;right:0;z-index:1000;pointer-events:none;transform:translateY(calc(-1 * var(--keyboard-height, 0px)));transition:transform .3s ease-out;max-width:100vw}.comment-composer{pointer-events:auto;background:var(--color-background-neutral-primary, #ffffff);border-top:1px solid var(--border-color-default);padding:12px 16px;padding-bottom:max(12px,env(safe-area-inset-bottom,0px));width:100%;display:flex;flex-direction:column;gap:8px;box-shadow:100px 150px 0 150px var(--color-background-neutral-primary, #ffffff)}.edit-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-brand-subtle, #f0edfe);border-radius:8px;animation:slideDown .2s ease-out}.edit-indicator-content{display:flex;align-items:center;gap:8px;color:var(--color-brand-base, #6b5ff5);flex:1;min-width:0}.edit-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-brand-base, #6b5ff5)}.cancel-edit{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-brand-base, #6b5ff5);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-edit:active{background:var(--color-brand-subtle, #e0dbfe)}.reply-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:8px;animation:slideDown .2s ease-out}.reply-indicator-content{display:flex;align-items:center;gap:4px;color:var(--color-text-secondary, #737373);flex:1;min-width:0}.reply-to-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.reply-author{color:var(--color-brand-base, #6b5ff5);font-weight:600}.cancel-reply{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary, #737373);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-reply:active{background:var(--color-background-neutral-secondary, #f5f5f5)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.composer-content{display:flex;align-items:flex-start;gap:12px;width:100%;position:relative}.composer-content ds-avatar{position:relative;top:6px}.composer-input-wrapper{flex:1;display:flex;align-items:flex-start;gap:8px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:24px;padding:12px 48px 12px 16px;min-height:44px;position:relative}.mention-menu{position:absolute;bottom:100%;left:0;right:0;background:var(--color-background-neutral-primary, #ffffff);border-radius:12px;box-shadow:0 4px 12px #00000026;margin-bottom:8px;max-height:200px;overflow-y:auto;z-index:10;animation:slideUp .2s ease-out}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.mention-menu-item{display:flex;align-items:center;gap:12px;padding:12px;border:none;background:none;width:100%;text-align:left;cursor:pointer;transition:background .2s ease;border-bottom:1px solid var(--border-color-default)}.mention-menu-item:last-child{border-bottom:none}.mention-menu-item:active{background:var(--color-background-neutral-secondary, #f5f5f5)}.mention-user-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.mention-user-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:20px;color:var(--color-text-primary, #1a1a1a)}.mention-user-role{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373)}.composer-input{flex:1;border:none;background:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:20px;color:var(--color-text-primary, #1a1a1a);outline:none;resize:none;min-height:20px;max-height:120px;overflow-y:auto;padding:0;margin:0}.composer-input::placeholder{color:var(--color-text-tertiary, #a0a0a0);font-size:var(--font-size-sm)}.send-button-fixed{position:absolute;top:6px;right:6px;z-index:10;flex-shrink:0;animation:slideInFromRight .2s ease-out}.send-button-fixed::ng-deep button{width:32px!important;height:32px!important;min-width:32px!important;min-height:32px!important;padding:0!important;border-radius:50%!important}.composer-input-wrapper ds-icon-button{flex-shrink:0;animation:slideInFromRight .2s ease-out}.composer-input-wrapper ds-icon-button::ng-deep button{width:32px!important;height:32px!important;min-width:32px!important;min-height:32px!important;padding:0!important;border-radius:50%!important}@keyframes slideInFromRight{0%{opacity:0;transform:translate(20px) scale(.8)}to{opacity:1;transform:translate(0) scale(1)}}@supports (padding: env(safe-area-inset-bottom)){.post-detail-container{padding-bottom:calc(20px + env(safe-area-inset-bottom))}}.post-loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.loading-spinner{width:48px;height:48px;border:3px solid var(--color-background-neutral-secondary, #f0f0f0);border-top-color:var(--color-primary-base, #2563eb);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin-top:16px}.post-error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:16px}.error-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0}.error-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCommentComponent, selector: "ds-mobile-comment", inputs: ["authorName", "authorRole", "timestamp", "content", "avatarInitials", "avatarType", "clickable", "isOwnComment", "isLiked", "likeCount"], outputs: ["isLikedChange", "likeCountChange", "commentClick", "replyClick", "editClick", "longPress"] }] });
7316
+ `, isInline: true, styles: [".author-details{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.author-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.author-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);display:flex;align-items:center;gap:6px}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.lightbox-context .author-name,.overlay-context .author-name{color:#fffffff2}.lightbox-context .author-meta,.overlay-context .author-meta{color:#ffffffb3}.lightbox-context .author-meta .separator,.overlay-context .author-meta .separator{color:#ffffff80}.section-headline{font-size:var(--font-size-sm);font-weight:600;color:var(--text-color-default-primary);padding:16px 0;margin:0;letter-spacing:-.2px;display:flex;align-items:center;gap:6px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--text-color-default-primary, #202227);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--text-color-default-secondary, #545B66);margin:0}\n", ":host{display:block;position:relative;height:100%;width:100%}.post-modal-content{--background: var(--color-background-neutral-primary, #ffffff)}.post-modal-wrapper{display:flex;flex-direction:column;min-height:100%;min-height:100dvh;background:var(--color-background-neutral-primary, #ffffff)}.post-modal-header{position:sticky;top:0;z-index:10;background:var(--color-background-neutral-primary, #ffffff);border-bottom:1px solid var(--border-color-default);padding:0 16px}.header-content{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:72px}.post-author-info{display:flex;align-items:center;gap:12px;flex:1;min-width:0}.author-details{display:flex;flex-direction:column;min-width:0;flex:1}.author-meta .separator{color:var(--color-text-tertiary, #a0a0a0)}.close-button{flex-shrink:0;border-radius:50%}.close-button::ng-deep button{border-radius:50%!important;width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important}.post-detail-container{display:flex;flex-direction:column;gap:16px;width:100%;max-width:640px;margin:0 auto;padding:16px 0 20px;flex:1}.post-section{width:100%;border-bottom:1px solid var(--border-color-default);padding:0 0 16px}.post-content-only{font-size:var(--font-size-sm);line-height:24px;color:var(--color-text-primary, #1a1a1a);margin-bottom:16px;padding:0 20px}.post-content-only post-media{margin-top:16px}.post-actions{display:flex;align-items:center;gap:16px;padding:0 20px}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.comments-section{display:flex;flex-direction:column;margin-left:0;margin-right:0;padding:0 20px}.comments-header{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:24px;color:var(--color-text-primary, #1a1a1a);margin:0 0 16px;padding-left:0;padding-right:0}.comments-list{display:flex;flex-direction:column}.comments-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}.composer-spacer{height:calc(81px + env(safe-area-inset-bottom,0px))}.bottom-spacer{height:0px}.comment-composer-fixed{position:fixed;bottom:0;left:0;right:0;z-index:1000;pointer-events:none;transform:translateY(calc(-1 * var(--keyboard-height, 0px)));transition:transform .3s ease-out;max-width:100vw}.comment-composer{pointer-events:auto;background:var(--color-background-neutral-primary, #ffffff);border-top:1px solid var(--border-color-default);padding:12px 16px;padding-bottom:max(12px,env(safe-area-inset-bottom,0px));width:100%;display:flex;flex-direction:column;gap:8px;box-shadow:100px 150px 0 150px var(--color-background-neutral-primary, #ffffff)}.edit-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-brand-subtle, #f0edfe);border-radius:8px;animation:slideDown .2s ease-out}.edit-indicator-content{display:flex;align-items:center;gap:8px;color:var(--color-brand-base, #6b5ff5);flex:1;min-width:0}.edit-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:18px;color:var(--color-brand-base, #6b5ff5)}.cancel-edit{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-brand-base, #6b5ff5);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-edit:active{background:var(--color-brand-subtle, #e0dbfe)}.reply-indicator{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:8px;animation:slideDown .2s ease-out}.reply-indicator-content{display:flex;align-items:center;gap:4px;color:var(--color-text-secondary, #737373);flex:1;min-width:0}.reply-to-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.reply-author{color:var(--color-brand-base, #6b5ff5);font-weight:600}.cancel-reply{background:none;border:none;padding:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-text-secondary, #737373);border-radius:4px;transition:background .2s ease;flex-shrink:0}.cancel-reply:active{background:var(--color-background-neutral-secondary, #f5f5f5)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.composer-content{display:flex;align-items:flex-start;gap:12px;width:100%;position:relative}.composer-content ds-avatar{position:relative;top:6px}.composer-input-wrapper{flex:1;display:flex;align-items:flex-start;gap:8px;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:24px;padding:12px 48px 12px 16px;min-height:44px;position:relative}.mention-menu{position:absolute;bottom:100%;left:0;right:0;background:var(--color-background-neutral-primary, #ffffff);border-radius:12px;box-shadow:0 4px 12px #00000026;margin-bottom:8px;max-height:200px;overflow-y:auto;z-index:10;animation:slideUp .2s ease-out}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.mention-menu-item{display:flex;align-items:center;gap:12px;padding:12px;border:none;background:none;width:100%;text-align:left;cursor:pointer;transition:background .2s ease;border-bottom:1px solid var(--border-color-default)}.mention-menu-item:last-child{border-bottom:none}.mention-menu-item:active{background:var(--color-background-neutral-secondary, #f5f5f5)}.mention-user-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.mention-user-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:20px;color:var(--color-text-primary, #1a1a1a)}.mention-user-role{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:18px;color:var(--color-text-secondary, #737373)}.composer-input{flex:1;border:none;background:transparent;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);line-height:20px;color:var(--color-text-primary, #1a1a1a);outline:none;resize:none;min-height:20px;max-height:120px;overflow-y:auto;padding:0;margin:0}.composer-input::placeholder{color:var(--color-text-tertiary, #a0a0a0);font-size:var(--font-size-sm)}.send-button-fixed{position:absolute;top:6px;right:6px;z-index:10;flex-shrink:0;animation:slideInFromRight .2s ease-out}.send-button-fixed::ng-deep button{width:32px!important;height:32px!important;min-width:32px!important;min-height:32px!important;padding:0!important;border-radius:50%!important}.composer-input-wrapper ds-icon-button{flex-shrink:0;animation:slideInFromRight .2s ease-out}.composer-input-wrapper ds-icon-button::ng-deep button{width:32px!important;height:32px!important;min-width:32px!important;min-height:32px!important;padding:0!important;border-radius:50%!important}@keyframes slideInFromRight{0%{opacity:0;transform:translate(20px) scale(.8)}to{opacity:1;transform:translate(0) scale(1)}}@supports (padding: env(safe-area-inset-bottom)){.post-detail-container{padding-bottom:calc(20px + env(safe-area-inset-bottom))}}.post-loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.loading-spinner{width:48px;height:48px;border:3px solid var(--color-background-neutral-secondary, #f0f0f0);border-top-color:var(--color-primary-base, #2563eb);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin-top:16px}.post-error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:16px}.error-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0}.error-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCommentComponent, selector: "ds-mobile-comment", inputs: ["authorName", "authorRole", "timestamp", "content", "avatarInitials", "avatarType", "clickable", "isOwnComment", "isLiked", "likeCount"], outputs: ["isLikedChange", "likeToggled", "likeCountChange", "commentClick", "replyClick", "editClick", "longPress"] }] });
7301
7317
  }
7302
7318
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DsMobilePostDetailModalComponent, decorators: [{
7303
7319
  type: Component,
@@ -7379,7 +7395,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
7379
7395
  <h2 class="comments-header">{{ post().comments!.length }} {{ post().comments!.length === 1 ? 'reply' : 'replies' }}</h2>
7380
7396
 
7381
7397
  <div class="comments-list">
7382
- @for (comment of post().comments!; track comment.authorName + comment.timestamp) {
7398
+ @for (comment of post().comments!; track comment.id || comment.authorName + comment.timestamp) {
7383
7399
  <ds-mobile-comment
7384
7400
  [authorName]="comment.authorName"
7385
7401
  [authorRole]="comment.authorRole"
@@ -7390,8 +7406,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
7390
7406
  [likeCount]="comment.likeCount || 0"
7391
7407
  [clickable]="true"
7392
7408
  [isOwnComment]="comment.isOwnComment || false"
7409
+ (likeToggled)="handleCommentLikeToggle(comment, $event)"
7393
7410
  (replyClick)="handleReply(comment.authorName, comment.content)"
7394
- (editClick)="handleEditComment(comment.authorName, comment.content, comment.timestamp)"
7411
+ (editClick)="handleEditComment(comment)"
7395
7412
  (longPress)="handleCommentLongPress(comment.authorName, comment.content, comment.isOwnComment || false)" />
7396
7413
  }
7397
7414
  </div>
@@ -7464,7 +7481,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
7464
7481
  #commentInput
7465
7482
  class="composer-input"
7466
7483
  [placeholder]="editingComment() ? 'Rediger din kommentar...' : replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...'"
7467
- [(ngModel)]="commentText"
7484
+ [ngModel]="commentText()"
7485
+ (ngModelChange)="commentText.set($event)"
7468
7486
  (input)="handleInput($event)"
7469
7487
  (focus)="showKeyboard()"
7470
7488
  (click)="showKeyboard()"
@@ -7486,6 +7504,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
7486
7504
  type: Input
7487
7505
  }], onSubmitComment: [{
7488
7506
  type: Input
7507
+ }], onToggleCommentLike: [{
7508
+ type: Input
7509
+ }], onEditComment: [{
7510
+ type: Input
7511
+ }], onDeleteComment: [{
7512
+ type: Input
7489
7513
  }], loading: [{
7490
7514
  type: Input
7491
7515
  }], error: [{
@@ -7560,8 +7584,9 @@ class DsMobilePostDetailModalService {
7560
7584
  loading: options?.loading ?? false,
7561
7585
  error: options?.error,
7562
7586
  onSubmitComment: options?.onSubmitComment,
7587
+ onToggleCommentLike: options?.onToggleCommentLike,
7563
7588
  currentUserName: options?.currentUserName ?? '',
7564
- currentUserInitials: options?.currentUserInitials ?? '',
7589
+ currentUserInitialsInput: options?.currentUserInitials ?? '',
7565
7590
  },
7566
7591
  cssClass: 'ds-post-detail-modal',
7567
7592
  mode: 'ios',
@@ -12690,7 +12715,7 @@ class MobilePostDetailPageComponent {
12690
12715
  </div>
12691
12716
  </div>
12692
12717
  </ds-mobile-page-details>
12693
- `, isInline: true, styles: [".post-detail-container{display:flex;flex-direction:column;gap:16px;max-width:640px}.post-section{border-bottom:1px solid var(--border-color-default);padding-bottom:16px}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.comments-section{display:flex;flex-direction:column;margin-left:-8px;margin-right:-8px}.comments-header{font-family:Brockmann,sans-serif;font-size:18px;font-weight:600;line-height:24px;color:var(--color-text-primary, #1a1a1a);margin-bottom:16px;padding-left:8px;padding-right:8px}.comments-list{display:flex;flex-direction:column}\n"], dependencies: [{ kind: "component", type: DsMobilePageDetailsComponent, selector: "ds-mobile-page-details", inputs: ["title", "backRoute"], outputs: ["back"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "clickable"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCommentComponent, selector: "ds-mobile-comment", inputs: ["authorName", "authorRole", "timestamp", "content", "avatarInitials", "avatarType", "clickable", "isOwnComment", "isLiked", "likeCount"], outputs: ["isLikedChange", "likeCountChange", "commentClick", "replyClick", "editClick", "longPress"] }] });
12718
+ `, isInline: true, styles: [".post-detail-container{display:flex;flex-direction:column;gap:16px;max-width:640px}.post-section{border-bottom:1px solid var(--border-color-default);padding-bottom:16px}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.comments-section{display:flex;flex-direction:column;margin-left:-8px;margin-right:-8px}.comments-header{font-family:Brockmann,sans-serif;font-size:18px;font-weight:600;line-height:24px;color:var(--color-text-primary, #1a1a1a);margin-bottom:16px;padding-left:8px;padding-right:8px}.comments-list{display:flex;flex-direction:column}\n"], dependencies: [{ kind: "component", type: DsMobilePageDetailsComponent, selector: "ds-mobile-page-details", inputs: ["title", "backRoute"], outputs: ["back"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "clickable"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCommentComponent, selector: "ds-mobile-comment", inputs: ["authorName", "authorRole", "timestamp", "content", "avatarInitials", "avatarType", "clickable", "isOwnComment", "isLiked", "likeCount"], outputs: ["isLikedChange", "likeToggled", "likeCountChange", "commentClick", "replyClick", "editClick", "longPress"] }] });
12694
12719
  }
12695
12720
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: MobilePostDetailPageComponent, decorators: [{
12696
12721
  type: Component,