@awiki/dsh-plugin 0.3.0-rc.1 → 0.3.0-rc.2

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.
Files changed (71) hide show
  1. package/README.md +8 -7
  2. package/README.zh.md +7 -3
  3. package/lib/client.js +1608 -478
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +373 -36
  6. package/lib/provider.js +1 -1
  7. package/lib/{sdk-adapter-DLhLrLI6.mjs → sdk-adapter-BIbsJmRj.mjs} +28 -4
  8. package/lib/typert.host.js +221 -81
  9. package/lib/typert.remote-client.d.ts +5 -1
  10. package/lib/typert.remote-client.d.ts.map +1 -1
  11. package/lib/typert.remote-client.js +221 -81
  12. package/lib/types/client/AwikiGroupAccessNotice.d.ts +12 -0
  13. package/lib/types/client/AwikiGroupAccessNotice.d.ts.map +1 -0
  14. package/lib/types/client/AwikiGroupAccessNotice.js +31 -0
  15. package/lib/types/client/AwikiGroupAccessNotice.js.map +1 -0
  16. package/lib/types/client/AwikiGroupDetails.d.ts +8 -1
  17. package/lib/types/client/AwikiGroupDetails.d.ts.map +1 -1
  18. package/lib/types/client/AwikiGroupDetails.js +40 -4
  19. package/lib/types/client/AwikiGroupDetails.js.map +1 -1
  20. package/lib/types/client/AwikiIdentityAccess.d.ts +2 -1
  21. package/lib/types/client/AwikiIdentityAccess.d.ts.map +1 -1
  22. package/lib/types/client/AwikiIdentityAccess.js +10 -2
  23. package/lib/types/client/AwikiIdentityAccess.js.map +1 -1
  24. package/lib/types/client/AwikiMail.d.ts.map +1 -1
  25. package/lib/types/client/AwikiMail.js +5 -1
  26. package/lib/types/client/AwikiMail.js.map +1 -1
  27. package/lib/types/client/AwikiOnboarding.d.ts.map +1 -1
  28. package/lib/types/client/AwikiOnboarding.js +4 -1
  29. package/lib/types/client/AwikiOnboarding.js.map +1 -1
  30. package/lib/types/client/AwikiOverlay.d.ts.map +1 -1
  31. package/lib/types/client/AwikiOverlay.js +72 -11
  32. package/lib/types/client/AwikiOverlay.js.map +1 -1
  33. package/lib/types/client/AwikiRecoveryForm.d.ts +3 -0
  34. package/lib/types/client/AwikiRecoveryForm.d.ts.map +1 -1
  35. package/lib/types/client/AwikiRecoveryForm.js +10 -6
  36. package/lib/types/client/AwikiRecoveryForm.js.map +1 -1
  37. package/lib/types/client/AwikiSettingsSection.d.ts.map +1 -1
  38. package/lib/types/client/AwikiSettingsSection.js +5 -1
  39. package/lib/types/client/AwikiSettingsSection.js.map +1 -1
  40. package/lib/types/client/controller.d.ts +38 -2
  41. package/lib/types/client/controller.d.ts.map +1 -1
  42. package/lib/types/client/controller.js +473 -47
  43. package/lib/types/client/controller.js.map +1 -1
  44. package/lib/types/client/index.d.ts.map +1 -1
  45. package/lib/types/client/index.js +3 -0
  46. package/lib/types/client/index.js.map +1 -1
  47. package/lib/types/client/recharge-availability.d.ts +1 -1
  48. package/lib/types/client/recharge-availability.d.ts.map +1 -1
  49. package/lib/types/client/recharge-availability.js +1 -1
  50. package/lib/types/client/recharge-availability.js.map +1 -1
  51. package/lib/types/client/settings-locales.d.ts +1 -1
  52. package/lib/types/client/settings-locales.d.ts.map +1 -1
  53. package/lib/types/client/settings-locales.js +6 -0
  54. package/lib/types/client/settings-locales.js.map +1 -1
  55. package/lib/types/client/slots.d.ts +6 -0
  56. package/lib/types/client/slots.d.ts.map +1 -1
  57. package/lib/types/conversation-preferences.d.ts +20 -0
  58. package/lib/types/conversation-preferences.d.ts.map +1 -0
  59. package/lib/types/conversation-preferences.js +294 -0
  60. package/lib/types/conversation-preferences.js.map +1 -0
  61. package/lib/types/index.d.ts +6 -1
  62. package/lib/types/index.d.ts.map +1 -1
  63. package/lib/types/index.js +39 -0
  64. package/lib/types/index.js.map +1 -1
  65. package/lib/types/sdk-adapter.d.ts.map +1 -1
  66. package/lib/types/sdk-adapter.js +35 -4
  67. package/lib/types/sdk-adapter.js.map +1 -1
  68. package/lib/types/types.d.ts +32 -1
  69. package/lib/types/types.d.ts.map +1 -1
  70. package/lib/types/types.js.map +1 -1
  71. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -4132,6 +4132,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4132
4132
  literal("handle-unavailable"),
4133
4133
  literal("not-found"),
4134
4134
  literal("forbidden"),
4135
+ literal("identity-recovery-required"),
4135
4136
  literal("conflict"),
4136
4137
  literal("rate-limited"),
4137
4138
  literal("group-membership-required"),
@@ -4190,6 +4191,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4190
4191
  literal("handle-unavailable"),
4191
4192
  literal("not-found"),
4192
4193
  literal("forbidden"),
4194
+ literal("identity-recovery-required"),
4193
4195
  literal("conflict"),
4194
4196
  literal("rate-limited"),
4195
4197
  literal("group-membership-required"),
@@ -4227,6 +4229,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4227
4229
  literal("handle-unavailable"),
4228
4230
  literal("not-found"),
4229
4231
  literal("forbidden"),
4232
+ literal("identity-recovery-required"),
4230
4233
  literal("conflict"),
4231
4234
  literal("rate-limited"),
4232
4235
  literal("group-membership-required"),
@@ -4264,6 +4267,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4264
4267
  literal("handle-unavailable"),
4265
4268
  literal("not-found"),
4266
4269
  literal("forbidden"),
4270
+ literal("identity-recovery-required"),
4267
4271
  literal("conflict"),
4268
4272
  literal("rate-limited"),
4269
4273
  literal("group-membership-required"),
@@ -4309,6 +4313,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4309
4313
  literal("handle-unavailable"),
4310
4314
  literal("not-found"),
4311
4315
  literal("forbidden"),
4316
+ literal("identity-recovery-required"),
4312
4317
  literal("conflict"),
4313
4318
  literal("rate-limited"),
4314
4319
  literal("group-membership-required"),
@@ -4342,6 +4347,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4342
4347
  literal("handle-unavailable"),
4343
4348
  literal("not-found"),
4344
4349
  literal("forbidden"),
4350
+ literal("identity-recovery-required"),
4345
4351
  literal("conflict"),
4346
4352
  literal("rate-limited"),
4347
4353
  literal("group-membership-required"),
@@ -4379,6 +4385,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4379
4385
  literal("handle-unavailable"),
4380
4386
  literal("not-found"),
4381
4387
  literal("forbidden"),
4388
+ literal("identity-recovery-required"),
4382
4389
  literal("conflict"),
4383
4390
  literal("rate-limited"),
4384
4391
  literal("group-membership-required"),
@@ -4421,6 +4428,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4421
4428
  literal("handle-unavailable"),
4422
4429
  literal("not-found"),
4423
4430
  literal("forbidden"),
4431
+ literal("identity-recovery-required"),
4424
4432
  literal("conflict"),
4425
4433
  literal("rate-limited"),
4426
4434
  literal("group-membership-required"),
@@ -4444,6 +4452,64 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4444
4452
  "attachmentMaxBytes": number().readonly()
4445
4453
  }).readonly()
4446
4454
  })]);
4455
+ const _awiki_dsh_plugin_awiki_getConversationPreferences_result$schema = union([object({
4456
+ "ok": literal(false).readonly(),
4457
+ "error": object({
4458
+ "code": union([
4459
+ literal("not-registered"),
4460
+ literal("signed-out"),
4461
+ literal("already-registered"),
4462
+ literal("invalid-request"),
4463
+ literal("invalid-otp"),
4464
+ literal("challenge-expired"),
4465
+ literal("handle-unavailable"),
4466
+ literal("not-found"),
4467
+ literal("forbidden"),
4468
+ literal("identity-recovery-required"),
4469
+ literal("conflict"),
4470
+ literal("rate-limited"),
4471
+ literal("group-membership-required"),
4472
+ literal("group-identity-stale"),
4473
+ literal("attachment-too-large"),
4474
+ literal("summary-unavailable"),
4475
+ literal("summary-timeout"),
4476
+ literal("summary-cancelled"),
4477
+ literal("summary-invalid-output"),
4478
+ literal("summary-failed"),
4479
+ literal("delivery-unknown"),
4480
+ literal("network"),
4481
+ literal("remote")
4482
+ ]).readonly(),
4483
+ "message": string().readonly()
4484
+ }).readonly()
4485
+ }), object({
4486
+ "ok": literal(true).readonly(),
4487
+ "value": object({
4488
+ "hiddenConversations": array(object({
4489
+ "conversation": union([object({
4490
+ "kind": literal("group").readonly(),
4491
+ "id": intersection(string(), unknown()).readonly(),
4492
+ "groupDid": intersection(string(), unknown()).readonly(),
4493
+ "title": string().readonly(),
4494
+ "unreadCount": number().readonly().optional(),
4495
+ "lastMessageAt": number().readonly().optional(),
4496
+ "lastMessagePreview": string().readonly().optional()
4497
+ }), object({
4498
+ "kind": literal("direct").readonly(),
4499
+ "id": intersection(string(), unknown()).readonly(),
4500
+ "peerDid": intersection(string(), unknown()).readonly(),
4501
+ "peerHandle": intersection(string(), unknown()).readonly().optional(),
4502
+ "displayName": string().readonly().optional(),
4503
+ "title": string().readonly(),
4504
+ "unreadCount": number().readonly().optional(),
4505
+ "lastMessageAt": number().readonly().optional(),
4506
+ "lastMessagePreview": string().readonly().optional()
4507
+ })]).readonly(),
4508
+ "hiddenAt": number().readonly()
4509
+ })).readonly(),
4510
+ "dismissedGroupRecoverySignature": string().readonly().optional()
4511
+ }).readonly()
4512
+ })]);
4447
4513
  const _awiki_dsh_plugin_awiki_getGroup_parameter_0$schema = object({ "groupDid": intersection(string(), unknown()).readonly() });
4448
4514
  const _awiki_dsh_plugin_awiki_getGroup_result$schema = union([object({
4449
4515
  "ok": literal(false).readonly(),
@@ -4458,6 +4524,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4458
4524
  literal("handle-unavailable"),
4459
4525
  literal("not-found"),
4460
4526
  literal("forbidden"),
4527
+ literal("identity-recovery-required"),
4461
4528
  literal("conflict"),
4462
4529
  literal("rate-limited"),
4463
4530
  literal("group-membership-required"),
@@ -4504,6 +4571,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4504
4571
  literal("handle-unavailable"),
4505
4572
  literal("not-found"),
4506
4573
  literal("forbidden"),
4574
+ literal("identity-recovery-required"),
4507
4575
  literal("conflict"),
4508
4576
  literal("rate-limited"),
4509
4577
  literal("group-membership-required"),
@@ -4571,6 +4639,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4571
4639
  literal("handle-unavailable"),
4572
4640
  literal("not-found"),
4573
4641
  literal("forbidden"),
4642
+ literal("identity-recovery-required"),
4574
4643
  literal("conflict"),
4575
4644
  literal("rate-limited"),
4576
4645
  literal("group-membership-required"),
@@ -4614,6 +4683,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4614
4683
  literal("handle-unavailable"),
4615
4684
  literal("not-found"),
4616
4685
  literal("forbidden"),
4686
+ literal("identity-recovery-required"),
4617
4687
  literal("conflict"),
4618
4688
  literal("rate-limited"),
4619
4689
  literal("group-membership-required"),
@@ -4681,6 +4751,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4681
4751
  literal("handle-unavailable"),
4682
4752
  literal("not-found"),
4683
4753
  literal("forbidden"),
4754
+ literal("identity-recovery-required"),
4684
4755
  literal("conflict"),
4685
4756
  literal("rate-limited"),
4686
4757
  literal("group-membership-required"),
@@ -4718,6 +4789,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4718
4789
  literal("handle-unavailable"),
4719
4790
  literal("not-found"),
4720
4791
  literal("forbidden"),
4792
+ literal("identity-recovery-required"),
4721
4793
  literal("conflict"),
4722
4794
  literal("rate-limited"),
4723
4795
  literal("group-membership-required"),
@@ -4759,6 +4831,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4759
4831
  literal("handle-unavailable"),
4760
4832
  literal("not-found"),
4761
4833
  literal("forbidden"),
4834
+ literal("identity-recovery-required"),
4762
4835
  literal("conflict"),
4763
4836
  literal("rate-limited"),
4764
4837
  literal("group-membership-required"),
@@ -4812,6 +4885,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4812
4885
  literal("handle-unavailable"),
4813
4886
  literal("not-found"),
4814
4887
  literal("forbidden"),
4888
+ literal("identity-recovery-required"),
4815
4889
  literal("conflict"),
4816
4890
  literal("rate-limited"),
4817
4891
  literal("group-membership-required"),
@@ -4858,6 +4932,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4858
4932
  literal("handle-unavailable"),
4859
4933
  literal("not-found"),
4860
4934
  literal("forbidden"),
4935
+ literal("identity-recovery-required"),
4861
4936
  literal("conflict"),
4862
4937
  literal("rate-limited"),
4863
4938
  literal("group-membership-required"),
@@ -4895,6 +4970,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4895
4970
  literal("handle-unavailable"),
4896
4971
  literal("not-found"),
4897
4972
  literal("forbidden"),
4973
+ literal("identity-recovery-required"),
4898
4974
  literal("conflict"),
4899
4975
  literal("rate-limited"),
4900
4976
  literal("group-membership-required"),
@@ -4937,6 +5013,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4937
5013
  literal("handle-unavailable"),
4938
5014
  literal("not-found"),
4939
5015
  literal("forbidden"),
5016
+ literal("identity-recovery-required"),
4940
5017
  literal("conflict"),
4941
5018
  literal("rate-limited"),
4942
5019
  literal("group-membership-required"),
@@ -4974,6 +5051,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4974
5051
  literal("handle-unavailable"),
4975
5052
  literal("not-found"),
4976
5053
  literal("forbidden"),
5054
+ literal("identity-recovery-required"),
4977
5055
  literal("conflict"),
4978
5056
  literal("rate-limited"),
4979
5057
  literal("group-membership-required"),
@@ -5034,6 +5112,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5034
5112
  literal("handle-unavailable"),
5035
5113
  literal("not-found"),
5036
5114
  literal("forbidden"),
5115
+ literal("identity-recovery-required"),
5037
5116
  literal("conflict"),
5038
5117
  literal("rate-limited"),
5039
5118
  literal("group-membership-required"),
@@ -5092,6 +5171,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5092
5171
  literal("handle-unavailable"),
5093
5172
  literal("not-found"),
5094
5173
  literal("forbidden"),
5174
+ literal("identity-recovery-required"),
5095
5175
  literal("conflict"),
5096
5176
  literal("rate-limited"),
5097
5177
  literal("group-membership-required"),
@@ -5144,6 +5224,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5144
5224
  literal("handle-unavailable"),
5145
5225
  literal("not-found"),
5146
5226
  literal("forbidden"),
5227
+ literal("identity-recovery-required"),
5147
5228
  literal("conflict"),
5148
5229
  literal("rate-limited"),
5149
5230
  literal("group-membership-required"),
@@ -5190,6 +5271,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5190
5271
  literal("handle-unavailable"),
5191
5272
  literal("not-found"),
5192
5273
  literal("forbidden"),
5274
+ literal("identity-recovery-required"),
5193
5275
  literal("conflict"),
5194
5276
  literal("rate-limited"),
5195
5277
  literal("group-membership-required"),
@@ -5236,6 +5318,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5236
5318
  literal("handle-unavailable"),
5237
5319
  literal("not-found"),
5238
5320
  literal("forbidden"),
5321
+ literal("identity-recovery-required"),
5239
5322
  literal("conflict"),
5240
5323
  literal("rate-limited"),
5241
5324
  literal("group-membership-required"),
@@ -5270,6 +5353,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5270
5353
  literal("handle-unavailable"),
5271
5354
  literal("not-found"),
5272
5355
  literal("forbidden"),
5356
+ literal("identity-recovery-required"),
5273
5357
  literal("conflict"),
5274
5358
  literal("rate-limited"),
5275
5359
  literal("group-membership-required"),
@@ -5308,6 +5392,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5308
5392
  literal("handle-unavailable"),
5309
5393
  literal("not-found"),
5310
5394
  literal("forbidden"),
5395
+ literal("identity-recovery-required"),
5311
5396
  literal("conflict"),
5312
5397
  literal("rate-limited"),
5313
5398
  literal("group-membership-required"),
@@ -5362,6 +5447,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5362
5447
  literal("handle-unavailable"),
5363
5448
  literal("not-found"),
5364
5449
  literal("forbidden"),
5450
+ literal("identity-recovery-required"),
5365
5451
  literal("conflict"),
5366
5452
  literal("rate-limited"),
5367
5453
  literal("group-membership-required"),
@@ -5426,6 +5512,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5426
5512
  literal("handle-unavailable"),
5427
5513
  literal("not-found"),
5428
5514
  literal("forbidden"),
5515
+ literal("identity-recovery-required"),
5429
5516
  literal("conflict"),
5430
5517
  literal("rate-limited"),
5431
5518
  literal("group-membership-required"),
@@ -5468,6 +5555,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5468
5555
  literal("handle-unavailable"),
5469
5556
  literal("not-found"),
5470
5557
  literal("forbidden"),
5558
+ literal("identity-recovery-required"),
5471
5559
  literal("conflict"),
5472
5560
  literal("rate-limited"),
5473
5561
  literal("group-membership-required"),
@@ -5505,6 +5593,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5505
5593
  literal("handle-unavailable"),
5506
5594
  literal("not-found"),
5507
5595
  literal("forbidden"),
5596
+ literal("identity-recovery-required"),
5508
5597
  literal("conflict"),
5509
5598
  literal("rate-limited"),
5510
5599
  literal("group-membership-required"),
@@ -5543,6 +5632,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5543
5632
  literal("handle-unavailable"),
5544
5633
  literal("not-found"),
5545
5634
  literal("forbidden"),
5635
+ literal("identity-recovery-required"),
5546
5636
  literal("conflict"),
5547
5637
  literal("rate-limited"),
5548
5638
  literal("group-membership-required"),
@@ -5565,7 +5655,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5565
5655
  "processed": number().readonly(),
5566
5656
  "completed": number().readonly(),
5567
5657
  "pending": number().readonly(),
5568
- "blocked": number().readonly()
5658
+ "blocked": number().readonly(),
5659
+ "items": array(object({
5660
+ "groupDid": intersection(string(), unknown()).readonly(),
5661
+ "status": union([literal("pending"), literal("blocked")]).readonly()
5662
+ })).readonly()
5569
5663
  }).readonly()
5570
5664
  })]);
5571
5665
  const _awiki_dsh_plugin_awiki_resumeRecovery_parameter_0$schema = object({ "operationId": string().readonly() });
@@ -5582,6 +5676,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5582
5676
  literal("handle-unavailable"),
5583
5677
  literal("not-found"),
5584
5678
  literal("forbidden"),
5679
+ literal("identity-recovery-required"),
5585
5680
  literal("conflict"),
5586
5681
  literal("rate-limited"),
5587
5682
  literal("group-membership-required"),
@@ -5649,6 +5744,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5649
5744
  literal("handle-unavailable"),
5650
5745
  literal("not-found"),
5651
5746
  literal("forbidden"),
5747
+ literal("identity-recovery-required"),
5652
5748
  literal("conflict"),
5653
5749
  literal("rate-limited"),
5654
5750
  literal("group-membership-required"),
@@ -5718,6 +5814,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5718
5814
  literal("handle-unavailable"),
5719
5815
  literal("not-found"),
5720
5816
  literal("forbidden"),
5817
+ literal("identity-recovery-required"),
5721
5818
  literal("conflict"),
5722
5819
  literal("rate-limited"),
5723
5820
  literal("group-membership-required"),
@@ -5759,6 +5856,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5759
5856
  literal("handle-unavailable"),
5760
5857
  literal("not-found"),
5761
5858
  literal("forbidden"),
5859
+ literal("identity-recovery-required"),
5762
5860
  literal("conflict"),
5763
5861
  literal("rate-limited"),
5764
5862
  literal("group-membership-required"),
@@ -5801,6 +5899,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5801
5899
  literal("handle-unavailable"),
5802
5900
  literal("not-found"),
5803
5901
  literal("forbidden"),
5902
+ literal("identity-recovery-required"),
5804
5903
  literal("conflict"),
5805
5904
  literal("rate-limited"),
5806
5905
  literal("group-membership-required"),
@@ -5855,6 +5954,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5855
5954
  literal("handle-unavailable"),
5856
5955
  literal("not-found"),
5857
5956
  literal("forbidden"),
5957
+ literal("identity-recovery-required"),
5858
5958
  literal("conflict"),
5859
5959
  literal("rate-limited"),
5860
5960
  literal("group-membership-required"),
@@ -5922,6 +6022,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5922
6022
  literal("handle-unavailable"),
5923
6023
  literal("not-found"),
5924
6024
  literal("forbidden"),
6025
+ literal("identity-recovery-required"),
5925
6026
  literal("conflict"),
5926
6027
  literal("rate-limited"),
5927
6028
  literal("group-membership-required"),
@@ -5958,6 +6059,96 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5958
6059
  })).readonly()
5959
6060
  }).readonly()
5960
6061
  })]);
6062
+ const _awiki_dsh_plugin_awiki_updateConversationPreference_parameter_0$schema = union([
6063
+ object({
6064
+ "action": literal("hide").readonly(),
6065
+ "conversation": union([object({
6066
+ "kind": literal("group").readonly(),
6067
+ "id": intersection(string(), unknown()).readonly(),
6068
+ "groupDid": intersection(string(), unknown()).readonly(),
6069
+ "title": string().readonly(),
6070
+ "unreadCount": number().readonly().optional(),
6071
+ "lastMessageAt": number().readonly().optional(),
6072
+ "lastMessagePreview": string().readonly().optional()
6073
+ }), object({
6074
+ "kind": literal("direct").readonly(),
6075
+ "id": intersection(string(), unknown()).readonly(),
6076
+ "peerDid": intersection(string(), unknown()).readonly(),
6077
+ "peerHandle": intersection(string(), unknown()).readonly().optional(),
6078
+ "displayName": string().readonly().optional(),
6079
+ "title": string().readonly(),
6080
+ "unreadCount": number().readonly().optional(),
6081
+ "lastMessageAt": number().readonly().optional(),
6082
+ "lastMessagePreview": string().readonly().optional()
6083
+ })]).readonly()
6084
+ }),
6085
+ object({
6086
+ "action": literal("restore").readonly(),
6087
+ "conversationId": intersection(string(), unknown()).readonly()
6088
+ }),
6089
+ object({
6090
+ "action": literal("dismiss-group-recovery").readonly(),
6091
+ "signature": string().readonly()
6092
+ })
6093
+ ]);
6094
+ const _awiki_dsh_plugin_awiki_updateConversationPreference_result$schema = union([object({
6095
+ "ok": literal(false).readonly(),
6096
+ "error": object({
6097
+ "code": union([
6098
+ literal("not-registered"),
6099
+ literal("signed-out"),
6100
+ literal("already-registered"),
6101
+ literal("invalid-request"),
6102
+ literal("invalid-otp"),
6103
+ literal("challenge-expired"),
6104
+ literal("handle-unavailable"),
6105
+ literal("not-found"),
6106
+ literal("forbidden"),
6107
+ literal("identity-recovery-required"),
6108
+ literal("conflict"),
6109
+ literal("rate-limited"),
6110
+ literal("group-membership-required"),
6111
+ literal("group-identity-stale"),
6112
+ literal("attachment-too-large"),
6113
+ literal("summary-unavailable"),
6114
+ literal("summary-timeout"),
6115
+ literal("summary-cancelled"),
6116
+ literal("summary-invalid-output"),
6117
+ literal("summary-failed"),
6118
+ literal("delivery-unknown"),
6119
+ literal("network"),
6120
+ literal("remote")
6121
+ ]).readonly(),
6122
+ "message": string().readonly()
6123
+ }).readonly()
6124
+ }), object({
6125
+ "ok": literal(true).readonly(),
6126
+ "value": object({
6127
+ "hiddenConversations": array(object({
6128
+ "conversation": union([object({
6129
+ "kind": literal("group").readonly(),
6130
+ "id": intersection(string(), unknown()).readonly(),
6131
+ "groupDid": intersection(string(), unknown()).readonly(),
6132
+ "title": string().readonly(),
6133
+ "unreadCount": number().readonly().optional(),
6134
+ "lastMessageAt": number().readonly().optional(),
6135
+ "lastMessagePreview": string().readonly().optional()
6136
+ }), object({
6137
+ "kind": literal("direct").readonly(),
6138
+ "id": intersection(string(), unknown()).readonly(),
6139
+ "peerDid": intersection(string(), unknown()).readonly(),
6140
+ "peerHandle": intersection(string(), unknown()).readonly().optional(),
6141
+ "displayName": string().readonly().optional(),
6142
+ "title": string().readonly(),
6143
+ "unreadCount": number().readonly().optional(),
6144
+ "lastMessageAt": number().readonly().optional(),
6145
+ "lastMessagePreview": string().readonly().optional()
6146
+ })]).readonly(),
6147
+ "hiddenAt": number().readonly()
6148
+ })).readonly(),
6149
+ "dismissedGroupRecoverySignature": string().readonly().optional()
6150
+ }).readonly()
6151
+ })]);
5961
6152
  const _awiki_dsh_plugin_awiki_updateDisplayName_parameter_0$schema = object({ "displayName": string().readonly() });
5962
6153
  const _awiki_dsh_plugin_awiki_updateDisplayName_result$schema = union([object({
5963
6154
  "ok": literal(false).readonly(),
@@ -5972,6 +6163,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5972
6163
  literal("handle-unavailable"),
5973
6164
  literal("not-found"),
5974
6165
  literal("forbidden"),
6166
+ literal("identity-recovery-required"),
5975
6167
  literal("conflict"),
5976
6168
  literal("rate-limited"),
5977
6169
  literal("group-membership-required"),
@@ -6015,6 +6207,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6015
6207
  literal("handle-unavailable"),
6016
6208
  literal("not-found"),
6017
6209
  literal("forbidden"),
6210
+ literal("identity-recovery-required"),
6018
6211
  literal("conflict"),
6019
6212
  literal("rate-limited"),
6020
6213
  literal("group-membership-required"),
@@ -6068,7 +6261,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6068
6261
  },
6069
6262
  sourceLocation: {
6070
6263
  "file": "packages/dsh-awiki/src/index.ts",
6071
- "line": 115,
6264
+ "line": 117,
6072
6265
  "column": 9
6073
6266
  }
6074
6267
  },
@@ -6095,7 +6288,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6095
6288
  },
6096
6289
  sourceLocation: {
6097
6290
  "file": "packages/dsh-awiki/src/index.ts",
6098
- "line": 145,
6291
+ "line": 147,
6099
6292
  "column": 3
6100
6293
  }
6101
6294
  },
@@ -6122,7 +6315,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6122
6315
  },
6123
6316
  sourceLocation: {
6124
6317
  "file": "packages/dsh-awiki/src/index.ts",
6125
- "line": 195,
6318
+ "line": 205,
6126
6319
  "column": 3
6127
6320
  }
6128
6321
  },
@@ -6149,7 +6342,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6149
6342
  },
6150
6343
  sourceLocation: {
6151
6344
  "file": "packages/dsh-awiki/src/index.ts",
6152
- "line": 130,
6345
+ "line": 132,
6153
6346
  "column": 9
6154
6347
  }
6155
6348
  },
@@ -6176,7 +6369,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6176
6369
  },
6177
6370
  sourceLocation: {
6178
6371
  "file": "packages/dsh-awiki/src/index.ts",
6179
- "line": 124,
6372
+ "line": 126,
6180
6373
  "column": 9
6181
6374
  }
6182
6375
  },
@@ -6203,7 +6396,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6203
6396
  },
6204
6397
  sourceLocation: {
6205
6398
  "file": "packages/dsh-awiki/src/index.ts",
6206
- "line": 177,
6399
+ "line": 187,
6207
6400
  "column": 9
6208
6401
  }
6209
6402
  },
@@ -6221,7 +6414,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6221
6414
  },
6222
6415
  sourceLocation: {
6223
6416
  "file": "packages/dsh-awiki/src/index.ts",
6224
- "line": 74,
6417
+ "line": 76,
6418
+ "column": 3
6419
+ }
6420
+ },
6421
+ {
6422
+ id: "@awiki/dsh-plugin#awiki/getConversationPreferences",
6423
+ service: "awiki",
6424
+ namespace: "awiki",
6425
+ method: "getConversationPreferences",
6426
+ invocation: { kind: "direct" },
6427
+ parameters: [],
6428
+ result: {
6429
+ mode: "strict",
6430
+ typeSymbol: "@awiki/dsh-plugin/types#AwikiResult",
6431
+ schema: _awiki_dsh_plugin_awiki_getConversationPreferences_result$schema
6432
+ },
6433
+ sourceLocation: {
6434
+ "file": "packages/dsh-awiki/src/index.ts",
6435
+ "line": 156,
6225
6436
  "column": 3
6226
6437
  }
6227
6438
  },
@@ -6248,7 +6459,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6248
6459
  },
6249
6460
  sourceLocation: {
6250
6461
  "file": "packages/dsh-awiki/src/index.ts",
6251
- "line": 133,
6462
+ "line": 135,
6252
6463
  "column": 3
6253
6464
  }
6254
6465
  },
@@ -6275,7 +6486,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6275
6486
  },
6276
6487
  sourceLocation: {
6277
6488
  "file": "packages/dsh-awiki/src/index.ts",
6278
- "line": 157,
6489
+ "line": 167,
6279
6490
  "column": 3
6280
6491
  }
6281
6492
  },
@@ -6293,7 +6504,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6293
6504
  },
6294
6505
  sourceLocation: {
6295
6506
  "file": "packages/dsh-awiki/src/index.ts",
6296
- "line": 77,
6507
+ "line": 79,
6297
6508
  "column": 9
6298
6509
  }
6299
6510
  },
@@ -6320,7 +6531,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6320
6531
  },
6321
6532
  sourceLocation: {
6322
6533
  "file": "packages/dsh-awiki/src/index.ts",
6323
- "line": 160,
6534
+ "line": 170,
6324
6535
  "column": 3
6325
6536
  }
6326
6537
  },
@@ -6338,7 +6549,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6338
6549
  },
6339
6550
  sourceLocation: {
6340
6551
  "file": "packages/dsh-awiki/src/index.ts",
6341
- "line": 180,
6552
+ "line": 190,
6342
6553
  "column": 3
6343
6554
  }
6344
6555
  },
@@ -6356,7 +6567,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6356
6567
  },
6357
6568
  sourceLocation: {
6358
6569
  "file": "packages/dsh-awiki/src/index.ts",
6359
- "line": 103,
6570
+ "line": 105,
6360
6571
  "column": 3
6361
6572
  }
6362
6573
  },
@@ -6383,7 +6594,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6383
6594
  },
6384
6595
  sourceLocation: {
6385
6596
  "file": "packages/dsh-awiki/src/index.ts",
6386
- "line": 118,
6597
+ "line": 120,
6387
6598
  "column": 9
6388
6599
  }
6389
6600
  },
@@ -6401,7 +6612,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6401
6612
  },
6402
6613
  sourceLocation: {
6403
6614
  "file": "packages/dsh-awiki/src/index.ts",
6404
- "line": 80,
6615
+ "line": 82,
6405
6616
  "column": 9
6406
6617
  }
6407
6618
  },
@@ -6428,7 +6639,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6428
6639
  },
6429
6640
  sourceLocation: {
6430
6641
  "file": "packages/dsh-awiki/src/index.ts",
6431
- "line": 89,
6642
+ "line": 91,
6432
6643
  "column": 9
6433
6644
  }
6434
6645
  },
@@ -6455,7 +6666,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6455
6666
  },
6456
6667
  sourceLocation: {
6457
6668
  "file": "packages/dsh-awiki/src/index.ts",
6458
- "line": 136,
6669
+ "line": 138,
6459
6670
  "column": 3
6460
6671
  }
6461
6672
  },
@@ -6482,7 +6693,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6482
6693
  },
6483
6694
  sourceLocation: {
6484
6695
  "file": "packages/dsh-awiki/src/index.ts",
6485
- "line": 139,
6696
+ "line": 141,
6486
6697
  "column": 9
6487
6698
  }
6488
6699
  },
@@ -6510,7 +6721,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6510
6721
  },
6511
6722
  sourceLocation: {
6512
6723
  "file": "packages/dsh-awiki/src/index.ts",
6513
- "line": 154,
6724
+ "line": 164,
6514
6725
  "column": 3
6515
6726
  }
6516
6727
  },
@@ -6537,7 +6748,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6537
6748
  },
6538
6749
  sourceLocation: {
6539
6750
  "file": "packages/dsh-awiki/src/index.ts",
6540
- "line": 142,
6751
+ "line": 144,
6541
6752
  "column": 3
6542
6753
  }
6543
6754
  },
@@ -6565,7 +6776,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6565
6776
  },
6566
6777
  sourceLocation: {
6567
6778
  "file": "packages/dsh-awiki/src/index.ts",
6568
- "line": 183,
6779
+ "line": 193,
6569
6780
  "column": 9
6570
6781
  }
6571
6782
  },
@@ -6583,7 +6794,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6583
6794
  },
6584
6795
  sourceLocation: {
6585
6796
  "file": "packages/dsh-awiki/src/index.ts",
6586
- "line": 86,
6797
+ "line": 88,
6587
6798
  "column": 3
6588
6799
  }
6589
6800
  },
@@ -6610,7 +6821,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6610
6821
  },
6611
6822
  sourceLocation: {
6612
6823
  "file": "packages/dsh-awiki/src/index.ts",
6613
- "line": 83,
6824
+ "line": 85,
6614
6825
  "column": 3
6615
6826
  }
6616
6827
  },
@@ -6637,7 +6848,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6637
6848
  },
6638
6849
  sourceLocation: {
6639
6850
  "file": "packages/dsh-awiki/src/index.ts",
6640
- "line": 168,
6851
+ "line": 178,
6641
6852
  "column": 3
6642
6853
  }
6643
6854
  },
@@ -6664,7 +6875,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6664
6875
  },
6665
6876
  sourceLocation: {
6666
6877
  "file": "packages/dsh-awiki/src/index.ts",
6667
- "line": 189,
6878
+ "line": 199,
6668
6879
  "column": 3
6669
6880
  }
6670
6881
  },
@@ -6691,7 +6902,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6691
6902
  },
6692
6903
  sourceLocation: {
6693
6904
  "file": "packages/dsh-awiki/src/index.ts",
6694
- "line": 112,
6905
+ "line": 114,
6695
6906
  "column": 3
6696
6907
  }
6697
6908
  },
@@ -6718,7 +6929,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6718
6929
  },
6719
6930
  sourceLocation: {
6720
6931
  "file": "packages/dsh-awiki/src/index.ts",
6721
- "line": 186,
6932
+ "line": 196,
6722
6933
  "column": 9
6723
6934
  }
6724
6935
  },
@@ -6745,7 +6956,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6745
6956
  },
6746
6957
  sourceLocation: {
6747
6958
  "file": "packages/dsh-awiki/src/index.ts",
6748
- "line": 97,
6959
+ "line": 99,
6749
6960
  "column": 9
6750
6961
  }
6751
6962
  },
@@ -6772,7 +6983,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6772
6983
  },
6773
6984
  sourceLocation: {
6774
6985
  "file": "packages/dsh-awiki/src/index.ts",
6775
- "line": 148,
6986
+ "line": 150,
6776
6987
  "column": 3
6777
6988
  }
6778
6989
  },
@@ -6799,7 +7010,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6799
7010
  },
6800
7011
  sourceLocation: {
6801
7012
  "file": "packages/dsh-awiki/src/index.ts",
6802
- "line": 127,
7013
+ "line": 129,
6803
7014
  "column": 3
6804
7015
  }
6805
7016
  },
@@ -6817,7 +7028,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6817
7028
  },
6818
7029
  sourceLocation: {
6819
7030
  "file": "packages/dsh-awiki/src/index.ts",
6820
- "line": 151,
7031
+ "line": 153,
6821
7032
  "column": 9
6822
7033
  }
6823
7034
  },
@@ -6844,7 +7055,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6844
7055
  },
6845
7056
  sourceLocation: {
6846
7057
  "file": "packages/dsh-awiki/src/index.ts",
6847
- "line": 121,
7058
+ "line": 123,
6848
7059
  "column": 9
6849
7060
  }
6850
7061
  },
@@ -6871,7 +7082,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6871
7082
  },
6872
7083
  sourceLocation: {
6873
7084
  "file": "packages/dsh-awiki/src/index.ts",
6874
- "line": 174,
7085
+ "line": 184,
6875
7086
  "column": 9
6876
7087
  }
6877
7088
  },
@@ -6898,7 +7109,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6898
7109
  },
6899
7110
  sourceLocation: {
6900
7111
  "file": "packages/dsh-awiki/src/index.ts",
6901
- "line": 192,
7112
+ "line": 202,
6902
7113
  "column": 9
6903
7114
  }
6904
7115
  },
@@ -6925,7 +7136,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6925
7136
  },
6926
7137
  sourceLocation: {
6927
7138
  "file": "packages/dsh-awiki/src/index.ts",
6928
- "line": 109,
7139
+ "line": 111,
6929
7140
  "column": 3
6930
7141
  }
6931
7142
  },
@@ -6952,7 +7163,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6952
7163
  },
6953
7164
  sourceLocation: {
6954
7165
  "file": "packages/dsh-awiki/src/index.ts",
6955
- "line": 94,
7166
+ "line": 96,
6956
7167
  "column": 3
6957
7168
  }
6958
7169
  },
@@ -6979,7 +7190,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6979
7190
  },
6980
7191
  sourceLocation: {
6981
7192
  "file": "packages/dsh-awiki/src/index.ts",
6982
- "line": 171,
7193
+ "line": 181,
6983
7194
  "column": 3
6984
7195
  }
6985
7196
  },
@@ -7006,10 +7217,37 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7006
7217
  },
7007
7218
  sourceLocation: {
7008
7219
  "file": "packages/dsh-awiki/src/index.ts",
7009
- "line": 163,
7220
+ "line": 173,
7010
7221
  "column": 9
7011
7222
  }
7012
7223
  },
7224
+ {
7225
+ id: "@awiki/dsh-plugin#awiki/updateConversationPreference",
7226
+ service: "awiki",
7227
+ namespace: "awiki",
7228
+ method: "updateConversationPreference",
7229
+ invocation: { kind: "direct" },
7230
+ parameters: [{
7231
+ name: "request",
7232
+ wire: "request",
7233
+ source: "json",
7234
+ codec: {
7235
+ mode: "strict",
7236
+ typeSymbol: "@awiki/dsh-plugin/types#AwikiConversationPreferenceMutation",
7237
+ schema: _awiki_dsh_plugin_awiki_updateConversationPreference_parameter_0$schema
7238
+ }
7239
+ }],
7240
+ result: {
7241
+ mode: "strict",
7242
+ typeSymbol: "@awiki/dsh-plugin/types#AwikiResult",
7243
+ schema: _awiki_dsh_plugin_awiki_updateConversationPreference_result$schema
7244
+ },
7245
+ sourceLocation: {
7246
+ "file": "packages/dsh-awiki/src/index.ts",
7247
+ "line": 159,
7248
+ "column": 3
7249
+ }
7250
+ },
7013
7251
  {
7014
7252
  id: "@awiki/dsh-plugin#awiki/updateDisplayName",
7015
7253
  service: "awiki",
@@ -7033,7 +7271,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7033
7271
  },
7034
7272
  sourceLocation: {
7035
7273
  "file": "packages/dsh-awiki/src/index.ts",
7036
- "line": 100,
7274
+ "line": 102,
7037
7275
  "column": 9
7038
7276
  }
7039
7277
  },
@@ -7060,7 +7298,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7060
7298
  },
7061
7299
  sourceLocation: {
7062
7300
  "file": "packages/dsh-awiki/src/index.ts",
7063
- "line": 106,
7301
+ "line": 108,
7064
7302
  "column": 3
7065
7303
  }
7066
7304
  }
@@ -7271,6 +7509,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7271
7509
  default: return registrationFailureMessage(failure);
7272
7510
  }
7273
7511
  }
7512
+ function recoveryPreparationFailureMessage(failure) {
7513
+ switch (failure.code) {
7514
+ case "invalid-request": return "恢复信息不匹配,请检查验证码后重试。";
7515
+ case "invalid-otp": return "验证码不正确,请检查后重试。";
7516
+ case "challenge-expired": return "验证码状态已失效,请重新获取恢复验证码。";
7517
+ case "rate-limited": return "恢复验证过于频繁,请稍后重试。";
7518
+ case "network": return "无法连接 AWiki 服务,请检查网络后重试。";
7519
+ case "remote": return "AWiki 服务暂时无法验证恢复信息,请稍后重试。";
7520
+ default: return `${failure.code}:${failure.message}`;
7521
+ }
7522
+ }
7523
+ function recoveryContinuationFailureMessage(failure, phase) {
7524
+ const remoteCommitted = phase === "remote_committed" || phase === "identity_transition_pending";
7525
+ if (remoteCommitted && [
7526
+ "invalid-request",
7527
+ "conflict",
7528
+ "forbidden",
7529
+ "remote"
7530
+ ].includes(failure.code)) return "身份已在服务端恢复,但本机切换尚未完成。请保留当前恢复操作,并继续完成本机切换;不要重新获取验证码或创建新身份。";
7531
+ switch (failure.code) {
7532
+ case "network": return remoteCommitted ? "身份已在服务端恢复,但当前设备暂时无法完成本机切换。请检查网络后继续完成本机切换。" : "恢复请求结果尚未确认。请保留当前恢复操作并重新检查状态,不要重复提交。";
7533
+ case "invalid-request":
7534
+ case "conflict": return "身份恢复暂未完成。请保留当前恢复操作并重新检查状态,不要重新获取验证码或创建新身份。";
7535
+ case "rate-limited": return "恢复状态检查过于频繁,请稍后继续。";
7536
+ default: return `${failure.code}:${failure.message}`;
7537
+ }
7538
+ }
7274
7539
  function identityAccessInspectionFailureMessage(failure) {
7275
7540
  switch (failure.code) {
7276
7541
  case "invalid-request": return "Handle 格式不正确,请检查后重试。";
@@ -7285,9 +7550,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7285
7550
  identity: null,
7286
7551
  profile: null,
7287
7552
  conversations: Object.freeze([]),
7553
+ hiddenConversations: Object.freeze([]),
7288
7554
  conversationsHasMore: false,
7289
7555
  selectedConversationId: null,
7290
7556
  selectedGroup: null,
7557
+ groupAccess: null,
7291
7558
  groupMembers: Object.freeze([]),
7292
7559
  groupMembersHasMore: false,
7293
7560
  groupRecovery: null,
@@ -7356,17 +7623,78 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7356
7623
  function groupRecoveryFailureMessage(failure) {
7357
7624
  return failure.code === "network" ? "无法连接 AWiki 服务,暂时不能恢复旧群聊身份。" : "暂时不能检查旧群聊身份,请稍后重试。";
7358
7625
  }
7359
- function groupRecoveryView(summary) {
7360
- if (summary.blocked > 0) return {
7361
- status: "blocked",
7362
- pending: summary.pending,
7363
- blocked: summary.blocked
7626
+ function conversationPreferenceFailureMessage(_failure) {
7627
+ return "无法保存本机会话设置,请稍后重试。";
7628
+ }
7629
+ function recoveryFingerprint(parts) {
7630
+ let hash = 2166136261;
7631
+ for (const part of parts) {
7632
+ for (let index = 0; index < part.length; index += 1) {
7633
+ hash ^= part.charCodeAt(index);
7634
+ hash = Math.imul(hash, 16777619);
7635
+ }
7636
+ hash ^= 0;
7637
+ hash = Math.imul(hash, 16777619);
7638
+ }
7639
+ return (hash >>> 0).toString(16).padStart(8, "0");
7640
+ }
7641
+ function groupRecoveryProjection(summary, hiddenGroupDids) {
7642
+ const hiddenItems = summary.items.filter((item) => hiddenGroupDids.has(item.groupDid));
7643
+ const hiddenPending = hiddenItems.filter((item) => item.status === "pending").length;
7644
+ const hiddenBlocked = hiddenItems.filter((item) => item.status === "blocked").length;
7645
+ const pending = Math.max(0, summary.pending - hiddenPending);
7646
+ const blocked = Math.max(0, summary.blocked - hiddenBlocked);
7647
+ const signature = `v1:${pending}:${blocked}:${recoveryFingerprint(summary.items.filter((item) => !hiddenGroupDids.has(item.groupDid)).map((item) => `${item.status}:${item.groupDid}`).sort())}`;
7648
+ if (blocked > 0) return {
7649
+ view: {
7650
+ status: "blocked",
7651
+ pending,
7652
+ blocked
7653
+ },
7654
+ signature
7364
7655
  };
7365
- return summary.pending > 0 ? {
7366
- status: "pending",
7367
- pending: summary.pending,
7368
- blocked: 0
7369
- } : null;
7656
+ return {
7657
+ view: pending > 0 ? {
7658
+ status: "pending",
7659
+ pending,
7660
+ blocked: 0
7661
+ } : null,
7662
+ signature
7663
+ };
7664
+ }
7665
+ function groupReadFailureReason(failure) {
7666
+ switch (failure.code) {
7667
+ case "group-identity-stale": return "recovering";
7668
+ case "group-membership-required":
7669
+ case "not-found":
7670
+ case "forbidden": return "not-member";
7671
+ default: return "network-error";
7672
+ }
7673
+ }
7674
+ async function callGroupRead(operation) {
7675
+ try {
7676
+ const carried = await operation();
7677
+ if (!carried.ok) return {
7678
+ ok: false,
7679
+ error: "暂时无法连接 AWiki 群聊服务,请稍后重新检查。",
7680
+ reason: "network-error"
7681
+ };
7682
+ if (!carried.value.ok) return {
7683
+ ok: false,
7684
+ error: groupReadFailureMessage(carried.value.error),
7685
+ reason: groupReadFailureReason(carried.value.error)
7686
+ };
7687
+ return {
7688
+ ok: true,
7689
+ value: carried.value.value
7690
+ };
7691
+ } catch {
7692
+ return {
7693
+ ok: false,
7694
+ error: "暂时无法连接 AWiki 群聊服务,请稍后重新检查。",
7695
+ reason: "network-error"
7696
+ };
7697
+ }
7370
7698
  }
7371
7699
  /** Flatten the carrier and business result once for every controller caller. */
7372
7700
  async function call(operation, failureMessage = (failure) => `${failure.code}:${failure.message}`, carrierFailureMessage = (message) => `连接 AWiki Host 失败:${message}`) {
@@ -7391,6 +7719,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7391
7719
  };
7392
7720
  }
7393
7721
  }
7722
+ /** Preserve only the stable business code for controller-level state transitions. */
7723
+ async function callWithFailureCode(operation) {
7724
+ try {
7725
+ const carried = await operation();
7726
+ if (!carried.ok) return {
7727
+ ok: false,
7728
+ error: `连接 AWiki Host 失败:${carried.error.message}`
7729
+ };
7730
+ if (!carried.value.ok) return {
7731
+ ok: false,
7732
+ error: `${carried.value.error.code}:${carried.value.error.message}`,
7733
+ failureCode: carried.value.error.code
7734
+ };
7735
+ return {
7736
+ ok: true,
7737
+ value: carried.value.value
7738
+ };
7739
+ } catch (error) {
7740
+ return {
7741
+ ok: false,
7742
+ error: error instanceof Error ? `AWiki 调用失败:${error.message}` : "AWiki 调用失败"
7743
+ };
7744
+ }
7745
+ }
7394
7746
  function recoveryCarrierFailureMessage(message) {
7395
7747
  return message.includes("business result failed boundary validation") ? "恢复信息已验证,但暂时无法读取恢复状态。请稍后重试。" : `连接 AWiki Host 失败:${message}`;
7396
7748
  }
@@ -7568,6 +7920,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7568
7920
  directProfiles = /* @__PURE__ */ new Map();
7569
7921
  /** Last trustworthy group title for the active identity, keyed by canonical Group DID. */
7570
7922
  groupTitles = /* @__PURE__ */ new Map();
7923
+ /** Current secret-free Core journal state, keyed by canonical Group DID. */
7924
+ groupRecoveryItems = /* @__PURE__ */ new Map();
7925
+ /** Identity-scoped product overlays. Core conversations and history remain untouched. */
7926
+ hiddenConversationPreferences = /* @__PURE__ */ new Map();
7927
+ dismissedGroupRecoverySignature;
7928
+ lastGroupRecoverySignature;
7929
+ lastGroupRecoverySummary;
7571
7930
  /** Verified image payloads retained outside observable state for instant remounts. */
7572
7931
  imageAttachments = /* @__PURE__ */ new Map();
7573
7932
  imageAttachmentCacheBytes = 0;
@@ -7628,6 +7987,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7628
7987
  recoveryOperationId: storedRecoveryOperation()
7629
7988
  });
7630
7989
  if (identity !== null) {
7990
+ await this.loadConversationPreferences(generation);
7631
7991
  const profile = await call(() => this.remote.getProfile());
7632
7992
  if (this.current(generation) && profile.ok) this.publish({
7633
7993
  ...this.view,
@@ -7805,7 +8165,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7805
8165
  }
7806
8166
  /** Request a recovery OTP and persist only its secret-free operation id in the browser. */
7807
8167
  async sendRecoveryOtp(request) {
7808
- const result = await this.withPending("发送恢复验证码", () => call(() => this.remote.sendRecoveryOtp(request), registrationOtpFailureMessage));
8168
+ const result = await this.withPending("发送恢复验证码", () => call(() => this.remote.sendRecoveryOtp(request), registrationOtpFailureMessage), { publishFailure: false });
7809
8169
  if (!result.ok) return result;
7810
8170
  storeRecoveryOperation(result.value.operationId);
7811
8171
  this.publish({
@@ -7822,7 +8182,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7822
8182
  const result = await this.withPending("验证恢复信息", () => call(() => this.remote.prepareRecovery({
7823
8183
  ...request,
7824
8184
  operationId
7825
- }), registrationFailureMessage, recoveryCarrierFailureMessage));
8185
+ }), recoveryPreparationFailureMessage, recoveryCarrierFailureMessage), { publishFailure: false });
7826
8186
  if (result.ok) this.publish({
7827
8187
  ...this.view,
7828
8188
  recoveryProgress: result.value
@@ -7834,7 +8194,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7834
8194
  const operationId = this.view.recoveryOperationId;
7835
8195
  if (operationId === null) return this.fail("没有可继续的身份恢复操作");
7836
8196
  if (this.view.recoveryProgress?.phase !== "ready_to_commit") return this.fail("请先完成恢复信息验证");
7837
- const result = await this.withPending("恢复身份", () => call(() => this.remote.activateRecovery({ operationId }), registrationFailureMessage, recoveryCarrierFailureMessage));
8197
+ const phase = this.view.recoveryProgress.phase;
8198
+ const result = await this.withPending("恢复身份", () => call(() => this.remote.activateRecovery({ operationId }), (failure) => recoveryContinuationFailureMessage(failure, phase), recoveryCarrierFailureMessage), { publishFailure: false });
7838
8199
  if (!result.ok) return result;
7839
8200
  this.publish({
7840
8201
  ...this.view,
@@ -7855,7 +8216,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7855
8216
  async refreshRecoveryStatus() {
7856
8217
  const operationId = this.view.recoveryOperationId;
7857
8218
  if (operationId === null) return this.fail("没有可查询的身份恢复操作");
7858
- const result = await this.withPending("刷新恢复状态", () => call(() => this.remote.getRecoveryStatus({ operationId }), void 0, recoveryCarrierFailureMessage));
8219
+ const result = await this.withPending("刷新恢复状态", () => call(() => this.remote.getRecoveryStatus({ operationId }), void 0, recoveryCarrierFailureMessage), { publishFailure: false });
7859
8220
  if (!result.ok) return result;
7860
8221
  this.publish({
7861
8222
  ...this.view,
@@ -7882,7 +8243,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7882
8243
  "remote_committed",
7883
8244
  "identity_transition_pending"
7884
8245
  ].includes(progress.phase)) return this.fail("当前恢复状态不能重试");
7885
- const result = await this.withPending("继续恢复身份", () => call(() => this.remote.resumeRecovery({ operationId }), registrationFailureMessage, recoveryCarrierFailureMessage));
8246
+ const result = await this.withPending("继续恢复身份", () => call(() => this.remote.resumeRecovery({ operationId }), (failure) => recoveryContinuationFailureMessage(failure, progress.phase), recoveryCarrierFailureMessage), { publishFailure: false });
7886
8247
  if (!result.ok) return result;
7887
8248
  this.publish({
7888
8249
  ...this.view,
@@ -7908,7 +8269,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7908
8269
  };
7909
8270
  const phase = this.view.recoveryProgress?.phase;
7910
8271
  if (phase !== void 0 && phase !== "awaiting_factor" && phase !== "ready_to_commit") return this.fail("当前恢复状态不能取消");
7911
- const result = await this.withPending("取消身份恢复", () => call(() => this.remote.discardRecovery({ operationId })));
8272
+ const result = await this.withPending("取消身份恢复", () => call(() => this.remote.discardRecovery({ operationId })), { publishFailure: false });
7912
8273
  if (!result.ok) return result;
7913
8274
  storeRecoveryOperation(null);
7914
8275
  this.publish({
@@ -7947,17 +8308,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7947
8308
  */
7948
8309
  async loadMoreConversations() {
7949
8310
  const generation = this.generation;
7950
- const result = await this.withPending("加载更多会话", () => call(() => this.remote.listConversations(this.conversationsCursor === void 0 ? {} : { cursor: this.conversationsCursor })));
8311
+ const result = await this.withPending("加载更多会话", () => this.listConversationPage(this.conversationsCursor === void 0 ? {} : { cursor: this.conversationsCursor }));
7951
8312
  if (!result.ok) return result;
7952
8313
  if (!this.current(generation)) return {
7953
8314
  ok: true,
7954
8315
  value: void 0
7955
8316
  };
7956
8317
  this.conversationsCursor = result.value.nextCursor;
7957
- const conversations = result.value.items.map((incoming) => this.cacheConversation(incoming, this.view.conversations.find((current) => current.id === incoming.id)));
8318
+ const conversations = await this.reconcileConversationPage(result.value.items, generation);
8319
+ if (!this.current(generation)) return {
8320
+ ok: true,
8321
+ value: void 0
8322
+ };
7958
8323
  this.publish({
7959
8324
  ...this.view,
7960
- conversations: appendUnique(this.view.conversations, conversations, (value) => value.id),
8325
+ conversations: appendUnique(this.view.conversations, conversations.visible, (value) => value.id),
8326
+ hiddenConversations: conversations.hidden,
8327
+ groupRecovery: this.currentGroupRecoveryView(),
7961
8328
  conversationsHasMore: result.value.hasMore && result.value.nextCursor !== void 0
7962
8329
  });
7963
8330
  return {
@@ -7977,6 +8344,104 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7977
8344
  return this.resumeGroupRebindRecovery(generation);
7978
8345
  });
7979
8346
  }
8347
+ /** Dismiss only the current recovery-summary revision; Core recovery remains untouched. */
8348
+ async dismissGroupRecoveryNotice() {
8349
+ const signature = this.lastGroupRecoverySignature;
8350
+ if (signature === void 0 || this.view.groupRecovery === null) return {
8351
+ ok: true,
8352
+ value: void 0
8353
+ };
8354
+ const result = await call(() => this.remote.updateConversationPreference({
8355
+ action: "dismiss-group-recovery",
8356
+ signature
8357
+ }), conversationPreferenceFailureMessage);
8358
+ if (!result.ok) return this.fail(result.error);
8359
+ this.applyConversationPreferences(result.value);
8360
+ this.publish({
8361
+ ...this.view,
8362
+ groupRecovery: null,
8363
+ error: null
8364
+ });
8365
+ return {
8366
+ ok: true,
8367
+ value: void 0
8368
+ };
8369
+ }
8370
+ /** Hide one recent row locally without leaving a group or deleting history. */
8371
+ async hideConversation(conversationId) {
8372
+ const conversation = this.view.conversations.find((item) => item.id === conversationId);
8373
+ if (conversation === void 0) return this.fail("该会话已不在当前列表中");
8374
+ const generation = this.generation;
8375
+ const result = await this.withPending("移除会话", () => call(() => this.remote.updateConversationPreference({
8376
+ action: "hide",
8377
+ conversation
8378
+ }), conversationPreferenceFailureMessage));
8379
+ if (!result.ok) return result;
8380
+ if (!this.current(generation)) return {
8381
+ ok: true,
8382
+ value: void 0
8383
+ };
8384
+ this.applyConversationPreferences(result.value);
8385
+ const selected = this.view.selectedConversationId === conversationId;
8386
+ if (selected) {
8387
+ this.selectionRevision += 1;
8388
+ this.historyCursor = void 0;
8389
+ this.groupMembersCursor = void 0;
8390
+ }
8391
+ this.publish({
8392
+ ...this.view,
8393
+ conversations: this.view.conversations.filter((item) => item.id !== conversationId),
8394
+ hiddenConversations: this.hiddenConversationsView(),
8395
+ ...selected ? {
8396
+ selectedConversationId: null,
8397
+ selectedGroup: null,
8398
+ groupAccess: null,
8399
+ groupMembers: [],
8400
+ groupMembersHasMore: false,
8401
+ messages: [],
8402
+ historyHasMore: false,
8403
+ localPending: false,
8404
+ refreshing: false
8405
+ } : {},
8406
+ groupRecovery: this.currentGroupRecoveryView(),
8407
+ error: null
8408
+ });
8409
+ return {
8410
+ ok: true,
8411
+ value: void 0
8412
+ };
8413
+ }
8414
+ /** Restore one locally hidden row to the recent roster. */
8415
+ async restoreConversation(conversationId) {
8416
+ const hidden = this.hiddenConversationPreferences.get(conversationId);
8417
+ if (hidden === void 0) return {
8418
+ ok: true,
8419
+ value: void 0
8420
+ };
8421
+ const generation = this.generation;
8422
+ const result = await this.withPending("恢复会话", () => call(() => this.remote.updateConversationPreference({
8423
+ action: "restore",
8424
+ conversationId
8425
+ }), conversationPreferenceFailureMessage));
8426
+ if (!result.ok) return result;
8427
+ if (!this.current(generation)) return {
8428
+ ok: true,
8429
+ value: void 0
8430
+ };
8431
+ this.applyConversationPreferences(result.value);
8432
+ const conversation = this.cacheConversation(hidden.conversation, this.view.conversations.find((item) => item.id === conversationId));
8433
+ this.publish({
8434
+ ...this.view,
8435
+ conversations: appendUnique([conversation], this.view.conversations, (item) => item.id),
8436
+ hiddenConversations: this.hiddenConversationsView(),
8437
+ groupRecovery: this.currentGroupRecoveryView(),
8438
+ error: null
8439
+ });
8440
+ return {
8441
+ ok: true,
8442
+ value: void 0
8443
+ };
8444
+ }
7980
8445
  /**
7981
8446
  * Look up a Handle or DID, then open the matching direct conversation.
7982
8447
  * @param handle - peer Handle or DID typed by the user.
@@ -7992,8 +8457,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7992
8457
  const identity = this.view.identity;
7993
8458
  if (identity === null) return this.fail("请先注册 AWiki 身份");
7994
8459
  if (sameIdentity(identity, peer)) return this.fail("不能向自己发起私聊");
7995
- const existing = findDirect(this.view.conversations, peer);
7996
- if (existing !== void 0) return this.selectConversation(existing.id);
8460
+ const existing = findDirect([...this.view.conversations, ...this.view.hiddenConversations], peer);
8461
+ if (existing !== void 0) {
8462
+ if (this.hiddenConversationPreferences.has(existing.id)) {
8463
+ const restored = await this.restoreConversation(existing.id);
8464
+ if (!restored.ok) return restored;
8465
+ }
8466
+ return this.selectConversation(existing.id);
8467
+ }
7997
8468
  const generation = this.generation;
7998
8469
  const resolved = await this.withPending("查找用户", () => call(() => this.remote.resolvePeer({ peer })));
7999
8470
  if (!resolved.ok) return resolved.error.startsWith("not-found") ? this.fail("该 Handle 不存在") : resolved;
@@ -8076,14 +8547,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8076
8547
  if (!result.ok || !this.current(generation)) return result;
8077
8548
  await this.refreshConversations(generation);
8078
8549
  if (!this.current(generation)) return result;
8079
- const conversation = this.view.conversations.find((value) => value.kind === "group" && value.groupDid === groupDid) ?? this.cacheConversation({
8550
+ const conversation = [...this.view.conversations, ...this.view.hiddenConversations].find((value) => value.kind === "group" && value.groupDid === groupDid) ?? this.cacheConversation({
8080
8551
  kind: "group",
8081
8552
  id: result.value.conversationId,
8082
8553
  groupDid,
8083
8554
  title: result.value.title,
8084
8555
  unreadCount: 0
8085
8556
  });
8086
- this.publish({
8557
+ if (this.hiddenConversationPreferences.has(conversation.id)) {
8558
+ const restored = await this.restoreConversation(conversation.id);
8559
+ if (!restored.ok) return {
8560
+ ok: false,
8561
+ error: restored.error
8562
+ };
8563
+ } else this.publish({
8087
8564
  ...this.view,
8088
8565
  conversations: appendUnique([conversation], this.view.conversations, (value) => value.id)
8089
8566
  });
@@ -8094,13 +8571,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8094
8571
  async refreshSelectedGroup() {
8095
8572
  const conversation = this.selectedConversation();
8096
8573
  if (conversation?.kind !== "group") return this.fail("请先打开一个群聊");
8097
- return this.withPending("刷新群成员", async () => {
8098
- const refreshed = await this.loadGroupState(conversation, true);
8574
+ if (this.disposed) return {
8575
+ ok: false,
8576
+ error: "AWiki 插件已卸载"
8577
+ };
8578
+ const generation = this.generation;
8579
+ this.publish({
8580
+ ...this.view,
8581
+ pending: "刷新群成员",
8582
+ error: null
8583
+ });
8584
+ const result = await (async () => {
8585
+ if (this.view.groupAccess?.status !== "available" && this.view.groupAccess?.status !== "loading") await this.resumeGroupRebindRecovery(this.generation);
8586
+ const refreshed = await this.loadGroupState(conversation, true, true);
8099
8587
  return refreshed.ok ? {
8100
8588
  ok: true,
8101
8589
  value: void 0
8102
8590
  } : refreshed;
8591
+ })();
8592
+ if (this.current(generation)) this.publish({
8593
+ ...this.view,
8594
+ pending: null,
8595
+ error: null
8103
8596
  });
8597
+ return result;
8104
8598
  }
8105
8599
  /** Load the next authoritative member page using Core's opaque cursor. */
8106
8600
  async loadMoreGroupMembers() {
@@ -8175,6 +8669,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8175
8669
  ...this.view,
8176
8670
  selectedConversationId: null,
8177
8671
  selectedGroup: null,
8672
+ groupAccess: null,
8178
8673
  groupMembers: [],
8179
8674
  groupMembersHasMore: false,
8180
8675
  messages: []
@@ -8204,6 +8699,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8204
8699
  ...this.view,
8205
8700
  selectedConversationId: conversationId,
8206
8701
  selectedGroup: null,
8702
+ groupAccess: selected?.kind === "group" ? {
8703
+ groupDid: selected.groupDid,
8704
+ status: "loading"
8705
+ } : null,
8207
8706
  groupMembers: [],
8208
8707
  groupMembersHasMore: false,
8209
8708
  messages: sameConversation ? this.view.messages : [],
@@ -8252,26 +8751,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8252
8751
  value: void 0
8253
8752
  };
8254
8753
  }
8255
- async loadGroupState(conversation, reset) {
8754
+ async loadGroupState(conversation, reset, preserveAvailableOnNetworkFailure = false) {
8256
8755
  const generation = this.generation;
8257
8756
  const selectionRevision = this.selectionRevision;
8258
- const snapshot = await call(() => this.remote.getGroup({ groupDid: conversation.groupDid }), groupReadFailureMessage);
8757
+ const snapshot = await callGroupRead(() => this.remote.getGroup({ groupDid: conversation.groupDid }));
8259
8758
  if (!snapshot.ok) {
8260
- if (this.currentSelection(generation, selectionRevision, conversation.id)) this.publish({
8759
+ if (!(preserveAvailableOnNetworkFailure && snapshot.reason === "network-error" && this.view.groupAccess?.groupDid === conversation.groupDid && this.view.groupAccess.status === "available") && this.currentSelection(generation, selectionRevision, conversation.id)) this.publishGroupAccessFailure(conversation, snapshot.reason);
8760
+ return snapshot;
8761
+ }
8762
+ if (this.currentSelection(generation, selectionRevision, conversation.id)) {
8763
+ const access = this.view.groupAccess;
8764
+ this.publish({
8261
8765
  ...this.view,
8262
- error: snapshot.error
8766
+ selectedGroup: snapshot.value,
8767
+ groupAccess: access?.groupDid === conversation.groupDid && access.status === "available" ? access : {
8768
+ groupDid: conversation.groupDid,
8769
+ status: "loading"
8770
+ },
8771
+ error: null
8263
8772
  });
8264
- return snapshot;
8265
8773
  }
8266
- const members = await call(() => this.remote.listGroupMembers({
8774
+ const members = await callGroupRead(() => this.remote.listGroupMembers({
8267
8775
  groupDid: conversation.groupDid,
8268
8776
  limit: 50
8269
- }), groupReadFailureMessage);
8777
+ }));
8270
8778
  if (!members.ok) {
8271
- if (this.currentSelection(generation, selectionRevision, conversation.id)) this.publish({
8272
- ...this.view,
8273
- error: members.error
8274
- });
8779
+ if (!(preserveAvailableOnNetworkFailure && members.reason === "network-error" && this.view.groupAccess?.groupDid === conversation.groupDid && this.view.groupAccess.status === "available") && this.currentSelection(generation, selectionRevision, conversation.id)) this.publishGroupAccessFailure(conversation, members.reason);
8275
8780
  return members;
8276
8781
  }
8277
8782
  if (!this.currentSelection(generation, selectionRevision, conversation.id)) return snapshot;
@@ -8280,6 +8785,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8280
8785
  this.publish({
8281
8786
  ...this.view,
8282
8787
  selectedGroup: snapshot.value,
8788
+ groupAccess: {
8789
+ groupDid: conversation.groupDid,
8790
+ status: "available"
8791
+ },
8283
8792
  groupMembers: reset ? members.value.items : appendUnique(this.view.groupMembers, members.value.items, groupMemberKey),
8284
8793
  groupMembersHasMore: members.value.hasMore && members.value.nextCursor !== void 0
8285
8794
  });
@@ -8311,10 +8820,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8311
8820
  recordTiming("conversation.select.remote_history_ms", remoteStartedAt, remote.ok);
8312
8821
  if (!this.currentSelection(generation, selectionRevision, conversationId)) return;
8313
8822
  if (!remote.ok) {
8823
+ if (selected?.kind === "group") this.publishGroupAccessFailure(selected, remote.reason);
8314
8824
  this.publish({
8315
8825
  ...this.view,
8316
8826
  refreshing: false,
8317
- error: refreshFailureMessage(this.view.messages, remote.error)
8827
+ error: selected?.kind === "group" ? null : refreshFailureMessage(this.view.messages, remote.error)
8318
8828
  });
8319
8829
  return;
8320
8830
  }
@@ -8350,14 +8860,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8350
8860
  });
8351
8861
  }
8352
8862
  async readRemoteHistoryWithGroupReadiness(conversation, conversationId, generation, selectionRevision) {
8353
- if (conversation?.kind !== "group") return call(() => this.remote.getHistory({ conversationId }));
8863
+ if (conversation?.kind !== "group") {
8864
+ const result = await call(() => this.remote.getHistory({ conversationId }));
8865
+ return result.ok ? result : {
8866
+ ...result,
8867
+ reason: "network-error"
8868
+ };
8869
+ }
8354
8870
  for (const retryDelay of GROUP_HISTORY_RETRY_DELAYS_MS) {
8355
- const remote = await call(() => this.remote.getHistory({ conversationId }), groupReadFailureMessage);
8871
+ const remote = await callGroupRead(() => this.remote.getHistory({ conversationId }));
8356
8872
  if (remote.ok || !this.currentSelection(generation, selectionRevision, conversationId)) return remote;
8873
+ if (remote.reason !== "network-error") return remote;
8357
8874
  await delay(retryDelay);
8358
8875
  if (!this.currentSelection(generation, selectionRevision, conversationId)) return remote;
8359
8876
  }
8360
- return call(() => this.remote.getHistory({ conversationId }), groupReadFailureMessage);
8877
+ return callGroupRead(() => this.remote.getHistory({ conversationId }));
8361
8878
  }
8362
8879
  async refreshSelectedDirectProfile(selected, generation, selectionRevision) {
8363
8880
  if (selected?.kind !== "direct") return;
@@ -8412,6 +8929,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8412
8929
  ok: true,
8413
8930
  value: void 0
8414
8931
  };
8932
+ if (conversation.kind === "group" && this.view.groupAccess?.status !== "available") return {
8933
+ ok: true,
8934
+ value: void 0
8935
+ };
8415
8936
  const existing = this.markReadInFlight.get(conversation.id);
8416
8937
  if (existing !== void 0) return existing;
8417
8938
  const conversationId = conversation.id;
@@ -8504,6 +9025,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8504
9025
  async sendText(text, clientMessageId, mentions) {
8505
9026
  const conversation = this.selectedConversation();
8506
9027
  if (conversation === void 0) return this.fail("请先选择会话");
9028
+ if (conversation.kind === "group" && this.view.groupAccess?.status !== "available") return this.fail("当前身份尚未获得这个群聊的发送权限,请先重新检查群成员状态。");
8507
9029
  const conversationId = conversation.id;
8508
9030
  const generation = this.generation;
8509
9031
  const result = await this.withPending("发送消息", () => call(() => this.remote.sendText({
@@ -8531,6 +9053,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8531
9053
  async sendAttachment(file) {
8532
9054
  const conversation = this.selectedConversation();
8533
9055
  if (conversation === void 0) return this.fail("请先选择会话");
9056
+ if (conversation.kind === "group" && this.view.groupAccess?.status !== "available") return this.fail("当前身份尚未获得这个群聊的发送权限,请先重新检查群成员状态。");
8534
9057
  const conversationId = conversation.id;
8535
9058
  const generation = this.generation;
8536
9059
  const request = {
@@ -8633,8 +9156,67 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8633
9156
  this.close();
8634
9157
  this.listeners.clear();
8635
9158
  }
9159
+ async loadConversationPreferences(generation) {
9160
+ const result = await call(() => this.remote.getConversationPreferences(), conversationPreferenceFailureMessage);
9161
+ if (!result.ok || !this.current(generation)) return;
9162
+ this.applyConversationPreferences(result.value);
9163
+ this.publish({
9164
+ ...this.view,
9165
+ hiddenConversations: this.hiddenConversationsView()
9166
+ });
9167
+ }
9168
+ applyConversationPreferences(preferences) {
9169
+ this.hiddenConversationPreferences.clear();
9170
+ for (const hidden of preferences.hiddenConversations) this.hiddenConversationPreferences.set(hidden.conversation.id, {
9171
+ conversation: { ...hidden.conversation },
9172
+ hiddenAt: hidden.hiddenAt
9173
+ });
9174
+ this.dismissedGroupRecoverySignature = preferences.dismissedGroupRecoverySignature;
9175
+ }
9176
+ hiddenConversationsView() {
9177
+ return [...this.hiddenConversationPreferences.values()].sort((left, right) => right.hiddenAt - left.hiddenAt).map((item) => item.conversation);
9178
+ }
9179
+ currentGroupRecoveryView() {
9180
+ const summary = this.lastGroupRecoverySummary;
9181
+ if (summary === void 0) return this.view.groupRecovery;
9182
+ const projection = groupRecoveryProjection(summary, new Set([...this.hiddenConversationPreferences.values()].map((item) => item.conversation).filter((conversation) => conversation.kind === "group").map((conversation) => conversation.groupDid)));
9183
+ this.lastGroupRecoverySignature = projection.signature;
9184
+ return projection.signature === this.dismissedGroupRecoverySignature ? null : projection.view;
9185
+ }
9186
+ async reconcileConversationPage(incoming, generation) {
9187
+ const current = [...this.view.conversations, ...this.view.hiddenConversations];
9188
+ const conversations = incoming.map((item) => this.cacheConversation(item, current.find((candidate) => candidate.id === item.id)));
9189
+ for (const conversation of conversations) {
9190
+ const hidden = this.hiddenConversationPreferences.get(conversation.id);
9191
+ if (hidden === void 0) continue;
9192
+ const previousActivity = hidden.conversation.lastMessageAt ?? 0;
9193
+ if ((conversation.lastMessageAt ?? 0) <= previousActivity) continue;
9194
+ const restored = await call(() => this.remote.updateConversationPreference({
9195
+ action: "restore",
9196
+ conversationId: conversation.id
9197
+ }), conversationPreferenceFailureMessage);
9198
+ if (!this.current(generation)) return {
9199
+ visible: [],
9200
+ hidden: this.hiddenConversationsView()
9201
+ };
9202
+ if (restored.ok) this.applyConversationPreferences(restored.value);
9203
+ }
9204
+ const visible = [];
9205
+ for (const conversation of conversations) {
9206
+ const hidden = this.hiddenConversationPreferences.get(conversation.id);
9207
+ if (hidden === void 0) visible.push(conversation);
9208
+ else this.hiddenConversationPreferences.set(conversation.id, {
9209
+ ...hidden,
9210
+ conversation
9211
+ });
9212
+ }
9213
+ return {
9214
+ visible,
9215
+ hidden: this.hiddenConversationsView()
9216
+ };
9217
+ }
8636
9218
  async refreshConversations(generation, background = false) {
8637
- const result = await call(() => this.remote.listConversations({}));
9219
+ const result = await this.listConversationPage({});
8638
9220
  if (!this.current(generation)) return {
8639
9221
  ok: true,
8640
9222
  value: void 0
@@ -8642,13 +9224,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8642
9224
  if (!result.ok) return background ? result : this.fail(result.error);
8643
9225
  const firstPage = this.view.conversations.length === 0;
8644
9226
  if (firstPage) this.conversationsCursor = result.value.nextCursor;
8645
- const refreshed = result.value.items.map((incoming) => {
8646
- const current = this.view.conversations.find((value) => value.id === incoming.id);
8647
- return this.cacheConversation(incoming, current);
8648
- });
9227
+ const refreshed = await this.reconcileConversationPage(result.value.items, generation);
9228
+ if (!this.current(generation)) return {
9229
+ ok: true,
9230
+ value: void 0
9231
+ };
8649
9232
  this.publish({
8650
9233
  ...this.view,
8651
- conversations: firstPage ? refreshed : appendUnique(refreshed, this.view.conversations, (value) => value.id),
9234
+ conversations: firstPage ? refreshed.visible : appendUnique(refreshed.visible, this.view.conversations, (value) => value.id),
9235
+ hiddenConversations: refreshed.hidden,
9236
+ groupRecovery: this.currentGroupRecoveryView(),
8652
9237
  conversationsHasMore: firstPage ? result.value.hasMore && result.value.nextCursor !== void 0 : this.view.conversationsHasMore,
8653
9238
  error: background ? this.view.error : null
8654
9239
  });
@@ -8657,6 +9242,56 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8657
9242
  value: void 0
8658
9243
  };
8659
9244
  }
9245
+ /** List the active identity's own conversations and detect a revoked local credential. */
9246
+ async listConversationPage(request) {
9247
+ const result = await callWithFailureCode(() => this.remote.listConversations(request));
9248
+ if (!result.ok && (result.failureCode === "identity-recovery-required" || result.failureCode === "forbidden")) {
9249
+ this.enterIdentityRecoveryRequired();
9250
+ return {
9251
+ ok: false,
9252
+ error: "当前设备的 AWiki 身份凭证已失效,请重新恢复身份。"
9253
+ };
9254
+ }
9255
+ return result.ok ? result : {
9256
+ ok: false,
9257
+ error: result.error
9258
+ };
9259
+ }
9260
+ /** Replace only visible browser projections; Core identity and SQLite state remain untouched. */
9261
+ enterIdentityRecoveryRequired() {
9262
+ if (this.view.identity === null) return;
9263
+ this.close();
9264
+ this.conversationsCursor = void 0;
9265
+ this.historyCursor = void 0;
9266
+ this.groupMembersCursor = void 0;
9267
+ this.unreadAtOpen.clear();
9268
+ this.summaryBaselines.clear();
9269
+ this.groupRecoveryItems.clear();
9270
+ this.lastGroupRecoverySignature = void 0;
9271
+ this.lastGroupRecoverySummary = void 0;
9272
+ this.clearImageAttachments();
9273
+ this.publish({
9274
+ ...this.view,
9275
+ status: "ready",
9276
+ sessionStatus: "recovery-required",
9277
+ conversations: Object.freeze([]),
9278
+ hiddenConversations: Object.freeze([]),
9279
+ conversationsHasMore: false,
9280
+ selectedConversationId: null,
9281
+ selectedGroup: null,
9282
+ groupAccess: null,
9283
+ groupMembers: Object.freeze([]),
9284
+ groupMembersHasMore: false,
9285
+ groupRecovery: null,
9286
+ messages: Object.freeze([]),
9287
+ historyHasMore: false,
9288
+ localPending: false,
9289
+ refreshing: false,
9290
+ pending: null,
9291
+ error: null,
9292
+ summaries: Object.freeze({})
9293
+ });
9294
+ }
8660
9295
  /** Hydrate account-projected groups before asking Core to resume their durable rebind jobs. */
8661
9296
  async refreshConversationsAndRecoverGroups(generation, background = false) {
8662
9297
  const listed = await this.refreshConversations(generation, background);
@@ -8670,9 +9305,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8670
9305
  let operation;
8671
9306
  operation = call(() => this.remote.resumeGroupRebindRecovery(), groupRecoveryFailureMessage).then((result) => {
8672
9307
  if (!this.current(generation)) return result;
9308
+ if (result.ok) {
9309
+ this.lastGroupRecoverySummary = result.value;
9310
+ this.groupRecoveryItems.clear();
9311
+ for (const item of result.value.items) this.groupRecoveryItems.set(item.groupDid, item.status);
9312
+ } else {
9313
+ this.lastGroupRecoverySummary = void 0;
9314
+ this.lastGroupRecoverySignature = "unavailable";
9315
+ }
8673
9316
  this.publish({
8674
9317
  ...this.view,
8675
- groupRecovery: result.ok ? groupRecoveryView(result.value) : {
9318
+ groupRecovery: result.ok ? this.currentGroupRecoveryView() : this.dismissedGroupRecoverySignature === "unavailable" ? null : {
8676
9319
  status: "unavailable",
8677
9320
  pending: 0,
8678
9321
  blocked: 0
@@ -8691,6 +9334,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8691
9334
  async loadHistory(older) {
8692
9335
  const conversationId = this.view.selectedConversationId;
8693
9336
  if (conversationId === null) return this.fail("请先选择会话");
9337
+ if (this.selectedConversation()?.kind === "group" && this.view.groupAccess?.status !== "available") return {
9338
+ ok: false,
9339
+ error: "当前群聊仅可查看本机已有记录,请先重新检查群成员状态。"
9340
+ };
8694
9341
  const generation = this.generation;
8695
9342
  const request = {
8696
9343
  conversationId,
@@ -8729,6 +9376,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8729
9376
  if ((await this.refreshConversations(generation, true)).ok && this.view.conversations.some((conversation) => conversation.kind === "group" && !knownGroups.has(conversation.groupDid))) await this.resumeGroupRebindRecovery(generation);
8730
9377
  const selected = this.view.selectedConversationId;
8731
9378
  if (selected === null || !this.current(generation)) return;
9379
+ if (this.selectedConversation()?.kind === "group" && this.view.groupAccess?.status !== "available") return;
8732
9380
  const result = await call(() => this.remote.getHistory({ conversationId: selected }));
8733
9381
  if (!this.current(generation) || !result.ok || this.view.selectedConversationId !== selected) return;
8734
9382
  if (!pageBelongsToConversation(selected, result.value.items)) {
@@ -8752,7 +9400,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8752
9400
  this.polling = false;
8753
9401
  }
8754
9402
  }
8755
- async withPending(label, operation) {
9403
+ async withPending(label, operation, options = {}) {
8756
9404
  if (this.disposed) return {
8757
9405
  ok: false,
8758
9406
  error: "AWiki 插件已卸载"
@@ -8768,7 +9416,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8768
9416
  this.publish({
8769
9417
  ...this.view,
8770
9418
  pending: null,
8771
- error: result.ok ? null : result.error
9419
+ error: result.ok || options.publishFailure === false ? null : result.error
8772
9420
  });
8773
9421
  return result;
8774
9422
  }
@@ -8818,12 +9466,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8818
9466
  const selected = this.view.selectedConversationId;
8819
9467
  return selected === null ? void 0 : this.view.conversations.find((value) => value.id === selected);
8820
9468
  }
9469
+ publishGroupAccessFailure(conversation, reason) {
9470
+ const journal = this.groupRecoveryItems.get(conversation.groupDid);
9471
+ const status = reason === "not-member" ? journal === "blocked" ? "blocked" : journal === "pending" ? "recovering" : "not-member" : reason;
9472
+ this.publish({
9473
+ ...this.view,
9474
+ groupAccess: {
9475
+ groupDid: conversation.groupDid,
9476
+ status
9477
+ },
9478
+ error: null
9479
+ });
9480
+ }
8821
9481
  /** Keep presentation-only cache entries isolated to one authenticated identity. */
8822
9482
  activatePresentationCache(identity) {
8823
9483
  const ownerDid = identity?.did ?? null;
8824
9484
  if (ownerDid === this.presentationCacheOwnerDid) return;
8825
9485
  this.directProfiles.clear();
8826
9486
  this.groupTitles.clear();
9487
+ this.groupRecoveryItems.clear();
9488
+ this.hiddenConversationPreferences.clear();
9489
+ this.dismissedGroupRecoverySignature = void 0;
9490
+ this.lastGroupRecoverySignature = void 0;
9491
+ this.lastGroupRecoverySummary = void 0;
8827
9492
  this.clearImageAttachments();
8828
9493
  this.presentationCacheOwnerDid = ownerDid;
8829
9494
  }
@@ -8831,6 +9496,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8831
9496
  clearPresentationCache() {
8832
9497
  this.directProfiles.clear();
8833
9498
  this.groupTitles.clear();
9499
+ this.groupRecoveryItems.clear();
9500
+ this.hiddenConversationPreferences.clear();
9501
+ this.dismissedGroupRecoverySignature = void 0;
9502
+ this.lastGroupRecoverySignature = void 0;
9503
+ this.lastGroupRecoverySummary = void 0;
8834
9504
  this.clearImageAttachments();
8835
9505
  this.presentationCacheOwnerDid = null;
8836
9506
  }
@@ -8981,7 +9651,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8981
9651
  }
8982
9652
  //#endregion
8983
9653
  //#region \0dsh-awiki-css:AwikiOverlay.module.css.mjs
8984
- const css$5 = ".EtEeYG_trigger{z-index:2;border:1px solid var(--dsw-alias-border-l2);width:48px;height:48px;color:var(--dsw-alias-brand-primary);box-shadow:var(--dsw-shadow-lv2);cursor:grab;font:inherit;touch-action:none;user-select:none;background:#fff;border-radius:50%;place-items:center;padding:0;display:grid;position:fixed;overflow:visible}.EtEeYG_trigger:hover{box-shadow:var(--dsw-shadow-lv3);background:#fff}.EtEeYG_trigger:active,.EtEeYG_trigger[data-dragging]{cursor:grabbing}.EtEeYG_launcherIcon{object-fit:cover;pointer-events:none;border-radius:50%;width:100%;height:100%;display:block}.EtEeYG_unreadBadge{border:2px solid var(--dsw-alias-bg-base);background:var(--dsw-alias-state-error-primary);color:#fff;box-sizing:border-box;pointer-events:none;border-radius:10px;place-items:center;min-width:20px;height:20px;padding:0 5px;font-size:11px;font-weight:600;line-height:16px;display:grid;position:absolute;top:-5px;right:-5px}.EtEeYG_trigger:focus-visible,.EtEeYG_drawer button:focus-visible,.EtEeYG_drawer input:focus-visible,.EtEeYG_drawer textarea:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.EtEeYG_drawer{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);z-index:1;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:min(720px,100vw - 80px);min-width:min(360px,100vw - 80px);height:min(720px,100vh - 16px);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3);border-radius:16px;flex-direction:column;transition:width .16s;display:flex;position:fixed;overflow:hidden}.EtEeYG_drawer[data-mode=mail]{width:min(1040px,100vw - 80px)}.EtEeYG_drawer[data-resizing]{user-select:none;transition:none}.EtEeYG_resizeHandle{z-index:5;touch-action:none;user-select:none;position:absolute}.EtEeYG_resizeHandle[data-resize-handle=n],.EtEeYG_resizeHandle[data-resize-handle=s]{cursor:ns-resize;height:8px;left:14px;right:14px}.EtEeYG_resizeHandle[data-resize-handle=n]{top:0}.EtEeYG_resizeHandle[data-resize-handle=s]{bottom:0}.EtEeYG_resizeHandle[data-resize-handle=e],.EtEeYG_resizeHandle[data-resize-handle=w]{cursor:ew-resize;width:8px;top:14px;bottom:14px}.EtEeYG_resizeHandle[data-resize-handle=e]{right:0}.EtEeYG_resizeHandle[data-resize-handle=w]{left:0}.EtEeYG_resizeHandle[data-resize-handle=ne],.EtEeYG_resizeHandle[data-resize-handle=se],.EtEeYG_resizeHandle[data-resize-handle=sw],.EtEeYG_resizeHandle[data-resize-handle=nw]{width:14px;height:14px}.EtEeYG_resizeHandle[data-resize-handle=ne]{cursor:nesw-resize;top:0;right:0}.EtEeYG_resizeHandle[data-resize-handle=se]{cursor:nwse-resize;bottom:0;right:0}.EtEeYG_resizeHandle[data-resize-handle=sw]{cursor:nesw-resize;bottom:0;left:0}.EtEeYG_resizeHandle[data-resize-handle=nw]{cursor:nwse-resize;top:0;left:0}.EtEeYG_drawerHeader{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;touch-action:none;user-select:none;flex:none;align-items:center;gap:8px;height:58px;padding:0 14px 0 18px;display:flex}.EtEeYG_drawerHeader[data-dragging]{cursor:grabbing}.EtEeYG_drawerHeader>div{flex:1;align-items:center;gap:8px;display:flex}.EtEeYG_drawerHeader h2{margin:0;font-size:16px;line-height:24px}.EtEeYG_drawerHeader button,.EtEeYG_back{cursor:pointer;width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:9px;place-items:center;padding:0;display:grid}.EtEeYG_drawerHeader button:hover,.EtEeYG_back:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_centerState,.EtEeYG_threadEmpty{text-align:center;color:var(--dsw-alias-label-secondary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:14px;padding:32px;display:flex}.EtEeYG_centerState p{overflow-wrap:anywhere;max-width:420px;margin:0}.EtEeYG_registrationIcon{background:var(--dsw-alias-interactive-bg-active);width:48px;height:48px;color:var(--dsw-alias-brand-primary);border-radius:50%;justify-self:center;place-items:center;display:grid}.EtEeYG_fileDraft input,.EtEeYG_composeRow textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:10px}.EtEeYG_primary,.EtEeYG_more,.EtEeYG_fileDraft button{background:var(--dsw-alias-button-primary-fill);min-height:36px;color:var(--dsw-alias-label-primary-inverted);cursor:pointer;font:inherit;border:0;border-radius:10px;padding:0 14px}.EtEeYG_primary:hover,.EtEeYG_fileDraft button:hover{background:var(--dsw-alias-button-primary-hover)}.EtEeYG_primary:disabled,.EtEeYG_fileDraft button:disabled{opacity:.5;cursor:default}.EtEeYG_secondary{border:1px solid var(--dsw-alias-border-l2);min-height:36px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;background:0 0;border-radius:10px;padding:0 14px}.EtEeYG_secondary:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_composeBackdrop{background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) 72%, transparent);place-items:center;padding:24px;display:grid;position:absolute;inset:58px 0 0;overflow:auto}.EtEeYG_composeCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:min(360px,100%);box-shadow:var(--dsw-shadow-lv3);border-radius:14px;gap:12px;padding:20px;display:grid}.EtEeYG_composeCard h3{margin:0;font-size:16px;line-height:24px}.EtEeYG_composeCard p{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}.EtEeYG_composeCard label{color:var(--dsw-alias-label-secondary);gap:6px;font-size:13px;line-height:20px;display:grid}.EtEeYG_composeCard input,.EtEeYG_composeCard textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:10px;padding:9px 12px}.EtEeYG_composeCard input{height:40px;padding-block:0}.EtEeYG_composeCard textarea{resize:vertical;min-height:92px}.EtEeYG_composeActions{justify-content:flex-end;gap:8px;display:flex}.EtEeYG_logoutWarning{color:var(--dsw-alias-label-secondary);gap:8px;font-size:13px;line-height:20px;display:grid}.EtEeYG_logoutWarning p{margin:0}.EtEeYG_logoutConfirm{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.EtEeYG_compactModal.EtEeYG_compactModal{max-height:calc(100vh - 48px)}.EtEeYG_compactModalContent{min-height:0;overflow-y:auto}.EtEeYG_linkButton{color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:0}.EtEeYG_notice{color:var(--dsw-alias-state-success-primary);text-align:center}.EtEeYG_identityAccess{flex:1;min-height:0;overflow:hidden}.EtEeYG_recoveryForm{width:100%;min-width:0;color:var(--dsw-alias-label-secondary);gap:14px;display:grid}.EtEeYG_recoveryForm h3{color:var(--dsw-alias-label-primary);text-align:center;margin:0}.EtEeYG_recoveryForm>p{text-align:center;margin:0;font-size:13px;line-height:20px}.EtEeYG_recoveryForm>label:not(.EtEeYG_recoveryConfirmation){gap:6px;font-size:13px;line-height:20px;display:grid}.EtEeYG_recoveryForm>label>input:not([type=checkbox]){box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:100%;height:40px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;padding:0 12px}.EtEeYG_recoveryForm input:focus-visible,.EtEeYG_recoveryForm button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.EtEeYG_recoveryStatusLine{border-bottom:1px solid var(--dsw-alias-border-l1);gap:3px;min-width:0;padding-bottom:10px;display:grid}.EtEeYG_recoveryStatusLine span{color:var(--dsw-alias-brand-primary);font-size:12px;font-weight:600}.EtEeYG_recoveryIdentitySummary{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;grid-template-columns:max-content minmax(0,1fr);gap:6px 14px;min-width:0;padding:12px;font-size:12px;line-height:18px;display:grid}.EtEeYG_recoveryIdentitySummary span{color:var(--dsw-alias-label-tertiary)}.EtEeYG_recoveryIdentitySummary strong{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-primary)}.EtEeYG_recoveryDiagnostics{border-top:1px solid var(--dsw-alias-border-l1);min-width:0;color:var(--dsw-alias-label-tertiary);padding-top:2px;font-size:11px;line-height:17px}.EtEeYG_recoveryDiagnostics summary{cursor:pointer;width:max-content;color:var(--dsw-alias-label-secondary);user-select:none}.EtEeYG_recoveryDiagnostics summary:hover{color:var(--dsw-alias-label-primary)}.EtEeYG_recoveryDiagnostics summary:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}.EtEeYG_recoveryDiagnostics dl{gap:6px;margin:8px 0 0;display:grid}.EtEeYG_recoveryDiagnostics dl>div{gap:2px;min-width:0;display:grid}.EtEeYG_recoveryDiagnostics dt{color:var(--dsw-alias-label-tertiary)}.EtEeYG_recoveryDiagnostics dd{min-width:0;margin:0}.EtEeYG_recoveryDiagnostics code{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);font-size:10px;line-height:16px;display:block}.EtEeYG_recoveryImpact{border-left:3px solid var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2);gap:6px;padding:12px;display:grid}.EtEeYG_recoveryImpact p{align-items:flex-start;gap:7px;margin:0;font-size:12px;line-height:18px;display:flex}.EtEeYG_recoveryImpact svg{flex:none;margin-top:2px}.EtEeYG_recoveryImpact p[data-tone=success] svg{color:var(--dsw-alias-state-success-primary)}.EtEeYG_recoveryImpact p[data-tone=neutral] svg{color:var(--dsw-alias-label-tertiary)}.EtEeYG_recoveryHandle{overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);text-align:center;margin:-8px 0 0;font-size:13px;line-height:20px}.EtEeYG_recoveryConfirmationCopy{color:var(--dsw-alias-label-secondary);text-align:left;margin:0;font-size:12px;line-height:18px}.EtEeYG_recoveryProgressPanel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);text-align:center;border-radius:8px;justify-items:center;gap:10px;min-width:0;padding:16px;display:grid}.EtEeYG_recoveryProgressPanel>svg{color:var(--dsw-alias-brand-primary);animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_recoveryProgressPanel p{margin:0;font-size:12px;line-height:18px}.EtEeYG_recoveryProgressPanel button{justify-content:center;align-items:center;gap:6px;width:100%;display:flex}.EtEeYG_chat{flex:1;grid-template-columns:240px minmax(0,1fr);min-height:0;display:grid}.EtEeYG_roster{border-right:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);flex-direction:column;min-width:0;display:flex}.EtEeYG_identityCard{background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;gap:2px;margin:14px;padding:12px;display:flex}.EtEeYG_identityNameRow{align-items:center;min-width:0;min-height:24px;display:flex}.EtEeYG_profileAvatar{background:var(--dsw-alias-interactive-bg-active);width:24px;height:24px;color:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;place-items:center;margin-right:7px;display:grid}.EtEeYG_identityNameText{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:14px;line-height:22px;overflow:hidden}.EtEeYG_identityName{min-width:0;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:text;background:0 0;border:0;flex:1;padding:0;font-size:16px;font-weight:600;line-height:24px;overflow:hidden}.EtEeYG_identityName:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}.EtEeYG_identityEdit{width:24px;height:24px;color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:.72;background:0 0;border:0;border-radius:6px;flex:none;place-items:center;margin-left:4px;padding:0;transition:opacity .12s;display:grid}.EtEeYG_identityNameRow:hover .EtEeYG_identityEdit,.EtEeYG_identityNameRow:focus-within .EtEeYG_identityEdit{opacity:1}.EtEeYG_identityEdit:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_identityEditor{flex:1;align-items:center;gap:4px;min-width:0;display:flex}.EtEeYG_identityEditor input{border:1px solid var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1);min-width:0;height:28px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:7px;outline:none;flex:1;padding:0 8px;font-size:13px}.EtEeYG_identityEditor button{width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_identityEditor button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_identityEditor button:disabled,.EtEeYG_identityName:disabled{cursor:default;opacity:.5}.EtEeYG_identityEdit:disabled{cursor:default}.EtEeYG_identityHandle{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:16px;overflow:hidden}.EtEeYG_identityStatus{color:var(--dsw-alias-state-success-primary);margin-top:4px;font-size:12px;line-height:18px}.EtEeYG_identityError{color:var(--dsw-alias-state-error-primary);margin-top:4px;font-size:11px;line-height:16px}.EtEeYG_identityCard i{background:var(--dsw-alias-state-success-primary);border-radius:50%;width:6px;height:6px;margin-right:5px;display:inline-block}.EtEeYG_profileBio{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:6px 0 2px;font-size:11px;line-height:17px;display:-webkit-box;overflow:hidden}.EtEeYG_profileTags{flex-wrap:wrap;gap:4px;margin-top:5px;display:flex}.EtEeYG_profileTags>span{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);min-width:0;max-width:100%;min-height:20px;color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;border-radius:7px;align-items:center;gap:3px;padding:0 6px;font-size:10px;line-height:16px;display:inline-flex}.EtEeYG_profileTags>span>button{width:16px;height:16px;color:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px;place-items:center;padding:0;display:grid}.EtEeYG_profileTags>span>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_profileEditor{gap:10px;display:grid}.EtEeYG_profileEditor label{color:var(--dsw-alias-label-secondary);gap:4px;font-size:11px;line-height:16px;display:grid;position:relative}.EtEeYG_profileEditor label>small{color:var(--dsw-alias-label-tertiary);font-size:10px;position:absolute;top:0;right:1px}.EtEeYG_profileEditor input,.EtEeYG_profileEditor textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:7px;padding:7px 8px;font-size:12px}.EtEeYG_profileEditor input{height:32px;padding-block:0}.EtEeYG_profileEditor textarea{resize:vertical}.EtEeYG_profileTagEditor{gap:4px;display:grid}.EtEeYG_profileTagEditor>div:first-of-type{grid-template-columns:minmax(0,1fr) 30px;gap:5px;display:grid}.EtEeYG_profileTagEditor>div:first-of-type button{border:1px solid var(--dsw-alias-border-l2);width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:7px;place-items:center;padding:0;display:grid}.EtEeYG_profileEditorActions{grid-template-columns:1fr 1fr;gap:6px;margin-top:2px;display:grid}.EtEeYG_profileEditorActions button{min-width:0;padding-inline:6px;font-size:12px}.EtEeYG_modePanel{flex:1;min-height:0;display:none}.EtEeYG_modePanel[data-active]{display:flex}.EtEeYG_modeTabs{background:var(--dsw-alias-bg-layer-3);border-radius:9px;grid-template-columns:1fr 1fr;gap:4px;margin:0 14px 12px;padding:3px;display:grid}.EtEeYG_modeTabs button{min-height:30px;color:var(--dsw-alias-label-tertiary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:7px;justify-content:center;align-items:center;gap:5px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.EtEeYG_modeTabs button:hover{color:var(--dsw-alias-label-primary)}.EtEeYG_modeTabs button[aria-selected=true]{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv1)}.EtEeYG_modeTabs small{min-width:18px;color:var(--dsw-alias-brand-primary);font-size:10px;line-height:14px}.EtEeYG_rosterHeader{justify-content:space-between;align-items:center;min-height:32px;padding:0 8px 8px 16px;display:flex}.EtEeYG_rosterTitle{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.EtEeYG_rosterAction{width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:9px;place-items:center;padding:0;display:grid}.EtEeYG_rosterAction:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupRecoveryNotice{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;align-items:flex-start;gap:8px;margin:0 8px 8px;padding:9px 10px;display:flex}.EtEeYG_groupRecoveryNotice[data-status=blocked]{border-color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupRecoveryNotice>span{flex:1;gap:2px;min-width:0;display:grid}.EtEeYG_groupRecoveryNotice strong{font-size:12px;line-height:18px}.EtEeYG_groupRecoveryNotice small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.EtEeYG_groupRecoveryNotice button{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_groupRecoveryNotice button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupRecoveryNotice button:disabled{cursor:default;opacity:.5}.EtEeYG_conversationList{flex:1;min-height:0;padding:0 8px;overflow:auto}.EtEeYG_conversationRow{width:100%;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:10px;align-items:center;gap:10px;padding:9px;display:flex}.EtEeYG_conversationRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_conversationRow[data-active]{background:var(--dsw-alias-interactive-bg-active)}.EtEeYG_avatar{background:var(--dsw-alias-interactive-bg-active);width:34px;height:34px;color:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;place-items:center;font-size:12px;line-height:18px;display:grid;position:relative;overflow:visible}.EtEeYG_conversationUnreadBadge{border:2px solid var(--dsw-alias-bg-layer-2);background:var(--dsw-alias-state-error-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-inverted);box-sizing:border-box;pointer-events:none;border-radius:9px;place-items:center;padding:0 4px;font-size:10px;font-weight:600;line-height:14px;display:grid;position:absolute;top:-6px;right:-7px}.EtEeYG_conversationText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.EtEeYG_conversationHeader{align-items:center;gap:8px;min-width:0;display:flex}.EtEeYG_conversationHeader strong{flex:1;min-width:0}.EtEeYG_conversationTime{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;font-weight:400;line-height:16px}.EtEeYG_conversationText strong,.EtEeYG_conversationText small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_conversationText strong{font-size:13px;line-height:20px}.EtEeYG_conversationText small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.EtEeYG_more{background:var(--dsw-alias-button-elevated-fill);color:var(--dsw-alias-label-secondary);margin:8px}.EtEeYG_more:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_thread{flex-direction:column;min-width:0;min-height:0;display:flex;position:relative}.EtEeYG_threadHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:8px;height:56px;padding:0 14px;display:flex}.EtEeYG_threadTitle{flex-direction:column;flex:1;min-width:0;display:flex}.EtEeYG_threadTitle strong,.EtEeYG_threadTitle small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_threadHeader small{color:var(--dsw-alias-label-tertiary)}.EtEeYG_threadAction{width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:8px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_threadAction:hover,.EtEeYG_threadAction[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupDetails{z-index:4;border-left:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:min(360px,100%);min-width:0;box-shadow:var(--dsw-shadow-lv2);flex-direction:column;display:flex;position:absolute;top:56px;bottom:0;right:0;overflow:hidden}.EtEeYG_groupDetailsHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:12px;min-height:54px;padding:0 12px 0 16px;display:flex}.EtEeYG_groupDetailsHeader>div{flex-direction:column;flex:1;min-width:0;display:flex}.EtEeYG_groupDetailsHeader strong{font-size:14px;line-height:21px}.EtEeYG_groupDetailsHeader small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:15px;overflow:hidden}.EtEeYG_groupDetailsHeader button,.EtEeYG_groupMemberHeading button,.EtEeYG_groupMemberRemove{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_groupDetailsHeader button:hover,.EtEeYG_groupMemberHeading button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupDetailsLoading{color:var(--dsw-alias-label-tertiary);margin:auto;font-size:12px}.EtEeYG_groupSummary{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;gap:5px;padding:16px;display:grid}.EtEeYG_groupSummary>strong{font-size:15px;line-height:22px}.EtEeYG_groupSummary>code{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;overflow:hidden}.EtEeYG_groupSummary>p{color:var(--dsw-alias-label-secondary);margin:3px 0 0;font-size:12px;line-height:18px}.EtEeYG_groupSummary dl{grid-template-columns:1fr 1fr;gap:8px;margin:8px 0 0;display:grid}.EtEeYG_groupSummary dl>div{gap:1px;display:grid}.EtEeYG_groupSummary dt{color:var(--dsw-alias-label-tertiary);font-size:10px}.EtEeYG_groupSummary dd{color:var(--dsw-alias-label-primary);margin:0;font-size:12px}.EtEeYG_groupInvite{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;gap:5px;padding:12px 16px;display:grid}.EtEeYG_groupInvite label{color:var(--dsw-alias-label-secondary);font-size:11px}.EtEeYG_groupInvite>div{grid-template-columns:minmax(0,1fr) 32px;gap:6px;display:grid}.EtEeYG_groupInvite input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:0;height:32px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:7px;padding:0 9px;font-size:12px}.EtEeYG_groupInvite button{background:var(--dsw-alias-button-primary-fill);width:32px;height:32px;color:var(--dsw-alias-label-primary-inverted);cursor:pointer;border:0;border-radius:7px;place-items:center;padding:0;display:grid}.EtEeYG_groupInvite button:disabled{cursor:default;opacity:.7}.EtEeYG_groupInvite button[data-busy] svg{animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_groupInviteStatus{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-tertiary);margin:0;font-size:10px;line-height:16px}.EtEeYG_groupInviteStatus[data-state=success]{color:var(--dsw-alias-state-success-primary)}.EtEeYG_groupInviteStatus[data-state=error]{color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupMemberSection{flex-direction:column;flex:1;min-height:0;display:flex}.EtEeYG_groupMemberHeading{flex:none;justify-content:space-between;align-items:center;min-height:40px;padding:0 12px 0 16px;display:flex}.EtEeYG_groupMemberHeading strong{font-size:12px;line-height:18px}.EtEeYG_groupMemberList{min-height:0;padding:0 8px;overflow:auto}.EtEeYG_groupMemberRow{border-bottom:1px solid var(--dsw-alias-border-l1);grid-template-columns:30px minmax(0,1fr) auto 28px;align-items:center;gap:8px;min-height:48px;padding:4px 6px;display:grid}.EtEeYG_groupMemberAvatar{background:var(--dsw-alias-interactive-bg-active);width:30px;height:30px;color:var(--dsw-alias-brand-primary);border-radius:50%;place-items:center;font-size:11px;display:grid}.EtEeYG_groupMemberIdentity{flex-direction:column;min-width:0;display:flex}.EtEeYG_groupMemberIdentity strong{text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:5px;font-size:12px;line-height:18px;display:flex;overflow:hidden}.EtEeYG_groupMemberIdentity strong small{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-brand-primary);border-radius:4px;padding:0 4px;font-size:9px}.EtEeYG_groupMemberIdentity>small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:15px;overflow:hidden}.EtEeYG_groupMemberRole{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:10px}.EtEeYG_groupMemberRemove:hover{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupDetailsFooter{border-top:1px solid var(--dsw-alias-border-l1);flex:none;justify-content:space-between;align-items:center;gap:8px;min-height:46px;padding:0 16px;display:flex}.EtEeYG_groupDetailsFooter small{color:var(--dsw-alias-label-tertiary);font-size:10px}.EtEeYG_dangerText{color:var(--dsw-alias-state-error-primary);cursor:pointer;font:inherit;background:0 0;border:0;padding:0;font-size:12px}.EtEeYG_dangerText:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.EtEeYG_groupDetailsError{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);flex:none;padding:8px 12px;font-size:11px;line-height:17px}.EtEeYG_summaryTrigger{min-height:30px;color:var(--dsw-alias-brand-primary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:8px;flex:none;align-items:center;gap:5px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.EtEeYG_summaryTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryTrigger:disabled{cursor:default;opacity:.7}.EtEeYG_summaryTrigger[aria-expanded=true]>svg:last-child{transform:rotate(180deg)}.EtEeYG_summaryTrigger>svg:first-child{flex:none}.EtEeYG_summaryPanel{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-height:0;max-height:min(220px,33%);color:var(--dsw-alias-label-primary);border-radius:10px;flex:0 33%;margin:8px 10px 0;overflow:hidden}.EtEeYG_summaryPanel[data-collapsed]{flex-basis:auto;max-height:42px}.EtEeYG_summaryHeader{border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:9px;min-height:38px;padding:0 8px 0 12px;display:flex}.EtEeYG_summaryHeader>span{color:var(--dsw-alias-brand-primary);align-items:center;gap:6px;display:flex}.EtEeYG_summaryHeader>span strong{color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}.EtEeYG_summaryHeader>small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:11px;line-height:16px;overflow:hidden}.EtEeYG_summaryHeader>button{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_summaryHeader>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryCollapsed{width:100%;min-height:40px;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:8px;padding:0 10px 0 12px;display:grid}.EtEeYG_summaryCollapsed:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryCollapsed>span{color:var(--dsw-alias-brand-primary);align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}.EtEeYG_summaryCollapsed>small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_summaryCollapsed>em{color:var(--dsw-alias-state-warn-label);white-space:nowrap;font-size:11px;font-style:normal}.EtEeYG_summaryLoading{min-height:88px;color:var(--dsw-alias-brand-primary);justify-content:center;align-items:center;gap:10px;padding:16px;display:flex}.EtEeYG_summaryLoading>svg,.EtEeYG_summaryTrigger:disabled>svg:first-child{animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_summaryLoading>span{flex-direction:column;gap:2px;display:flex}.EtEeYG_summaryLoading strong{color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}.EtEeYG_summaryLoading small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.EtEeYG_summaryError{min-height:58px;color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:12px;padding:12px;font-size:12px;line-height:18px;display:flex}.EtEeYG_summaryError>span{overflow-wrap:anywhere;min-width:0}.EtEeYG_summaryError button,.EtEeYG_summaryStale button{border:1px solid var(--dsw-alias-border-l2);min-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;background:0 0;border-radius:7px;flex:none;align-items:center;gap:5px;padding:0 8px;font-size:11px;display:flex}.EtEeYG_summaryError button:hover,.EtEeYG_summaryStale button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryStale{background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-state-warn-label);justify-content:space-between;align-items:center;gap:10px;padding:6px 10px;font-size:11px;line-height:16px;display:flex}.EtEeYG_summaryBody{gap:10px;max-height:118px;padding:10px 12px;display:grid;overflow:auto}.EtEeYG_summarySection h4{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;margin:0 0 4px;font-size:12px;line-height:18px;display:flex}.EtEeYG_summarySection h4>svg{color:var(--dsw-alias-label-secondary);flex:none}.EtEeYG_summarySection ul{color:var(--dsw-alias-label-secondary);gap:2px;margin:0;padding-left:18px;font-size:11px;line-height:17px;display:grid}.EtEeYG_summarySection li{overflow-wrap:anywhere;padding-left:1px}.EtEeYG_summarySection p{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:17px}.EtEeYG_summarySection b{color:var(--dsw-alias-label-primary);font-weight:500}.EtEeYG_summaryActions{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:auto 1fr auto auto;align-items:center;gap:4px;min-height:34px;padding:0 8px;display:grid}.EtEeYG_summaryActions button{min-height:26px;color:var(--dsw-alias-brand-primary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:6px;align-items:center;gap:5px;padding:0 6px;font-size:11px;line-height:16px;display:flex}.EtEeYG_summaryActions button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryPrivacy{border-top:1px solid var(--dsw-alias-border-l1);min-height:28px;color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;padding:0 10px;font-size:10px;line-height:15px;display:flex}.EtEeYG_summaryPrivacy svg{flex:none}.EtEeYG_summaryCopyError{color:var(--dsw-alias-state-error-primary);padding:4px 10px;font-size:10px;line-height:15px}@keyframes EtEeYG_summary-spin{to{transform:rotate(360deg)}}.EtEeYG_back{display:none}.EtEeYG_historyShell{flex:1;min-height:0;position:relative}.EtEeYG_history{box-sizing:border-box;flex-direction:column;gap:12px;height:100%;min-height:0;padding:16px;display:flex;overflow:auto}.EtEeYG_historyLoading{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;margin:auto;font-size:12px;line-height:18px;display:flex}.EtEeYG_historyLoading>svg{color:var(--dsw-alias-brand-primary);animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_latestMessages{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-floating-fill);min-width:30px;min-height:30px;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv2);cursor:pointer;font:inherit;border-radius:16px;justify-content:center;align-items:center;gap:5px;padding:0 9px;font-size:11px;line-height:16px;display:flex;position:absolute;bottom:12px;left:50%;transform:translate(-50%)}.EtEeYG_latestMessages:hover{background:var(--dsw-alias-button-floating-hover)}.EtEeYG_message{align-self:flex-start;max-width:min(78%,420px)}.EtEeYG_message[data-outgoing]{align-self:flex-end}.EtEeYG_messageMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;gap:10px;margin-bottom:3px;font-size:11px;line-height:16px;display:flex}.EtEeYG_message p,.EtEeYG_attachment{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;border-radius:12px;margin:0;padding:9px 11px;line-height:20px}.EtEeYG_message[data-outgoing] p,.EtEeYG_message[data-outgoing] .EtEeYG_attachment{background:var(--dsw-alias-interactive-bg-active)}.EtEeYG_mention{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-brand-primary);border-radius:3px;padding:0 2px;font-weight:600}.EtEeYG_pendingMessage{grid-template-columns:auto minmax(0,1fr);align-self:flex-end;align-items:end;gap:7px;max-width:min(78%,420px);display:grid}.EtEeYG_pendingMessageSpinner{color:var(--dsw-alias-label-tertiary);margin-bottom:12px;animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_pendingMessageContent{opacity:.82;min-width:0}.EtEeYG_pendingMessageContent>p,.EtEeYG_pendingAttachment{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;border-radius:12px;margin:0;padding:9px 11px;line-height:20px}.EtEeYG_pendingAttachment{align-items:center;gap:9px;display:flex}.EtEeYG_pendingAttachment>svg{color:var(--dsw-alias-label-secondary);flex:none}.EtEeYG_pendingAttachment span{flex-direction:column;min-width:0;display:flex}.EtEeYG_pendingAttachment strong{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_pendingAttachment small{color:var(--dsw-alias-label-tertiary)}.EtEeYG_pendingMessageContent>.EtEeYG_pendingCaption{color:var(--dsw-alias-label-secondary);background:0 0;border:0;margin-top:4px;padding:4px 8px;font-size:12px}.EtEeYG_attachment{cursor:pointer;font:inherit;text-align:left;align-items:center;gap:12px;display:flex}.EtEeYG_attachment span{flex-direction:column;min-width:0;display:flex}.EtEeYG_attachment strong{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_attachment small{color:var(--dsw-alias-label-tertiary)}.EtEeYG_attachment:disabled{cursor:default}.EtEeYG_imageAttachment{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:280px;max-width:100%;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;text-align:left;border-radius:12px;margin:0;padding:0;display:block;overflow:hidden}.EtEeYG_imageAttachment img{background:var(--dsw-alias-bg-layer-1);object-fit:contain;width:100%;max-height:280px;display:block}.EtEeYG_imageAttachment span{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:0 10px;padding:7px 9px;display:grid}.EtEeYG_imageAttachment strong{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_imageAttachment small{color:var(--dsw-alias-label-tertiary);grid-column:1}.EtEeYG_imageAttachment svg{grid-area:1/2/span 2}.EtEeYG_message .EtEeYG_caption{color:var(--dsw-alias-label-secondary);background:0 0;margin-top:4px;padding:4px 8px;font-size:12px}.EtEeYG_inlineError{color:var(--dsw-alias-state-error-primary);margin-top:4px;display:block}.EtEeYG_empty{color:var(--dsw-alias-label-tertiary);text-align:center;margin:auto;padding:20px}.EtEeYG_composer{border-top:1px solid var(--dsw-alias-border-l1);flex:none;gap:8px;padding:10px 14px 14px;display:grid}.EtEeYG_filePicker{border:1px solid var(--dsw-alias-border-l2);width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:50%;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_filePicker:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_filePicker:disabled{opacity:.45;cursor:default}.EtEeYG_fileInput{display:none}.EtEeYG_composeInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:10px;gap:6px;min-width:0;padding:9px 10px 8px;display:grid;position:relative}.EtEeYG_mentionCandidates{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);max-height:180px;box-shadow:var(--dsw-shadow-lv2);border-radius:8px;padding:5px;position:absolute;bottom:calc(100% + 7px);left:0;right:0;overflow:auto}.EtEeYG_mentionCandidates button{width:100%;min-height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;grid-template-rows:auto auto;grid-template-columns:28px minmax(0,1fr);align-items:center;column-gap:8px;padding:4px 7px;display:grid}.EtEeYG_mentionCandidates button:hover,.EtEeYG_mentionCandidates button[aria-selected=true]{background:var(--dsw-alias-interactive-bg-active)}.EtEeYG_mentionCandidates button>span{background:var(--dsw-alias-bg-layer-3);width:28px;height:28px;color:var(--dsw-alias-brand-primary);border-radius:50%;grid-row:1/span 2;place-items:center;font-size:10px;display:grid}.EtEeYG_mentionCandidates strong,.EtEeYG_mentionCandidates small{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.EtEeYG_mentionCandidates strong{align-self:end;font-size:12px;line-height:16px}.EtEeYG_mentionCandidates small{color:var(--dsw-alias-label-tertiary);align-self:start;font-size:10px;line-height:14px}.EtEeYG_composeInput:focus-within{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.EtEeYG_composeInput textarea{resize:none;background:0 0;border:0;border-radius:0;outline:0;min-width:0;min-height:42px;padding:0}.EtEeYG_composeInput textarea:focus-visible{outline:0}.EtEeYG_composeActions{justify-content:space-between;align-items:center;min-height:32px;display:flex}.EtEeYG_filePreview{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;align-items:center;gap:8px;width:min(240px,100% - 8px);min-height:36px;padding:5px 28px 5px 8px;display:flex;position:relative}.EtEeYG_filePreview[data-image]{width:72px;height:72px;min-height:0;padding:0}.EtEeYG_filePreview img{object-fit:cover;border-radius:9px;width:72px;height:72px;display:block}.EtEeYG_filePreviewIcon{color:var(--dsw-alias-label-secondary);flex:none;place-items:center;display:grid}.EtEeYG_filePreviewName{min-width:0;color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.EtEeYG_removeFile{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-floating-fill);width:22px;height:22px;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv1);cursor:pointer;border-radius:50%;place-items:center;padding:0;display:grid;position:absolute;top:-7px;right:-7px}.EtEeYG_removeFile:hover{background:var(--dsw-alias-button-floating-hover)}.EtEeYG_send{background:var(--dsw-alias-button-primary-fill);width:32px;height:32px;color:var(--dsw-alias-label-primary-inverted);cursor:pointer;border:0;border-radius:50%;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_send:disabled{opacity:.45;cursor:default}.EtEeYG_error{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;flex:none;padding:8px 14px;font-size:12px;line-height:18px}.EtEeYG_pending{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-inverted);box-shadow:var(--dsw-shadow-lv2);border-radius:9px;padding:7px 10px;font-size:12px;line-height:18px;position:absolute;bottom:14px;right:14px}@media (width<=620px){.EtEeYG_trigger span{display:none}.EtEeYG_trigger{justify-content:center;width:36px;padding:0}.EtEeYG_drawer{width:calc(100vw - 56px);min-width:0}.EtEeYG_chat{grid-template-columns:1fr}.EtEeYG_thread{display:none}.EtEeYG_thread[data-visible]{display:flex}.EtEeYG_roster[data-hidden]{display:none}.EtEeYG_back{display:grid}.EtEeYG_summaryPanel{max-height:min(190px,33%);margin-left:8px;margin-right:8px}.EtEeYG_summaryTrigger>span{display:none}.EtEeYG_summaryTrigger{justify-content:center;width:30px;padding:0}.EtEeYG_summaryTrigger>svg:last-child{display:none}}@media (height<=420px){.EtEeYG_drawer{border-radius:10px}.EtEeYG_drawerHeader{height:44px;padding:0 8px 0 12px}.EtEeYG_drawerHeader h2{font-size:14px;line-height:20px}.EtEeYG_drawerHeader button,.EtEeYG_back{width:28px;height:28px}.EtEeYG_centerState,.EtEeYG_threadEmpty{justify-content:flex-start;gap:8px;min-height:0;padding:12px;overflow:auto}.EtEeYG_registrationIcon{width:32px;height:32px}.EtEeYG_composeBackdrop{place-items:start center;padding:8px;inset:44px 0 0}.EtEeYG_composeCard{border-radius:10px;gap:8px;padding:12px}.EtEeYG_recoveryForm{gap:8px}.EtEeYG_identityCard{border-radius:8px;margin:6px 8px;padding:7px 9px}.EtEeYG_profileBio,.EtEeYG_profileTags,.EtEeYG_identityStatus{display:none}.EtEeYG_modeTabs{margin:0 8px 4px}.EtEeYG_modeTabs button{min-height:26px}.EtEeYG_rosterHeader{min-height:28px;padding:0 4px 2px 12px}.EtEeYG_conversationRow{gap:7px;padding:5px 7px}.EtEeYG_avatar{width:28px;height:28px}.EtEeYG_threadHeader{gap:5px;height:44px;padding:0 8px}.EtEeYG_groupDetails{top:44px;overflow-y:auto}.EtEeYG_groupDetailsHeader{z-index:2;background:var(--dsw-alias-bg-layer-1);min-height:44px;padding-left:12px;position:sticky;top:0}.EtEeYG_groupSummary{gap:2px;padding:8px 12px}.EtEeYG_groupSummary dl{gap:6px;margin-top:3px}.EtEeYG_groupInvite{gap:3px;padding:7px 12px}.EtEeYG_groupMemberSection{flex:none}.EtEeYG_groupMemberHeading{min-height:32px;padding-left:12px}.EtEeYG_groupMemberList{overflow:visible}.EtEeYG_groupMemberRow{min-height:40px}.EtEeYG_groupDetailsFooter{background:var(--dsw-alias-bg-layer-1);min-height:40px;padding:0 12px;position:sticky;bottom:0}.EtEeYG_history{gap:6px;padding:8px}.EtEeYG_composer{gap:4px;padding:5px 8px 7px}.EtEeYG_composeInput{gap:3px;padding:5px 7px 4px}.EtEeYG_composeInput textarea{height:28px;min-height:28px}.EtEeYG_composeActions{min-height:28px}.EtEeYG_filePicker,.EtEeYG_send{width:28px;height:28px}.EtEeYG_mentionCandidates{max-height:72px}.EtEeYG_compactModal.EtEeYG_compactModal{border-radius:12px;gap:10px;max-height:calc(100vh - 48px);padding-bottom:12px}}@media (prefers-reduced-motion:reduce){.EtEeYG_drawer{scroll-behavior:auto;transition:none}.EtEeYG_summaryLoading>svg,.EtEeYG_summaryTrigger:disabled>svg:first-child,.EtEeYG_historyLoading>svg,.EtEeYG_recoveryProgressPanel>svg,.EtEeYG_pendingMessageSpinner{animation:none}}";
9654
+ const css$5 = ".EtEeYG_trigger{z-index:2;border:1px solid var(--dsw-alias-border-l2);width:48px;height:48px;color:var(--dsw-alias-brand-primary);box-shadow:var(--dsw-shadow-lv2);cursor:grab;font:inherit;touch-action:none;user-select:none;background:#fff;border-radius:50%;place-items:center;padding:0;display:grid;position:fixed;overflow:visible}.EtEeYG_trigger:hover{box-shadow:var(--dsw-shadow-lv3);background:#fff}.EtEeYG_trigger:active,.EtEeYG_trigger[data-dragging]{cursor:grabbing}.EtEeYG_launcherIcon{object-fit:cover;pointer-events:none;border-radius:50%;width:100%;height:100%;display:block}.EtEeYG_unreadBadge{border:2px solid var(--dsw-alias-bg-base);background:var(--dsw-alias-state-error-primary);color:#fff;box-sizing:border-box;pointer-events:none;border-radius:10px;place-items:center;min-width:20px;height:20px;padding:0 5px;font-size:11px;font-weight:600;line-height:16px;display:grid;position:absolute;top:-5px;right:-5px}.EtEeYG_trigger:focus-visible,.EtEeYG_drawer button:focus-visible,.EtEeYG_drawer input:focus-visible,.EtEeYG_drawer textarea:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.EtEeYG_drawer{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);z-index:1;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:min(720px,100vw - 80px);min-width:min(360px,100vw - 80px);height:min(720px,100vh - 16px);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3);border-radius:16px;flex-direction:column;transition:width .16s;display:flex;position:fixed;overflow:hidden}.EtEeYG_drawer[data-mode=mail]{width:min(1040px,100vw - 80px)}.EtEeYG_drawer[data-resizing]{user-select:none;transition:none}.EtEeYG_resizeHandle{z-index:5;touch-action:none;user-select:none;position:absolute}.EtEeYG_resizeHandle[data-resize-handle=n],.EtEeYG_resizeHandle[data-resize-handle=s]{cursor:ns-resize;height:8px;left:14px;right:14px}.EtEeYG_resizeHandle[data-resize-handle=n]{top:0}.EtEeYG_resizeHandle[data-resize-handle=s]{bottom:0}.EtEeYG_resizeHandle[data-resize-handle=e],.EtEeYG_resizeHandle[data-resize-handle=w]{cursor:ew-resize;width:8px;top:14px;bottom:14px}.EtEeYG_resizeHandle[data-resize-handle=e]{right:0}.EtEeYG_resizeHandle[data-resize-handle=w]{left:0}.EtEeYG_resizeHandle[data-resize-handle=ne],.EtEeYG_resizeHandle[data-resize-handle=se],.EtEeYG_resizeHandle[data-resize-handle=sw],.EtEeYG_resizeHandle[data-resize-handle=nw]{width:14px;height:14px}.EtEeYG_resizeHandle[data-resize-handle=ne]{cursor:nesw-resize;top:0;right:0}.EtEeYG_resizeHandle[data-resize-handle=se]{cursor:nwse-resize;bottom:0;right:0}.EtEeYG_resizeHandle[data-resize-handle=sw]{cursor:nesw-resize;bottom:0;left:0}.EtEeYG_resizeHandle[data-resize-handle=nw]{cursor:nwse-resize;top:0;left:0}.EtEeYG_drawerHeader{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;touch-action:none;user-select:none;flex:none;align-items:center;gap:8px;height:58px;padding:0 14px 0 18px;display:flex}.EtEeYG_drawerHeader[data-dragging]{cursor:grabbing}.EtEeYG_drawerHeader>div{flex:1;align-items:center;gap:8px;display:flex}.EtEeYG_drawerHeader h2{margin:0;font-size:16px;line-height:24px}.EtEeYG_drawerHeader button,.EtEeYG_back{cursor:pointer;width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:9px;place-items:center;padding:0;display:grid}.EtEeYG_drawerHeader button:hover,.EtEeYG_back:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_centerState,.EtEeYG_threadEmpty{text-align:center;color:var(--dsw-alias-label-secondary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:14px;padding:32px;display:flex}.EtEeYG_centerState p{overflow-wrap:anywhere;max-width:420px;margin:0}.EtEeYG_registrationIcon{background:var(--dsw-alias-interactive-bg-active);width:48px;height:48px;color:var(--dsw-alias-brand-primary);border-radius:50%;justify-self:center;place-items:center;display:grid}.EtEeYG_fileDraft input,.EtEeYG_composeRow textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:10px}.EtEeYG_primary,.EtEeYG_more,.EtEeYG_fileDraft button{background:var(--dsw-alias-button-primary-fill);min-height:36px;color:var(--dsw-alias-label-primary-inverted);cursor:pointer;font:inherit;border:0;border-radius:10px;padding:0 14px}.EtEeYG_primary:hover,.EtEeYG_fileDraft button:hover{background:var(--dsw-alias-button-primary-hover)}.EtEeYG_primary:disabled,.EtEeYG_fileDraft button:disabled{opacity:.5;cursor:default}.EtEeYG_secondary{border:1px solid var(--dsw-alias-border-l2);min-height:36px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;background:0 0;border-radius:10px;padding:0 14px}.EtEeYG_secondary:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_composeBackdrop{background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) 72%, transparent);place-items:center;padding:24px;display:grid;position:absolute;inset:58px 0 0;overflow:auto}.EtEeYG_composeCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:min(360px,100%);box-shadow:var(--dsw-shadow-lv3);border-radius:14px;gap:12px;padding:20px;display:grid}.EtEeYG_composeCard h3{margin:0;font-size:16px;line-height:24px}.EtEeYG_composeCard p{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}.EtEeYG_composeCard label{color:var(--dsw-alias-label-secondary);gap:6px;font-size:13px;line-height:20px;display:grid}.EtEeYG_composeCard input,.EtEeYG_composeCard textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:10px;padding:9px 12px}.EtEeYG_composeCard input{height:40px;padding-block:0}.EtEeYG_composeCard textarea{resize:vertical;min-height:92px}.EtEeYG_composeActions{justify-content:flex-end;gap:8px;display:flex}.EtEeYG_logoutWarning{color:var(--dsw-alias-label-secondary);gap:8px;font-size:13px;line-height:20px;display:grid}.EtEeYG_logoutWarning p{margin:0}.EtEeYG_logoutConfirm{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.EtEeYG_compactModal.EtEeYG_compactModal{max-height:calc(100vh - 48px)}.EtEeYG_compactModalContent{min-height:0;overflow-y:auto}.EtEeYG_linkButton{color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:0}.EtEeYG_notice{color:var(--dsw-alias-state-success-primary);text-align:center}.EtEeYG_identityAccess{flex:1;min-height:0;overflow:hidden}.EtEeYG_recoveryForm{width:100%;min-width:0;color:var(--dsw-alias-label-secondary);gap:14px;display:grid}.EtEeYG_recoveryForm h3{color:var(--dsw-alias-label-primary);text-align:center;margin:0}.EtEeYG_recoveryForm>p{text-align:center;margin:0;font-size:13px;line-height:20px}.EtEeYG_recoveryForm>label:not(.EtEeYG_recoveryConfirmation){gap:6px;font-size:13px;line-height:20px;display:grid}.EtEeYG_recoveryForm>label>input:not([type=checkbox]){box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:100%;height:40px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;padding:0 12px}.EtEeYG_recoveryForm input:focus-visible,.EtEeYG_recoveryForm button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.EtEeYG_recoveryStatusLine{border-bottom:1px solid var(--dsw-alias-border-l1);gap:3px;min-width:0;padding-bottom:10px;display:grid}.EtEeYG_recoveryStatusLine span{color:var(--dsw-alias-brand-primary);font-size:12px;font-weight:600}.EtEeYG_recoveryIdentitySummary{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;grid-template-columns:max-content minmax(0,1fr);gap:6px 14px;min-width:0;padding:12px;font-size:12px;line-height:18px;display:grid}.EtEeYG_recoveryIdentitySummary span{color:var(--dsw-alias-label-tertiary)}.EtEeYG_recoveryIdentitySummary strong{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-primary)}.EtEeYG_recoveryDiagnostics{border-top:1px solid var(--dsw-alias-border-l1);min-width:0;color:var(--dsw-alias-label-tertiary);padding-top:2px;font-size:11px;line-height:17px}.EtEeYG_recoveryDiagnostics summary{cursor:pointer;width:max-content;color:var(--dsw-alias-label-secondary);user-select:none}.EtEeYG_recoveryDiagnostics summary:hover{color:var(--dsw-alias-label-primary)}.EtEeYG_recoveryDiagnostics summary:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}.EtEeYG_recoveryDiagnostics dl{gap:6px;margin:8px 0 0;display:grid}.EtEeYG_recoveryDiagnostics dl>div{gap:2px;min-width:0;display:grid}.EtEeYG_recoveryDiagnostics dt{color:var(--dsw-alias-label-tertiary)}.EtEeYG_recoveryDiagnostics dd{min-width:0;margin:0}.EtEeYG_recoveryDiagnostics code{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);font-size:10px;line-height:16px;display:block}.EtEeYG_recoveryImpact{border-left:3px solid var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2);gap:6px;padding:12px;display:grid}.EtEeYG_recoveryImpact p{align-items:flex-start;gap:7px;margin:0;font-size:12px;line-height:18px;display:flex}.EtEeYG_recoveryImpact svg{flex:none;margin-top:2px}.EtEeYG_recoveryImpact p[data-tone=success] svg{color:var(--dsw-alias-state-success-primary)}.EtEeYG_recoveryImpact p[data-tone=neutral] svg{color:var(--dsw-alias-label-tertiary)}.EtEeYG_recoveryHandle{overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);text-align:center;margin:-8px 0 0;font-size:13px;line-height:20px}.EtEeYG_recoveryConfirmationCopy{color:var(--dsw-alias-label-secondary);text-align:left;margin:0;font-size:12px;line-height:18px}.EtEeYG_recoveryProgressPanel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);text-align:center;border-radius:8px;justify-items:center;gap:10px;min-width:0;padding:16px;display:grid}.EtEeYG_recoveryProgressPanel>svg{color:var(--dsw-alias-brand-primary);animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_recoveryProgressPanel p{margin:0;font-size:12px;line-height:18px}.EtEeYG_recoveryProgressPanel button{justify-content:center;align-items:center;gap:6px;width:100%;display:flex}.EtEeYG_chat{flex:1;grid-template-columns:240px minmax(0,1fr);min-height:0;display:grid}.EtEeYG_roster{border-right:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);flex-direction:column;min-width:0;display:flex}.EtEeYG_identityCard{background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;gap:2px;margin:14px;padding:12px;display:flex}.EtEeYG_identityNameRow{align-items:center;min-width:0;min-height:24px;display:flex}.EtEeYG_profileAvatar{background:var(--dsw-alias-interactive-bg-active);width:24px;height:24px;color:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;place-items:center;margin-right:7px;display:grid}.EtEeYG_identityNameText{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:14px;line-height:22px;overflow:hidden}.EtEeYG_identityName{min-width:0;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:text;background:0 0;border:0;flex:1;padding:0;font-size:16px;font-weight:600;line-height:24px;overflow:hidden}.EtEeYG_identityName:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}.EtEeYG_identityEdit{width:24px;height:24px;color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:.72;background:0 0;border:0;border-radius:6px;flex:none;place-items:center;margin-left:4px;padding:0;transition:opacity .12s;display:grid}.EtEeYG_identityNameRow:hover .EtEeYG_identityEdit,.EtEeYG_identityNameRow:focus-within .EtEeYG_identityEdit{opacity:1}.EtEeYG_identityEdit:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_identityEditor{flex:1;align-items:center;gap:4px;min-width:0;display:flex}.EtEeYG_identityEditor input{border:1px solid var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1);min-width:0;height:28px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:7px;outline:none;flex:1;padding:0 8px;font-size:13px}.EtEeYG_identityEditor button{width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_identityEditor button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_identityEditor button:disabled,.EtEeYG_identityName:disabled{cursor:default;opacity:.5}.EtEeYG_identityEdit:disabled{cursor:default}.EtEeYG_identityHandle{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:16px;overflow:hidden}.EtEeYG_identityStatus{color:var(--dsw-alias-state-success-primary);margin-top:4px;font-size:12px;line-height:18px}.EtEeYG_identityError{color:var(--dsw-alias-state-error-primary);margin-top:4px;font-size:11px;line-height:16px}.EtEeYG_identityCard i{background:var(--dsw-alias-state-success-primary);border-radius:50%;width:6px;height:6px;margin-right:5px;display:inline-block}.EtEeYG_profileBio{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:6px 0 2px;font-size:11px;line-height:17px;display:-webkit-box;overflow:hidden}.EtEeYG_profileTags{flex-wrap:wrap;gap:4px;margin-top:5px;display:flex}.EtEeYG_profileTags>span{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);min-width:0;max-width:100%;min-height:20px;color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;border-radius:7px;align-items:center;gap:3px;padding:0 6px;font-size:10px;line-height:16px;display:inline-flex}.EtEeYG_profileTags>span>button{width:16px;height:16px;color:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px;place-items:center;padding:0;display:grid}.EtEeYG_profileTags>span>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_profileEditor{gap:10px;display:grid}.EtEeYG_profileEditor label{color:var(--dsw-alias-label-secondary);gap:4px;font-size:11px;line-height:16px;display:grid;position:relative}.EtEeYG_profileEditor label>small{color:var(--dsw-alias-label-tertiary);font-size:10px;position:absolute;top:0;right:1px}.EtEeYG_profileEditor input,.EtEeYG_profileEditor textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);font:inherit;border-radius:7px;padding:7px 8px;font-size:12px}.EtEeYG_profileEditor input{height:32px;padding-block:0}.EtEeYG_profileEditor textarea{resize:vertical}.EtEeYG_profileTagEditor{gap:4px;display:grid}.EtEeYG_profileTagEditor>div:first-of-type{grid-template-columns:minmax(0,1fr) 30px;gap:5px;display:grid}.EtEeYG_profileTagEditor>div:first-of-type button{border:1px solid var(--dsw-alias-border-l2);width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:7px;place-items:center;padding:0;display:grid}.EtEeYG_profileEditorActions{grid-template-columns:1fr 1fr;gap:6px;margin-top:2px;display:grid}.EtEeYG_profileEditorActions button{min-width:0;padding-inline:6px;font-size:12px}.EtEeYG_modePanel{flex:1;min-height:0;display:none}.EtEeYG_modePanel[data-active]{display:flex}.EtEeYG_modeTabs{background:var(--dsw-alias-bg-layer-3);border-radius:9px;grid-template-columns:1fr 1fr;gap:4px;margin:0 14px 12px;padding:3px;display:grid}.EtEeYG_modeTabs button{min-height:30px;color:var(--dsw-alias-label-tertiary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:7px;justify-content:center;align-items:center;gap:5px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.EtEeYG_modeTabs button:hover{color:var(--dsw-alias-label-primary)}.EtEeYG_modeTabs button[aria-selected=true]{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv1)}.EtEeYG_modeTabs small{min-width:18px;color:var(--dsw-alias-brand-primary);font-size:10px;line-height:14px}.EtEeYG_rosterHeader{justify-content:space-between;align-items:center;min-height:32px;padding:0 8px 8px 16px;display:flex}.EtEeYG_rosterTitle{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.EtEeYG_rosterActions{align-items:center;gap:2px;display:flex}.EtEeYG_rosterAction{width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:9px;place-items:center;padding:0;display:grid}.EtEeYG_rosterAction:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_rosterActions .EtEeYG_rosterAction{position:relative}.EtEeYG_rosterActions .EtEeYG_rosterAction small{background:var(--dsw-alias-bg-layer-3);min-width:14px;height:14px;color:var(--dsw-alias-label-secondary);box-sizing:border-box;border-radius:7px;place-items:center;padding:0 3px;font-size:9px;line-height:12px;display:grid;position:absolute;top:1px;right:0}.EtEeYG_groupRecoveryNotice{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;align-items:flex-start;gap:8px;margin:0 8px 8px;padding:9px 10px;display:flex}.EtEeYG_groupRecoveryNotice[data-status=blocked]{border-color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupRecoveryNotice>span{flex:1;gap:2px;min-width:0;display:grid}.EtEeYG_groupRecoveryNotice strong{font-size:12px;line-height:18px}.EtEeYG_groupRecoveryNotice small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.EtEeYG_groupRecoveryNotice button{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_groupRecoveryNotice button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupRecoveryNotice button:disabled{cursor:default;opacity:.5}.EtEeYG_conversationList{flex:1;min-height:0;padding:0 8px;overflow:auto}.EtEeYG_conversationRow{width:100%;color:inherit;background:0 0;border-radius:10px;grid-template-columns:minmax(0,1fr) auto;align-items:center;display:grid}.EtEeYG_conversationRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_conversationRow[data-active]{background:var(--dsw-alias-interactive-bg-active)}.EtEeYG_conversationSelect{width:100%;min-width:0;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:10px;align-items:center;gap:10px;padding:9px;display:flex}.EtEeYG_conversationMenu{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;opacity:0;background:0 0;border:0;border-radius:7px;place-items:center;margin-right:5px;padding:0;display:grid}.EtEeYG_conversationRow:hover .EtEeYG_conversationMenu,.EtEeYG_conversationRow:focus-within .EtEeYG_conversationMenu,.EtEeYG_conversationMenu[aria-expanded=true]{opacity:1}.EtEeYG_conversationMenu:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.EtEeYG_conversationMenu:disabled{cursor:default;opacity:.45}.EtEeYG_avatar{background:var(--dsw-alias-interactive-bg-active);width:34px;height:34px;color:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;place-items:center;font-size:12px;line-height:18px;display:grid;position:relative;overflow:visible}.EtEeYG_conversationUnreadBadge{border:2px solid var(--dsw-alias-bg-layer-2);background:var(--dsw-alias-state-error-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-inverted);box-sizing:border-box;pointer-events:none;border-radius:9px;place-items:center;padding:0 4px;font-size:10px;font-weight:600;line-height:14px;display:grid;position:absolute;top:-6px;right:-7px}.EtEeYG_conversationText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.EtEeYG_conversationHeader{align-items:center;gap:8px;min-width:0;display:flex}.EtEeYG_conversationHeader strong{flex:1;min-width:0}.EtEeYG_conversationTime{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;font-weight:400;line-height:16px}.EtEeYG_conversationText strong,.EtEeYG_conversationText small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_conversationText strong{font-size:13px;line-height:20px}.EtEeYG_conversationText small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.EtEeYG_more{background:var(--dsw-alias-button-elevated-fill);color:var(--dsw-alias-label-secondary);margin:8px}.EtEeYG_more:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_hiddenConversationList{max-height:min(320px,48vh);display:grid;overflow:auto}.EtEeYG_hiddenConversationRow{border-bottom:1px solid var(--dsw-alias-border-l1);grid-template-columns:32px minmax(0,1fr) auto;align-items:center;gap:9px;min-height:50px;padding:6px 2px;display:grid}.EtEeYG_hiddenConversationRow:last-child{border-bottom:0}.EtEeYG_hiddenConversationRow .EtEeYG_avatar{width:30px;height:30px}.EtEeYG_hiddenConversationRow>span:nth-child(2){min-width:0;display:grid}.EtEeYG_hiddenConversationRow strong,.EtEeYG_hiddenConversationRow small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_hiddenConversationRow strong{font-size:12px;line-height:18px}.EtEeYG_hiddenConversationRow small{color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:15px}.EtEeYG_hiddenConversationRow>button{border:1px solid var(--dsw-alias-border-l2);min-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;background:0 0;border-radius:7px;padding:0 9px;font-size:11px}.EtEeYG_hiddenConversationRow>button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_hiddenConversationRow>button:disabled{cursor:default;opacity:.55}.EtEeYG_conversationPreferenceError{color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:17px}.EtEeYG_thread{flex-direction:column;min-width:0;min-height:0;display:flex;position:relative}.EtEeYG_threadHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:8px;height:56px;padding:0 14px;display:flex}.EtEeYG_threadTitle{flex-direction:column;flex:1;min-width:0;display:flex}.EtEeYG_threadTitle strong,.EtEeYG_threadTitle small{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_threadHeader small{color:var(--dsw-alias-label-tertiary)}.EtEeYG_threadAction{width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:8px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_threadAction:hover,.EtEeYG_threadAction[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupAccessNotice{border-bottom:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);flex:none;grid-template-columns:20px minmax(0,1fr) auto;align-items:start;gap:8px 10px;padding:11px 14px;display:grid}.EtEeYG_groupAccessNotice[data-status=blocked],.EtEeYG_groupAccessNotice[data-status=not-member]{background:var(--dsw-alias-interactive-bg-hover-danger)}.EtEeYG_groupAccessNotice[data-compact]{grid-template-columns:20px minmax(0,1fr);padding:12px 16px}.EtEeYG_groupAccessIcon{min-height:20px;color:var(--dsw-alias-label-secondary);place-items:center;display:grid}.EtEeYG_groupAccessNotice[data-status=loading] .EtEeYG_groupAccessIcon svg,.EtEeYG_groupAccessNotice[data-status=recovering] .EtEeYG_groupAccessIcon svg{animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_groupAccessCopy{gap:2px;min-width:0;display:grid}.EtEeYG_groupAccessCopy strong{font-size:12px;line-height:18px}.EtEeYG_groupAccessCopy small{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;font-size:11px;line-height:17px}.EtEeYG_groupAccessActions{flex-wrap:wrap;justify-content:flex-end;gap:6px;display:flex}.EtEeYG_groupAccessNotice[data-compact] .EtEeYG_groupAccessActions{grid-column:2;justify-content:flex-start}.EtEeYG_groupAccessActions button{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);min-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;border-radius:7px;justify-content:center;align-items:center;gap:5px;padding:0 8px;font-size:11px;line-height:16px;display:flex}.EtEeYG_groupAccessActions button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_groupAccessActions button:disabled{cursor:default;opacity:.55}.EtEeYG_groupDetails{z-index:4;border-left:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:min(360px,100%);min-width:0;box-shadow:var(--dsw-shadow-lv2);flex-direction:column;display:flex;position:absolute;top:56px;bottom:0;right:0;overflow:hidden}.EtEeYG_groupDetailsHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:12px;min-height:54px;padding:0 12px 0 16px;display:flex}.EtEeYG_groupDetailsHeader>div{flex-direction:column;flex:1;min-width:0;display:flex}.EtEeYG_groupDetailsHeader strong{font-size:14px;line-height:21px}.EtEeYG_groupDetailsHeader small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:15px;overflow:hidden}.EtEeYG_groupDetailsHeader button,.EtEeYG_groupMemberHeading button,.EtEeYG_groupMemberRemove{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_groupDetailsHeader button:hover,.EtEeYG_groupMemberHeading button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_groupDetailsLoading{color:var(--dsw-alias-label-tertiary);margin:auto;font-size:12px}.EtEeYG_groupSummary{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;gap:5px;padding:16px;display:grid}.EtEeYG_groupSummary>strong{font-size:15px;line-height:22px}.EtEeYG_groupSummary>code{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;overflow:hidden}.EtEeYG_groupSummary>p{color:var(--dsw-alias-label-secondary);margin:3px 0 0;font-size:12px;line-height:18px}.EtEeYG_groupSummary dl{grid-template-columns:1fr 1fr;gap:8px;margin:8px 0 0;display:grid}.EtEeYG_groupSummary dl>div{gap:1px;display:grid}.EtEeYG_groupSummary dt{color:var(--dsw-alias-label-tertiary);font-size:10px}.EtEeYG_groupSummary dd{color:var(--dsw-alias-label-primary);margin:0;font-size:12px}.EtEeYG_groupInvite{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;gap:5px;padding:12px 16px;display:grid}.EtEeYG_groupInvite label{color:var(--dsw-alias-label-secondary);font-size:11px}.EtEeYG_groupInvite>div{grid-template-columns:minmax(0,1fr) 32px;gap:6px;display:grid}.EtEeYG_groupInvite input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:0;height:32px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:7px;padding:0 9px;font-size:12px}.EtEeYG_groupInvite button{background:var(--dsw-alias-button-primary-fill);width:32px;height:32px;color:var(--dsw-alias-label-primary-inverted);cursor:pointer;border:0;border-radius:7px;place-items:center;padding:0;display:grid}.EtEeYG_groupInvite button:disabled{cursor:default;opacity:.7}.EtEeYG_groupInvite button[data-busy] svg{animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_groupInviteStatus{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-tertiary);margin:0;font-size:10px;line-height:16px}.EtEeYG_groupInviteStatus[data-state=success]{color:var(--dsw-alias-state-success-primary)}.EtEeYG_groupInviteStatus[data-state=error]{color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupMemberSection{flex-direction:column;flex:1;min-height:0;display:flex}.EtEeYG_groupMemberHeading{flex:none;justify-content:space-between;align-items:center;min-height:40px;padding:0 12px 0 16px;display:flex}.EtEeYG_groupMemberHeading strong{font-size:12px;line-height:18px}.EtEeYG_groupMemberHeading button[data-busy] svg{animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_groupMemberRefreshStatus{overflow-wrap:anywhere;min-height:22px;color:var(--dsw-alias-label-tertiary);flex:none;margin:0;padding:2px 16px 4px;font-size:10px;line-height:16px}.EtEeYG_groupMemberRefreshStatus[data-state=success]{color:var(--dsw-alias-state-success-primary)}.EtEeYG_groupMemberRefreshStatus[data-state=error]{color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupMemberList{min-height:0;padding:0 8px;overflow:auto}.EtEeYG_groupMemberRow{border-bottom:1px solid var(--dsw-alias-border-l1);grid-template-columns:30px minmax(0,1fr) auto 28px;align-items:center;gap:8px;min-height:48px;padding:4px 6px;display:grid}.EtEeYG_groupMemberAvatar{background:var(--dsw-alias-interactive-bg-active);width:30px;height:30px;color:var(--dsw-alias-brand-primary);border-radius:50%;place-items:center;font-size:11px;display:grid}.EtEeYG_groupMemberIdentity{flex-direction:column;min-width:0;display:flex}.EtEeYG_groupMemberIdentity strong{text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:5px;font-size:12px;line-height:18px;display:flex;overflow:hidden}.EtEeYG_groupMemberIdentity strong small{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-brand-primary);border-radius:4px;padding:0 4px;font-size:9px}.EtEeYG_groupMemberIdentity>small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:15px;overflow:hidden}.EtEeYG_groupMemberRole{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:10px}.EtEeYG_groupMemberRemove:hover{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.EtEeYG_groupDetailsFooter{border-top:1px solid var(--dsw-alias-border-l1);flex:none;justify-content:space-between;align-items:center;gap:8px;min-height:46px;padding:0 16px;display:flex}.EtEeYG_groupDetailsFooter small{color:var(--dsw-alias-label-tertiary);font-size:10px}.EtEeYG_dangerText{color:var(--dsw-alias-state-error-primary);cursor:pointer;font:inherit;background:0 0;border:0;padding:0;font-size:12px}.EtEeYG_dangerText:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.EtEeYG_groupDetailsError{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);flex:none;padding:8px 12px;font-size:11px;line-height:17px}.EtEeYG_summaryTrigger{min-height:30px;color:var(--dsw-alias-brand-primary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:8px;flex:none;align-items:center;gap:5px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.EtEeYG_summaryTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryTrigger:disabled{cursor:default;opacity:.7}.EtEeYG_summaryTrigger[aria-expanded=true]>svg:last-child{transform:rotate(180deg)}.EtEeYG_summaryTrigger>svg:first-child{flex:none}.EtEeYG_summaryPanel{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-height:0;max-height:min(220px,33%);color:var(--dsw-alias-label-primary);border-radius:10px;flex:0 33%;margin:8px 10px 0;overflow:hidden}.EtEeYG_summaryPanel[data-collapsed]{flex-basis:auto;max-height:42px}.EtEeYG_summaryHeader{border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:9px;min-height:38px;padding:0 8px 0 12px;display:flex}.EtEeYG_summaryHeader>span{color:var(--dsw-alias-brand-primary);align-items:center;gap:6px;display:flex}.EtEeYG_summaryHeader>span strong{color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}.EtEeYG_summaryHeader>small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:11px;line-height:16px;overflow:hidden}.EtEeYG_summaryHeader>button{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:7px;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_summaryHeader>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryCollapsed{width:100%;min-height:40px;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:8px;padding:0 10px 0 12px;display:grid}.EtEeYG_summaryCollapsed:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryCollapsed>span{color:var(--dsw-alias-brand-primary);align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}.EtEeYG_summaryCollapsed>small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_summaryCollapsed>em{color:var(--dsw-alias-state-warn-label);white-space:nowrap;font-size:11px;font-style:normal}.EtEeYG_summaryLoading{min-height:88px;color:var(--dsw-alias-brand-primary);justify-content:center;align-items:center;gap:10px;padding:16px;display:flex}.EtEeYG_summaryLoading>svg,.EtEeYG_summaryTrigger:disabled>svg:first-child{animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_summaryLoading>span{flex-direction:column;gap:2px;display:flex}.EtEeYG_summaryLoading strong{color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}.EtEeYG_summaryLoading small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.EtEeYG_summaryError{min-height:58px;color:var(--dsw-alias-state-error-primary);justify-content:space-between;align-items:center;gap:12px;padding:12px;font-size:12px;line-height:18px;display:flex}.EtEeYG_summaryError>span{overflow-wrap:anywhere;min-width:0}.EtEeYG_summaryError button,.EtEeYG_summaryStale button{border:1px solid var(--dsw-alias-border-l2);min-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;background:0 0;border-radius:7px;flex:none;align-items:center;gap:5px;padding:0 8px;font-size:11px;display:flex}.EtEeYG_summaryError button:hover,.EtEeYG_summaryStale button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryStale{background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-state-warn-label);justify-content:space-between;align-items:center;gap:10px;padding:6px 10px;font-size:11px;line-height:16px;display:flex}.EtEeYG_summaryBody{gap:10px;max-height:118px;padding:10px 12px;display:grid;overflow:auto}.EtEeYG_summarySection h4{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;margin:0 0 4px;font-size:12px;line-height:18px;display:flex}.EtEeYG_summarySection h4>svg{color:var(--dsw-alias-label-secondary);flex:none}.EtEeYG_summarySection ul{color:var(--dsw-alias-label-secondary);gap:2px;margin:0;padding-left:18px;font-size:11px;line-height:17px;display:grid}.EtEeYG_summarySection li{overflow-wrap:anywhere;padding-left:1px}.EtEeYG_summarySection p{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:17px}.EtEeYG_summarySection b{color:var(--dsw-alias-label-primary);font-weight:500}.EtEeYG_summaryActions{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:auto 1fr auto auto;align-items:center;gap:4px;min-height:34px;padding:0 8px;display:grid}.EtEeYG_summaryActions button{min-height:26px;color:var(--dsw-alias-brand-primary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:6px;align-items:center;gap:5px;padding:0 6px;font-size:11px;line-height:16px;display:flex}.EtEeYG_summaryActions button:hover{background:var(--dsw-alias-interactive-bg-hover)}.EtEeYG_summaryPrivacy{border-top:1px solid var(--dsw-alias-border-l1);min-height:28px;color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;padding:0 10px;font-size:10px;line-height:15px;display:flex}.EtEeYG_summaryPrivacy svg{flex:none}.EtEeYG_summaryCopyError{color:var(--dsw-alias-state-error-primary);padding:4px 10px;font-size:10px;line-height:15px}@keyframes EtEeYG_summary-spin{to{transform:rotate(360deg)}}.EtEeYG_back{display:none}.EtEeYG_historyShell{flex:1;min-height:0;position:relative}.EtEeYG_history{box-sizing:border-box;flex-direction:column;gap:12px;height:100%;min-height:0;padding:16px;display:flex;overflow:auto}.EtEeYG_historyLoading{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;margin:auto;font-size:12px;line-height:18px;display:flex}.EtEeYG_historyLoading>svg{color:var(--dsw-alias-brand-primary);animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_latestMessages{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-floating-fill);min-width:30px;min-height:30px;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv2);cursor:pointer;font:inherit;border-radius:16px;justify-content:center;align-items:center;gap:5px;padding:0 9px;font-size:11px;line-height:16px;display:flex;position:absolute;bottom:12px;left:50%;transform:translate(-50%)}.EtEeYG_latestMessages:hover{background:var(--dsw-alias-button-floating-hover)}.EtEeYG_message{align-self:flex-start;max-width:min(78%,420px)}.EtEeYG_message[data-outgoing]{align-self:flex-end}.EtEeYG_messageMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;gap:10px;margin-bottom:3px;font-size:11px;line-height:16px;display:flex}.EtEeYG_message p,.EtEeYG_attachment{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;border-radius:12px;margin:0;padding:9px 11px;line-height:20px}.EtEeYG_message[data-outgoing] p,.EtEeYG_message[data-outgoing] .EtEeYG_attachment{background:var(--dsw-alias-interactive-bg-active)}.EtEeYG_mention{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-brand-primary);border-radius:3px;padding:0 2px;font-weight:600}.EtEeYG_pendingMessage{grid-template-columns:auto minmax(0,1fr);align-self:flex-end;align-items:end;gap:7px;max-width:min(78%,420px);display:grid}.EtEeYG_pendingMessageSpinner{color:var(--dsw-alias-label-tertiary);margin-bottom:12px;animation:1s linear infinite EtEeYG_summary-spin}.EtEeYG_pendingMessageContent{opacity:.82;min-width:0}.EtEeYG_pendingMessageContent>p,.EtEeYG_pendingAttachment{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;border-radius:12px;margin:0;padding:9px 11px;line-height:20px}.EtEeYG_pendingAttachment{align-items:center;gap:9px;display:flex}.EtEeYG_pendingAttachment>svg{color:var(--dsw-alias-label-secondary);flex:none}.EtEeYG_pendingAttachment span{flex-direction:column;min-width:0;display:flex}.EtEeYG_pendingAttachment strong{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_pendingAttachment small{color:var(--dsw-alias-label-tertiary)}.EtEeYG_pendingMessageContent>.EtEeYG_pendingCaption{color:var(--dsw-alias-label-secondary);background:0 0;border:0;margin-top:4px;padding:4px 8px;font-size:12px}.EtEeYG_attachment{cursor:pointer;font:inherit;text-align:left;align-items:center;gap:12px;display:flex}.EtEeYG_attachment span{flex-direction:column;min-width:0;display:flex}.EtEeYG_attachment strong{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_attachment small{color:var(--dsw-alias-label-tertiary)}.EtEeYG_attachment:disabled{cursor:default}.EtEeYG_imageAttachment{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:280px;max-width:100%;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;text-align:left;border-radius:12px;margin:0;padding:0;display:block;overflow:hidden}.EtEeYG_imageAttachment img{background:var(--dsw-alias-bg-layer-1);object-fit:contain;width:100%;max-height:280px;display:block}.EtEeYG_imageAttachment span{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:0 10px;padding:7px 9px;display:grid}.EtEeYG_imageAttachment strong{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.EtEeYG_imageAttachment small{color:var(--dsw-alias-label-tertiary);grid-column:1}.EtEeYG_imageAttachment svg{grid-area:1/2/span 2}.EtEeYG_message .EtEeYG_caption{color:var(--dsw-alias-label-secondary);background:0 0;margin-top:4px;padding:4px 8px;font-size:12px}.EtEeYG_inlineError{color:var(--dsw-alias-state-error-primary);margin-top:4px;display:block}.EtEeYG_empty{color:var(--dsw-alias-label-tertiary);text-align:center;margin:auto;padding:20px}.EtEeYG_composer{border-top:1px solid var(--dsw-alias-border-l1);flex:none;gap:8px;padding:10px 14px 14px;display:grid}.EtEeYG_filePicker{border:1px solid var(--dsw-alias-border-l2);width:32px;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:50%;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_filePicker:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.EtEeYG_filePicker:disabled{opacity:.45;cursor:default}.EtEeYG_fileInput{display:none}.EtEeYG_composeInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:10px;gap:6px;min-width:0;padding:9px 10px 8px;display:grid;position:relative}.EtEeYG_mentionCandidates{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);max-height:180px;box-shadow:var(--dsw-shadow-lv2);border-radius:8px;padding:5px;position:absolute;bottom:calc(100% + 7px);left:0;right:0;overflow:auto}.EtEeYG_mentionCandidates button{width:100%;min-height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;grid-template-rows:auto auto;grid-template-columns:28px minmax(0,1fr);align-items:center;column-gap:8px;padding:4px 7px;display:grid}.EtEeYG_mentionCandidates button:hover,.EtEeYG_mentionCandidates button[aria-selected=true]{background:var(--dsw-alias-interactive-bg-active)}.EtEeYG_mentionCandidates button>span{background:var(--dsw-alias-bg-layer-3);width:28px;height:28px;color:var(--dsw-alias-brand-primary);border-radius:50%;grid-row:1/span 2;place-items:center;font-size:10px;display:grid}.EtEeYG_mentionCandidates strong,.EtEeYG_mentionCandidates small{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.EtEeYG_mentionCandidates strong{align-self:end;font-size:12px;line-height:16px}.EtEeYG_mentionCandidates small{color:var(--dsw-alias-label-tertiary);align-self:start;font-size:10px;line-height:14px}.EtEeYG_composeInput:focus-within{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.EtEeYG_composeInput textarea{resize:none;background:0 0;border:0;border-radius:0;outline:0;min-width:0;min-height:42px;padding:0}.EtEeYG_composeInput textarea:focus-visible{outline:0}.EtEeYG_composeActions{justify-content:space-between;align-items:center;min-height:32px;display:flex}.EtEeYG_filePreview{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;align-items:center;gap:8px;width:min(240px,100% - 8px);min-height:36px;padding:5px 28px 5px 8px;display:flex;position:relative}.EtEeYG_filePreview[data-image]{width:72px;height:72px;min-height:0;padding:0}.EtEeYG_filePreview img{object-fit:cover;border-radius:9px;width:72px;height:72px;display:block}.EtEeYG_filePreviewIcon{color:var(--dsw-alias-label-secondary);flex:none;place-items:center;display:grid}.EtEeYG_filePreviewName{min-width:0;color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.EtEeYG_removeFile{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-floating-fill);width:22px;height:22px;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv1);cursor:pointer;border-radius:50%;place-items:center;padding:0;display:grid;position:absolute;top:-7px;right:-7px}.EtEeYG_removeFile:hover{background:var(--dsw-alias-button-floating-hover)}.EtEeYG_send{background:var(--dsw-alias-button-primary-fill);width:32px;height:32px;color:var(--dsw-alias-label-primary-inverted);cursor:pointer;border:0;border-radius:50%;flex:none;place-items:center;padding:0;display:grid}.EtEeYG_send:disabled{opacity:.45;cursor:default}.EtEeYG_error{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;flex:none;padding:8px 14px;font-size:12px;line-height:18px}.EtEeYG_pending{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-inverted);box-shadow:var(--dsw-shadow-lv2);border-radius:9px;padding:7px 10px;font-size:12px;line-height:18px;position:absolute;bottom:14px;right:14px}@media (width<=620px){.EtEeYG_trigger span{display:none}.EtEeYG_trigger{justify-content:center;width:36px;padding:0}.EtEeYG_drawer{width:calc(100vw - 56px);min-width:0}.EtEeYG_chat{grid-template-columns:1fr}.EtEeYG_thread{display:none}.EtEeYG_thread[data-visible]{display:flex}.EtEeYG_roster[data-hidden]{display:none}.EtEeYG_back{display:grid}.EtEeYG_summaryPanel{max-height:min(190px,33%);margin-left:8px;margin-right:8px}.EtEeYG_summaryTrigger>span{display:none}.EtEeYG_summaryTrigger{justify-content:center;width:30px;padding:0}.EtEeYG_summaryTrigger>svg:last-child{display:none}}@media (height<=420px){.EtEeYG_drawer{border-radius:10px}.EtEeYG_drawerHeader{height:44px;padding:0 8px 0 12px}.EtEeYG_drawerHeader h2{font-size:14px;line-height:20px}.EtEeYG_drawerHeader button,.EtEeYG_back{width:28px;height:28px}.EtEeYG_centerState,.EtEeYG_threadEmpty{justify-content:flex-start;gap:8px;min-height:0;padding:12px;overflow:auto}.EtEeYG_registrationIcon{width:32px;height:32px}.EtEeYG_composeBackdrop{place-items:start center;padding:8px;inset:44px 0 0}.EtEeYG_composeCard{border-radius:10px;gap:8px;padding:12px}.EtEeYG_recoveryForm{gap:8px}.EtEeYG_identityCard{border-radius:8px;margin:6px 8px;padding:7px 9px}.EtEeYG_profileBio,.EtEeYG_profileTags,.EtEeYG_identityStatus{display:none}.EtEeYG_modeTabs{margin:0 8px 4px}.EtEeYG_modeTabs button{min-height:26px}.EtEeYG_rosterHeader{min-height:28px;padding:0 4px 2px 12px}.EtEeYG_conversationSelect{gap:7px;padding:5px 7px}.EtEeYG_avatar{width:28px;height:28px}.EtEeYG_threadHeader{gap:5px;height:44px;padding:0 8px}.EtEeYG_groupAccessNotice{grid-template-columns:18px minmax(0,1fr);gap:6px 8px;padding:8px}.EtEeYG_groupAccessActions{grid-column:2;justify-content:flex-start}.EtEeYG_groupDetails{top:44px;overflow-y:auto}.EtEeYG_groupDetailsHeader{z-index:2;background:var(--dsw-alias-bg-layer-1);min-height:44px;padding-left:12px;position:sticky;top:0}.EtEeYG_groupSummary{gap:2px;padding:8px 12px}.EtEeYG_groupSummary dl{gap:6px;margin-top:3px}.EtEeYG_groupInvite{gap:3px;padding:7px 12px}.EtEeYG_groupMemberSection{flex:none}.EtEeYG_groupMemberHeading{min-height:32px;padding-left:12px}.EtEeYG_groupMemberList{overflow:visible}.EtEeYG_groupMemberRow{min-height:40px}.EtEeYG_groupDetailsFooter{background:var(--dsw-alias-bg-layer-1);min-height:40px;padding:0 12px;position:sticky;bottom:0}.EtEeYG_history{gap:6px;padding:8px}.EtEeYG_composer{gap:4px;padding:5px 8px 7px}.EtEeYG_composeInput{gap:3px;padding:5px 7px 4px}.EtEeYG_composeInput textarea{height:28px;min-height:28px}.EtEeYG_composeActions{min-height:28px}.EtEeYG_filePicker,.EtEeYG_send{width:28px;height:28px}.EtEeYG_mentionCandidates{max-height:72px}.EtEeYG_compactModal.EtEeYG_compactModal{border-radius:12px;gap:10px;max-height:calc(100vh - 48px);padding-bottom:12px}}@media (hover:none){.EtEeYG_conversationMenu{opacity:1}}@media (prefers-reduced-motion:reduce){.EtEeYG_drawer{scroll-behavior:auto;transition:none}.EtEeYG_summaryLoading>svg,.EtEeYG_summaryTrigger:disabled>svg:first-child,.EtEeYG_historyLoading>svg,.EtEeYG_recoveryProgressPanel>svg,.EtEeYG_groupMemberHeading button[data-busy] svg,.EtEeYG_pendingMessageSpinner{animation:none}}";
8985
9655
  const tagId$5 = "@awiki/dsh-plugin/AwikiOverlay.module.css";
8986
9656
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
8987
9657
  const tag = document.createElement("style");
@@ -9007,7 +9677,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9007
9677
  "composeRow": "EtEeYG_composeRow",
9008
9678
  "conversationHeader": "EtEeYG_conversationHeader",
9009
9679
  "conversationList": "EtEeYG_conversationList",
9680
+ "conversationMenu": "EtEeYG_conversationMenu",
9681
+ "conversationPreferenceError": "EtEeYG_conversationPreferenceError",
9010
9682
  "conversationRow": "EtEeYG_conversationRow",
9683
+ "conversationSelect": "EtEeYG_conversationSelect",
9011
9684
  "conversationText": "EtEeYG_conversationText",
9012
9685
  "conversationTime": "EtEeYG_conversationTime",
9013
9686
  "conversationUnreadBadge": "EtEeYG_conversationUnreadBadge",
@@ -9022,6 +9695,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9022
9695
  "filePreview": "EtEeYG_filePreview",
9023
9696
  "filePreviewIcon": "EtEeYG_filePreviewIcon",
9024
9697
  "filePreviewName": "EtEeYG_filePreviewName",
9698
+ "groupAccessActions": "EtEeYG_groupAccessActions",
9699
+ "groupAccessCopy": "EtEeYG_groupAccessCopy",
9700
+ "groupAccessIcon": "EtEeYG_groupAccessIcon",
9701
+ "groupAccessNotice": "EtEeYG_groupAccessNotice",
9025
9702
  "groupDetails": "EtEeYG_groupDetails",
9026
9703
  "groupDetailsError": "EtEeYG_groupDetailsError",
9027
9704
  "groupDetailsFooter": "EtEeYG_groupDetailsFooter",
@@ -9033,12 +9710,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9033
9710
  "groupMemberHeading": "EtEeYG_groupMemberHeading",
9034
9711
  "groupMemberIdentity": "EtEeYG_groupMemberIdentity",
9035
9712
  "groupMemberList": "EtEeYG_groupMemberList",
9713
+ "groupMemberRefreshStatus": "EtEeYG_groupMemberRefreshStatus",
9036
9714
  "groupMemberRemove": "EtEeYG_groupMemberRemove",
9037
9715
  "groupMemberRole": "EtEeYG_groupMemberRole",
9038
9716
  "groupMemberRow": "EtEeYG_groupMemberRow",
9039
9717
  "groupMemberSection": "EtEeYG_groupMemberSection",
9040
9718
  "groupRecoveryNotice": "EtEeYG_groupRecoveryNotice",
9041
9719
  "groupSummary": "EtEeYG_groupSummary",
9720
+ "hiddenConversationList": "EtEeYG_hiddenConversationList",
9721
+ "hiddenConversationRow": "EtEeYG_hiddenConversationRow",
9042
9722
  "history": "EtEeYG_history",
9043
9723
  "historyLoading": "EtEeYG_historyLoading",
9044
9724
  "historyShell": "EtEeYG_historyShell",
@@ -9094,6 +9774,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9094
9774
  "resizeHandle": "EtEeYG_resizeHandle",
9095
9775
  "roster": "EtEeYG_roster",
9096
9776
  "rosterAction": "EtEeYG_rosterAction",
9777
+ "rosterActions": "EtEeYG_rosterActions",
9097
9778
  "rosterHeader": "EtEeYG_rosterHeader",
9098
9779
  "rosterTitle": "EtEeYG_rosterTitle",
9099
9780
  "secondary": "EtEeYG_secondary",
@@ -9147,8 +9828,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9147
9828
  function progressMessage(progress) {
9148
9829
  switch (progress.phase) {
9149
9830
  case "remote_outcome_unknown": return "恢复请求已经提交,正在确认服务端结果。请不要重新发起恢复。";
9150
- case "remote_committed": return "服务端已经恢复身份,正在为当前设备更新凭证。";
9151
- case "identity_transition_pending": return "身份已经恢复,正在完成当前设备的数据切换。";
9831
+ case "remote_committed": return "身份已在服务端恢复,正在为当前设备更新本机凭证。";
9832
+ case "identity_transition_pending": return "身份已在服务端恢复,本机切换尚未完成。请继续完成本机切换。";
9152
9833
  case "quarantined_key_unavailable": return "新的本机凭证暂时不可用,请稍后重新检查恢复结果。";
9153
9834
  case "applied": return "身份已经恢复完成。";
9154
9835
  default: return "正在处理身份恢复,请保持窗口打开。";
@@ -9192,7 +9873,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9192
9873
  ]);
9193
9874
  const requestOtp = async () => {
9194
9875
  setError(null);
9195
- const fullHandle = handle.current?.value.trim() ?? "";
9876
+ const fullHandle = props.fixedHandle?.trim() ?? handle.current?.value.trim() ?? "";
9196
9877
  const phone = requestPhone.current?.value.trim() ?? "";
9197
9878
  const result = await props.sendRecoveryOtp({
9198
9879
  fullHandle,
@@ -9226,7 +9907,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9226
9907
  setCommitAttempted(true);
9227
9908
  setError(null);
9228
9909
  const result = await props.activateRecovery();
9229
- if (!result.ok) setError(`${result.error} 请先刷新状态,不要重复提交恢复请求。`);
9910
+ if (!result.ok) setError(result.error);
9230
9911
  };
9231
9912
  const refresh = async () => {
9232
9913
  setError(null);
@@ -9270,18 +9951,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9270
9951
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.registrationIcon,
9271
9952
  children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: 24 })
9272
9953
  }),
9273
- (0, react_jsx_runtime.jsx)("h3", { children: "恢复已有身份" }),
9274
- (0, react_jsx_runtime.jsx)("p", { children: "输入原来的完整 Handle 和绑定手机号,我们会发送验证码来确认身份归属。" }),
9275
- (0, react_jsx_runtime.jsxs)("label", { children: ["完整 Handle", (0, react_jsx_runtime.jsx)("input", {
9954
+ (0, react_jsx_runtime.jsx)("h3", { children: props.requestTitle ?? "恢复已有身份" }),
9955
+ (0, react_jsx_runtime.jsx)("p", { children: props.requestDescription ?? "输入原来的完整 Handle 和绑定手机号,我们会发送验证码来确认身份归属。" }),
9956
+ props.fixedHandle === void 0 ? (0, react_jsx_runtime.jsxs)("label", { children: ["完整 Handle", (0, react_jsx_runtime.jsx)("input", {
9276
9957
  ref: handle,
9277
9958
  autoComplete: "username",
9278
9959
  placeholder: "例如 alice.awiki.info",
9279
9960
  autoFocus: true
9280
- })] }),
9961
+ })] }) : (0, react_jsx_runtime.jsxs)("div", {
9962
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.recoveryIdentitySummary,
9963
+ children: [(0, react_jsx_runtime.jsx)("span", { children: "当前身份" }), (0, react_jsx_runtime.jsx)("strong", { children: props.fixedHandle })]
9964
+ }),
9281
9965
  (0, react_jsx_runtime.jsxs)("label", { children: ["绑定手机号", (0, react_jsx_runtime.jsx)("input", {
9282
9966
  ref: requestPhone,
9283
9967
  type: "tel",
9284
- autoComplete: "tel"
9968
+ autoComplete: "tel",
9969
+ autoFocus: props.fixedHandle !== void 0
9285
9970
  })] }),
9286
9971
  (0, react_jsx_runtime.jsx)("button", {
9287
9972
  type: "submit",
@@ -9434,7 +10119,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9434
10119
  onClick: () => {
9435
10120
  canResume(progress) ? resume() : refresh();
9436
10121
  },
9437
- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, { size: 14 }), "重新检查恢复结果"]
10122
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, { size: 14 }), progress.phase === "identity_transition_pending" || progress.phase === "remote_committed" ? "继续完成本机切换" : "重新检查恢复结果"]
9438
10123
  })
9439
10124
  ]
9440
10125
  }),
@@ -9499,7 +10184,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9499
10184
  discardRecovery: props.discardRecovery,
9500
10185
  ...props.onExit === void 0 ? {} : { onExit: props.onExit },
9501
10186
  ...props.onExitLabel === void 0 ? {} : { onExitLabel: props.onExitLabel },
9502
- ...props.initialFactorContext === void 0 ? {} : { initialFactorContext: props.initialFactorContext }
10187
+ ...props.initialFactorContext === void 0 ? {} : { initialFactorContext: props.initialFactorContext },
10188
+ ...props.fixedHandle === void 0 ? {} : { fixedHandle: props.fixedHandle },
10189
+ ...props.requestTitle === void 0 ? {} : { requestTitle: props.requestTitle },
10190
+ ...props.requestDescription === void 0 ? {} : { requestDescription: props.requestDescription }
9503
10191
  });
9504
10192
  }
9505
10193
  /** Keep phone and OTP values mounted only for the duration of this explicit user flow. */
@@ -9630,15 +10318,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9630
10318
  setSignedOutAlternative("none");
9631
10319
  };
9632
10320
  const signedOutRecoveryOpen = props.sessionStatus === "signed-out" && signedOutAlternative === "recover";
10321
+ const revokedHandle = props.sessionStatus === "recovery-required" ? props.identity?.handle : void 0;
9633
10322
  if (props.recoveryOperationId !== null && !signedOutRecoveryOpen) {
9634
10323
  const onExit = props.sessionStatus === "signed-out" ? returnToSignedOutHome : resetIdentityEntry;
9635
10324
  return (0, react_jsx_runtime.jsx)(Recovery, {
9636
10325
  ...props,
9637
10326
  onExit,
9638
10327
  onExitLabel: props.sessionStatus === "signed-out" ? "返回本机身份" : "返回身份入口",
9639
- ...recoveryFactorContext === null ? {} : { initialFactorContext: recoveryFactorContext }
10328
+ ...recoveryFactorContext === null ? {} : { initialFactorContext: recoveryFactorContext },
10329
+ ...revokedHandle === void 0 ? {} : {
10330
+ fixedHandle: revokedHandle,
10331
+ requestTitle: "需要重新恢复身份",
10332
+ requestDescription: "这个 Handle 已在另一台设备完成了更新恢复,当前设备的旧凭证因此失效。验证绑定手机号后即可继续使用本机数据。"
10333
+ }
9640
10334
  });
9641
10335
  }
10336
+ if (props.sessionStatus === "recovery-required") return (0, react_jsx_runtime.jsx)(Recovery, {
10337
+ ...props,
10338
+ ...revokedHandle === void 0 ? {} : { fixedHandle: revokedHandle },
10339
+ requestTitle: "需要重新恢复身份",
10340
+ requestDescription: "这个 Handle 已在另一台设备完成了更新恢复,当前设备的旧凭证因此失效。验证绑定手机号后即可继续使用本机数据。"
10341
+ });
9642
10342
  if (props.sessionStatus === "signed-out") {
9643
10343
  if (signedOutAlternative === "recover") return (0, react_jsx_runtime.jsx)(Recovery, {
9644
10344
  ...props,
@@ -9919,6 +10619,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9919
10619
  };
9920
10620
  const identityAccess = (sessionStatus) => (0, react_jsx_runtime.jsx)(AwikiIdentityAccess, {
9921
10621
  sessionStatus,
10622
+ identity: identity.identity,
9922
10623
  recoveryOperationId: identity.recoveryOperationId ?? null,
9923
10624
  recoveryProgress: identity.recoveryProgress ?? null,
9924
10625
  pending: identity.pending !== null,
@@ -10038,6 +10739,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10038
10739
  })
10039
10740
  ]
10040
10741
  });
10742
+ if (identity.sessionStatus === "recovery-required") return (0, react_jsx_runtime.jsxs)(OnboardingModal, {
10743
+ title: t("onboardingRecoveryRequiredTitle"),
10744
+ closeLabel: t("onboardingClose"),
10745
+ onClose: dismiss,
10746
+ children: [
10747
+ (0, react_jsx_runtime.jsx)("p", {
10748
+ className: _dsh_awiki_css_AwikiOnboarding_module_css_default.description,
10749
+ children: t("onboardingRecoveryRequiredDescription")
10750
+ }),
10751
+ identityAccess("recovery-required"),
10752
+ (0, react_jsx_runtime.jsx)("div", {
10753
+ className: _dsh_awiki_css_AwikiOnboarding_module_css_default.actions,
10754
+ children: alternatives
10755
+ })
10756
+ ]
10757
+ });
10041
10758
  if ((models.status === "idle" || models.status === "loading") && models.account === null) return null;
10042
10759
  const account = models.account?.account;
10043
10760
  const pendingOrder = props.rechargeEnabled ? models.account?.pending_recharge_order ?? null : null;
@@ -10469,6 +11186,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10469
11186
  function participant(values, fallback) {
10470
11187
  return values.length === 0 ? fallback : values.join("、");
10471
11188
  }
11189
+ function recipient(summary, folder, account) {
11190
+ const fallback = folder === "inbox" ? account?.mailboxAddress ?? "未提供" : "未提供";
11191
+ return participant(summary.to, fallback);
11192
+ }
10472
11193
  function splitAddresses(raw) {
10473
11194
  return raw.split(/[\s,,;;]+/u).map((value) => value.trim()).filter((value) => value !== "");
10474
11195
  }
@@ -11139,7 +11860,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11139
11860
  (0, react_jsx_runtime.jsx)("time", { children: mailTime(folder === "inbox" ? message.summary.receivedAt ?? message.summary.sentAt : message.summary.sentAt ?? message.summary.receivedAt) }),
11140
11861
  (0, react_jsx_runtime.jsxs)("dl", { children: [
11141
11862
  (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "发件人" }), (0, react_jsx_runtime.jsx)("dd", { children: participant(message.summary.from, "未知发件人") })] }),
11142
- (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "收件人" }), (0, react_jsx_runtime.jsx)("dd", { children: participant(message.summary.to, "未提供") })] }),
11863
+ (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "收件人" }), (0, react_jsx_runtime.jsx)("dd", { children: recipient(message.summary, folder, account) })] }),
11143
11864
  message.summary.cc.length > 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "抄送" }), (0, react_jsx_runtime.jsx)("dd", { children: participant(message.summary.cc, "") })] })
11144
11865
  ] })
11145
11866
  ]
@@ -11251,6 +11972,89 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11251
11972
  });
11252
11973
  }
11253
11974
  //#endregion
11975
+ //#region lib/types/client/AwikiGroupAccessNotice.js
11976
+ function accessCopy(status) {
11977
+ switch (status) {
11978
+ case "loading": return {
11979
+ title: "正在确认群成员权限",
11980
+ detail: "本机已有消息会先保留显示。"
11981
+ };
11982
+ case "recovering": return {
11983
+ title: "正在恢复此群聊的身份关联",
11984
+ detail: "完成后即可继续同步和发送消息。"
11985
+ };
11986
+ case "blocked": return {
11987
+ title: "此群聊无法自动恢复",
11988
+ detail: "旧成员记录没有绑定 Handle。本机已有消息仍可查看,也可以尝试重新加入。"
11989
+ };
11990
+ case "not-member": return {
11991
+ title: "当前身份暂时无法访问此群聊",
11992
+ detail: "服务器尚未确认当前身份是群成员。本机已有消息仍可查看。"
11993
+ };
11994
+ case "network-error": return {
11995
+ title: "暂时无法确认群成员权限",
11996
+ detail: "请检查网络后重新确认。本机已有消息不受影响。"
11997
+ };
11998
+ case "available": return {
11999
+ title: "群聊可用",
12000
+ detail: ""
12001
+ };
12002
+ }
12003
+ }
12004
+ /** Group-scoped access state with bounded recovery and navigation actions. */
12005
+ function AwikiGroupAccessNotice(props) {
12006
+ if (props.access.status === "available") return null;
12007
+ const copy = accessCopy(props.access.status);
12008
+ const loading = props.access.status === "loading";
12009
+ const canRejoin = props.access.status === "blocked" || props.access.status === "not-member";
12010
+ return (0, react_jsx_runtime.jsxs)("section", {
12011
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupAccessNotice,
12012
+ "data-status": props.access.status,
12013
+ "data-compact": props.compact || void 0,
12014
+ role: loading || props.access.status === "recovering" ? "status" : "alert",
12015
+ "aria-live": "polite",
12016
+ children: [
12017
+ (0, react_jsx_runtime.jsx)("span", {
12018
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupAccessIcon,
12019
+ children: loading || props.access.status === "recovering" ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 16 }) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconWarningOutline16, { size: 16 })
12020
+ }),
12021
+ (0, react_jsx_runtime.jsxs)("span", {
12022
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupAccessCopy,
12023
+ children: [(0, react_jsx_runtime.jsx)("strong", { children: copy.title }), (0, react_jsx_runtime.jsx)("small", { children: copy.detail })]
12024
+ }),
12025
+ !loading && (0, react_jsx_runtime.jsxs)("span", {
12026
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupAccessActions,
12027
+ children: [
12028
+ (0, react_jsx_runtime.jsxs)("button", {
12029
+ type: "button",
12030
+ disabled: props.pending,
12031
+ onClick: props.onRetry,
12032
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, { size: 14 }), "重新检查"]
12033
+ }),
12034
+ canRejoin && (0, react_jsx_runtime.jsx)("button", {
12035
+ type: "button",
12036
+ disabled: props.pending,
12037
+ onClick: props.onRejoin,
12038
+ children: "尝试重新加入"
12039
+ }),
12040
+ props.onRemove !== void 0 && (0, react_jsx_runtime.jsx)("button", {
12041
+ type: "button",
12042
+ disabled: props.pending,
12043
+ onClick: props.onRemove,
12044
+ children: "从列表移除"
12045
+ }),
12046
+ props.onBack !== void 0 && (0, react_jsx_runtime.jsx)("button", {
12047
+ type: "button",
12048
+ disabled: props.pending,
12049
+ onClick: props.onBack,
12050
+ children: "返回会话列表"
12051
+ })
12052
+ ]
12053
+ })
12054
+ ]
12055
+ });
12056
+ }
12057
+ //#endregion
11254
12058
  //#region lib/types/client/mentions.js
11255
12059
  /** Browser-only AWiki mention editing helpers. All ranges use Unicode code points. */
11256
12060
  const HUMAN_SUBJECT_TYPES = /* @__PURE__ */ new Set([
@@ -11469,6 +12273,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11469
12273
  function AwikiGroupDetails(props) {
11470
12274
  const [invite, setInvite] = (0, react.useState)("");
11471
12275
  const [inviteStatus, setInviteStatus] = (0, react.useState)({ state: "idle" });
12276
+ const [memberRefreshStatus, setMemberRefreshStatus] = (0, react.useState)({ state: "idle" });
11472
12277
  const [error, setError] = (0, react.useState)(null);
11473
12278
  const [removeCandidate, setRemoveCandidate] = (0, react.useState)(null);
11474
12279
  const [leaveOpen, setLeaveOpen] = (0, react.useState)(false);
@@ -11481,14 +12286,38 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11481
12286
  window.clearTimeout(timer);
11482
12287
  };
11483
12288
  }, [inviteStatus]);
11484
- const refresh = async () => {
12289
+ (0, react.useEffect)(() => {
12290
+ if (memberRefreshStatus.state !== "success") return;
12291
+ const timer = window.setTimeout(() => {
12292
+ setMemberRefreshStatus({ state: "idle" });
12293
+ }, 3e3);
12294
+ return () => {
12295
+ window.clearTimeout(timer);
12296
+ };
12297
+ }, [memberRefreshStatus]);
12298
+ (0, react.useEffect)(() => {
12299
+ setMemberRefreshStatus({ state: "idle" });
12300
+ }, [props.fallback.groupDid]);
12301
+ const refreshAccess = async () => {
11485
12302
  setError(null);
12303
+ setMemberRefreshStatus({ state: "idle" });
11486
12304
  const result = await props.refreshSelectedGroup();
11487
12305
  if (!result.ok) setError(result.error);
11488
12306
  };
12307
+ const refreshMembers = async () => {
12308
+ if (memberRefreshStatus.state === "pending") return;
12309
+ setError(null);
12310
+ setMemberRefreshStatus({ state: "pending" });
12311
+ const result = await props.refreshSelectedGroup();
12312
+ setMemberRefreshStatus(result.ok ? { state: "success" } : {
12313
+ state: "error",
12314
+ message: result.error
12315
+ });
12316
+ };
11489
12317
  const add = async () => {
11490
12318
  const member = invite.trim();
11491
12319
  if (member === "" || inviteStatus.state === "pending") return;
12320
+ setMemberRefreshStatus({ state: "idle" });
11492
12321
  setInviteStatus({
11493
12322
  state: "pending",
11494
12323
  member
@@ -11509,6 +12338,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11509
12338
  };
11510
12339
  const remove = async () => {
11511
12340
  if (removeCandidate === null) return;
12341
+ setMemberRefreshStatus({ state: "idle" });
11512
12342
  setError(null);
11513
12343
  const result = await props.removeSelectedGroupMember(removeCandidate);
11514
12344
  if (!result.ok) {
@@ -11518,6 +12348,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11518
12348
  setRemoveCandidate(null);
11519
12349
  };
11520
12350
  const leave = async () => {
12351
+ setMemberRefreshStatus({ state: "idle" });
11521
12352
  setError(null);
11522
12353
  const result = await props.leaveSelectedGroup();
11523
12354
  if (!result.ok) {
@@ -11527,6 +12358,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11527
12358
  setLeaveOpen(false);
11528
12359
  props.onClose();
11529
12360
  };
12361
+ const rejoin = async () => {
12362
+ setMemberRefreshStatus({ state: "idle" });
12363
+ setError(null);
12364
+ const result = await props.joinGroup(props.fallback.groupDid);
12365
+ if (!result.ok) setError(result.error);
12366
+ };
12367
+ const group = props.group?.groupDid === props.fallback.groupDid ? props.group : null;
12368
+ const available = props.access.status === "available" && group !== null;
11530
12369
  return (0, react_jsx_runtime.jsxs)("aside", {
11531
12370
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupDetails,
11532
12371
  "aria-label": "群聊详情",
@@ -11544,24 +12383,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11544
12383
  })
11545
12384
  })]
11546
12385
  }),
11547
- props.group === null ? (0, react_jsx_runtime.jsx)("div", {
11548
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupDetailsLoading,
11549
- role: "status",
11550
- children: "正在读取群聊信息…"
11551
- }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
11552
- (0, react_jsx_runtime.jsxs)("section", {
11553
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupSummary,
11554
- children: [
11555
- (0, react_jsx_runtime.jsx)("strong", { children: props.group.title }),
11556
- (0, react_jsx_runtime.jsx)("code", {
11557
- title: props.group.groupDid,
11558
- children: props.group.groupDid
11559
- }),
11560
- props.group.description !== void 0 && props.group.description !== "" && (0, react_jsx_runtime.jsx)("p", { children: props.group.description }),
11561
- (0, react_jsx_runtime.jsxs)("dl", { children: [(0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "我的角色" }), (0, react_jsx_runtime.jsx)("dd", { children: roleLabel(props.group.myRole) })] }), (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "成员" }), (0, react_jsx_runtime.jsx)("dd", { children: props.group.memberCount ?? props.members.length })] })] })
11562
- ]
11563
- }),
11564
- roleRank(props.group.myRole) >= 2 && (0, react_jsx_runtime.jsxs)("form", {
12386
+ (0, react_jsx_runtime.jsxs)("section", {
12387
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupSummary,
12388
+ children: [
12389
+ (0, react_jsx_runtime.jsx)("strong", { children: group?.title ?? props.fallback.title }),
12390
+ (0, react_jsx_runtime.jsx)("code", {
12391
+ title: props.fallback.groupDid,
12392
+ children: props.fallback.groupDid
12393
+ }),
12394
+ group?.description !== void 0 && group.description !== "" && (0, react_jsx_runtime.jsx)("p", { children: group.description }),
12395
+ available && (0, react_jsx_runtime.jsxs)("dl", { children: [(0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "我的角色" }), (0, react_jsx_runtime.jsx)("dd", { children: roleLabel(group.myRole) })] }), (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: "成员" }), (0, react_jsx_runtime.jsx)("dd", { children: group.memberCount ?? props.members.length })] })] })
12396
+ ]
12397
+ }),
12398
+ !available && (0, react_jsx_runtime.jsx)(AwikiGroupAccessNotice, {
12399
+ access: props.access,
12400
+ pending: props.pending,
12401
+ compact: true,
12402
+ onRetry: () => {
12403
+ refreshAccess();
12404
+ },
12405
+ onRejoin: () => {
12406
+ rejoin();
12407
+ },
12408
+ ...props.onRemove === void 0 ? {} : { onRemove: props.onRemove }
12409
+ }),
12410
+ available && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
12411
+ roleRank(group.myRole) >= 2 && (0, react_jsx_runtime.jsxs)("form", {
11565
12412
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupInvite,
11566
12413
  onSubmit: (event) => {
11567
12414
  event.preventDefault();
@@ -11606,22 +12453,38 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11606
12453
  children: [
11607
12454
  (0, react_jsx_runtime.jsxs)("div", {
11608
12455
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupMemberHeading,
11609
- children: [(0, react_jsx_runtime.jsx)("strong", { children: "群成员" }), (0, react_jsx_runtime.jsx)("button", {
11610
- type: "button",
11611
- "aria-label": "刷新群成员",
11612
- disabled: props.pending,
11613
- onClick: () => {
11614
- refresh();
11615
- },
11616
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, { size: 14 })
12456
+ children: [(0, react_jsx_runtime.jsx)("strong", { children: "群成员" }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
12457
+ label: memberRefreshStatus.state === "pending" ? "正在刷新群成员" : "刷新群成员",
12458
+ side: "right",
12459
+ children: (0, react_jsx_runtime.jsx)("button", {
12460
+ type: "button",
12461
+ "aria-label": memberRefreshStatus.state === "pending" ? "正在刷新群成员" : "刷新群成员",
12462
+ "data-busy": memberRefreshStatus.state === "pending" ? "" : void 0,
12463
+ disabled: props.pending || memberRefreshStatus.state === "pending",
12464
+ onClick: () => {
12465
+ refreshMembers();
12466
+ },
12467
+ children: memberRefreshStatus.state === "pending" ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 14 }) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, { size: 14 })
12468
+ })
11617
12469
  })]
11618
12470
  }),
12471
+ memberRefreshStatus.state !== "idle" && (0, react_jsx_runtime.jsxs)("p", {
12472
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupMemberRefreshStatus,
12473
+ "data-state": memberRefreshStatus.state,
12474
+ role: memberRefreshStatus.state === "error" ? "alert" : "status",
12475
+ "aria-live": "polite",
12476
+ children: [
12477
+ memberRefreshStatus.state === "pending" && "正在刷新群成员…",
12478
+ memberRefreshStatus.state === "success" && "群成员已更新",
12479
+ memberRefreshStatus.state === "error" && `刷新失败:${memberRefreshStatus.message}`
12480
+ ]
12481
+ }),
11619
12482
  (0, react_jsx_runtime.jsxs)("div", {
11620
12483
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupMemberList,
11621
12484
  children: [props.members.map((member, index) => {
11622
12485
  const label = memberLabel(member);
11623
12486
  const key = member.membershipId ?? member.did ?? member.handle ?? `${label}-${index}`;
11624
- const removable = canRemoveGroupMember(props.group?.myRole, member, props.identity);
12487
+ const removable = canRemoveGroupMember(group.myRole, member, props.identity);
11625
12488
  return (0, react_jsx_runtime.jsxs)("div", {
11626
12489
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupMemberRow,
11627
12490
  children: [
@@ -11674,12 +12537,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11674
12537
  children: [(0, react_jsx_runtime.jsx)("button", {
11675
12538
  type: "button",
11676
12539
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.dangerText,
11677
- disabled: props.pending || roleRank(props.group.myRole) === 3,
12540
+ disabled: props.pending || roleRank(group.myRole) === 3,
11678
12541
  onClick: () => {
11679
12542
  setLeaveOpen(true);
11680
12543
  },
11681
12544
  children: "退出群聊"
11682
- }), roleRank(props.group.myRole) === 3 && (0, react_jsx_runtime.jsx)("small", { children: "群主不能直接退出群聊" })]
12545
+ }), roleRank(group.myRole) === 3 && (0, react_jsx_runtime.jsx)("small", { children: "群主不能直接退出群聊" })]
11683
12546
  })
11684
12547
  ] }),
11685
12548
  error !== null && (0, react_jsx_runtime.jsx)("div", {
@@ -12031,7 +12894,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12031
12894
  const AWIKI_DRAWER_FRAME_KEY = "dsh-awiki-drawer-frame-v1";
12032
12895
  const LAUNCHER_SIZE = 48;
12033
12896
  const LAUNCHER_EDGE_GAP = 8;
12034
- const LAUNCHER_RIGHT_OFFSET = 28;
12897
+ const LAUNCHER_LEFT_OFFSET = 176;
12035
12898
  const LAUNCHER_BOTTOM_CLEARANCE = 152;
12036
12899
  const LAUNCHER_DRAG_THRESHOLD = 4;
12037
12900
  const DRAWER_LONG_PRESS_MS = 300;
@@ -12135,7 +12998,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12135
12998
  }
12136
12999
  function defaultLauncherPosition() {
12137
13000
  return clampAwikiLauncherPosition({
12138
- left: window.innerWidth - LAUNCHER_SIZE - LAUNCHER_RIGHT_OFFSET,
13001
+ left: LAUNCHER_LEFT_OFFSET,
12139
13002
  top: window.innerHeight - LAUNCHER_SIZE - LAUNCHER_BOTTOM_CLEARANCE
12140
13003
  }, window.innerWidth, window.innerHeight);
12141
13004
  }
@@ -12243,32 +13106,72 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12243
13106
  }
12244
13107
  /** Render one direct or group conversation row. */
12245
13108
  function ConversationRow(props) {
13109
+ const [menuOpen, setMenuOpen] = (0, react.useState)(false);
13110
+ const labelId = (0, react.useId)();
12246
13111
  const label = conversationLabel(props.conversation);
12247
13112
  const unreadCount = props.conversation.unreadCount ?? 0;
12248
13113
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
12249
13114
  const preview = props.conversation.lastMessagePreview ?? "暂无消息";
12250
- return (0, react_jsx_runtime.jsxs)("button", {
12251
- type: "button",
13115
+ return (0, react_jsx_runtime.jsxs)("div", {
12252
13116
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationRow,
12253
13117
  "data-active": props.active || void 0,
12254
- "aria-label": unreadCount > 0 ? `${label},${unreadCount} 条未读消息` : void 0,
12255
- onClick: props.onSelect,
12256
- children: [(0, react_jsx_runtime.jsxs)("span", {
12257
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.avatar,
12258
- children: [props.conversation.kind === "direct" ? "私" : "群", unreadCount > 0 && (0, react_jsx_runtime.jsx)("span", {
12259
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationUnreadBadge,
12260
- "aria-hidden": "true",
12261
- children: unreadLabel
12262
- })]
12263
- }), (0, react_jsx_runtime.jsxs)("span", {
12264
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationText,
13118
+ children: [(0, react_jsx_runtime.jsxs)("button", {
13119
+ type: "button",
13120
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationSelect,
13121
+ "aria-label": unreadCount > 0 ? `${label},${unreadCount} 条未读消息` : void 0,
13122
+ onClick: props.onSelect,
12265
13123
  children: [(0, react_jsx_runtime.jsxs)("span", {
12266
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationHeader,
12267
- children: [(0, react_jsx_runtime.jsx)("strong", { children: label }), props.conversation.lastMessageAt !== void 0 && (0, react_jsx_runtime.jsx)("time", {
12268
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationTime,
12269
- children: conversationTime(props.conversation.lastMessageAt)
13124
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.avatar,
13125
+ children: [props.conversation.kind === "direct" ? "私" : "群", unreadCount > 0 && (0, react_jsx_runtime.jsx)("span", {
13126
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationUnreadBadge,
13127
+ "aria-hidden": "true",
13128
+ children: unreadLabel
12270
13129
  })]
12271
- }), (0, react_jsx_runtime.jsx)("small", { children: preview })]
13130
+ }), (0, react_jsx_runtime.jsxs)("span", {
13131
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationText,
13132
+ children: [(0, react_jsx_runtime.jsxs)("span", {
13133
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationHeader,
13134
+ children: [(0, react_jsx_runtime.jsx)("strong", {
13135
+ id: labelId,
13136
+ children: label
13137
+ }), props.conversation.lastMessageAt !== void 0 && (0, react_jsx_runtime.jsx)("time", {
13138
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationTime,
13139
+ children: conversationTime(props.conversation.lastMessageAt)
13140
+ })]
13141
+ }), (0, react_jsx_runtime.jsx)("small", { children: preview })]
13142
+ })]
13143
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
13144
+ open: menuOpen,
13145
+ onClose: () => {
13146
+ setMenuOpen(false);
13147
+ },
13148
+ align: "end",
13149
+ portal: true,
13150
+ compact: true,
13151
+ items: [{
13152
+ id: "remove",
13153
+ label: "从会话列表移除",
13154
+ icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 14 })
13155
+ }],
13156
+ onSelect: () => {
13157
+ setMenuOpen(false);
13158
+ props.onRemove();
13159
+ },
13160
+ anchor: (0, react_jsx_runtime.jsx)("button", {
13161
+ type: "button",
13162
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationMenu,
13163
+ "aria-label": "更多会话操作",
13164
+ "aria-describedby": labelId,
13165
+ title: `管理会话:${label}`,
13166
+ "aria-expanded": menuOpen,
13167
+ "aria-haspopup": "menu",
13168
+ disabled: props.pending,
13169
+ onClick: (event) => {
13170
+ event.stopPropagation();
13171
+ setMenuOpen((value) => !value);
13172
+ },
13173
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, { size: 15 })
13174
+ })
12272
13175
  })]
12273
13176
  });
12274
13177
  }
@@ -12575,6 +13478,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12575
13478
  const [file, setFile] = (0, react.useState)(null);
12576
13479
  const [sendingDraft, setSendingDraft] = (0, react.useState)(null);
12577
13480
  const [groupDetailsOpen, setGroupDetailsOpen] = (0, react.useState)(false);
13481
+ const [threadMenuOpen, setThreadMenuOpen] = (0, react.useState)(false);
13482
+ const [hiddenConversationsOpen, setHiddenConversationsOpen] = (0, react.useState)(false);
13483
+ const [removeCandidate, setRemoveCandidate] = (0, react.useState)(null);
13484
+ const [conversationPreferenceError, setConversationPreferenceError] = (0, react.useState)(null);
12578
13485
  const [previewUrl, setPreviewUrl] = (0, react.useState)(null);
12579
13486
  const [fileError, setFileError] = (0, react.useState)(null);
12580
13487
  const input = (0, react.useRef)(null);
@@ -12589,6 +13496,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12589
13496
  const [historyAwayFromBottom, setHistoryAwayFromBottom] = (0, react.useState)(false);
12590
13497
  const [unseenMessageCount, setUnseenMessageCount] = (0, react.useState)(0);
12591
13498
  const selected = view.conversations.find((value) => value.id === view.selectedConversationId);
13499
+ const selectedGroupAccess = selected?.kind === "group" ? view.groupAccess?.groupDid === selected.groupDid ? view.groupAccess : {
13500
+ groupDid: selected.groupDid,
13501
+ status: "loading"
13502
+ } : null;
13503
+ const groupWritable = selectedGroupAccess === null || selectedGroupAccess.status === "available";
12592
13504
  const candidates = mentionQuery === null || selected?.kind !== "group" ? [] : mentionCandidates(view.groupMembers, view.identity.did, mentionQuery.query);
12593
13505
  const summary = selected === void 0 ? void 0 : view.summaries[selected.id];
12594
13506
  const summaryPanelId = (0, react.useId)();
@@ -12600,7 +13512,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12600
13512
  setMentionQuery(null);
12601
13513
  setMentionCandidateIndex(0);
12602
13514
  setGroupDetailsOpen(false);
13515
+ setThreadMenuOpen(false);
12603
13516
  }, [view.selectedConversationId]);
13517
+ (0, react.useEffect)(() => {
13518
+ if (view.hiddenConversations.length === 0) setHiddenConversationsOpen(false);
13519
+ }, [view.hiddenConversations.length]);
12604
13520
  (0, react.useEffect)(() => {
12605
13521
  if (mentionCandidateIndex >= candidates.length) setMentionCandidateIndex(0);
12606
13522
  }, [candidates.length, mentionCandidateIndex]);
@@ -12825,349 +13741,553 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12825
13741
  setMentionDrafts(mentionDrafts);
12826
13742
  }
12827
13743
  };
13744
+ const removeConversation = async () => {
13745
+ if (removeCandidate === null) return;
13746
+ setConversationPreferenceError(null);
13747
+ const result = await props.hideConversation(removeCandidate.id);
13748
+ if (!result.ok) {
13749
+ setConversationPreferenceError(result.error);
13750
+ return;
13751
+ }
13752
+ setRemoveCandidate(null);
13753
+ setGroupDetailsOpen(false);
13754
+ };
13755
+ const restoreConversation = async (conversationId) => {
13756
+ setConversationPreferenceError(null);
13757
+ const result = await props.restoreConversation(conversationId);
13758
+ if (!result.ok) setConversationPreferenceError(result.error);
13759
+ };
12828
13760
  return (0, react_jsx_runtime.jsxs)("div", {
12829
13761
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.chat,
12830
- children: [(0, react_jsx_runtime.jsxs)("aside", {
12831
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.roster,
12832
- "data-hidden": selected !== void 0 || void 0,
12833
- "aria-label": "会话",
12834
- children: [
12835
- (0, react_jsx_runtime.jsx)(AwikiProfileCard, {
12836
- identity: view.identity,
12837
- profile: view.profile,
12838
- pending: view.pending !== null,
12839
- updateProfile: props.updateProfile
12840
- }),
12841
- props.modeTabs,
12842
- (0, react_jsx_runtime.jsxs)("div", {
12843
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.rosterHeader,
12844
- children: [(0, react_jsx_runtime.jsx)("div", {
12845
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.rosterTitle,
12846
- children: "会话"
12847
- }), props.composeMenu]
12848
- }),
12849
- view.groupRecovery !== null && (0, react_jsx_runtime.jsxs)("div", {
12850
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupRecoveryNotice,
12851
- "data-status": view.groupRecovery.status,
12852
- role: view.groupRecovery.status === "blocked" ? "alert" : "status",
12853
- children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("strong", { children: view.groupRecovery.status === "pending" ? "正在恢复旧群聊身份" : view.groupRecovery.status === "blocked" ? "部分旧群聊需要处理" : "暂时无法检查旧群聊身份" }), (0, react_jsx_runtime.jsx)("small", { children: view.groupRecovery.status === "pending" ? `${view.groupRecovery.pending} 个群聊尚未完成,其他会话不受影响。` : view.groupRecovery.status === "blocked" ? `${view.groupRecovery.blocked} 个群聊未能自动恢复,其他会话不受影响。` : "私聊和新群聊不受影响,可稍后重试。" })] }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
12854
- label: "重试群聊身份恢复",
12855
- side: "right",
12856
- children: (0, react_jsx_runtime.jsx)("button", {
12857
- type: "button",
12858
- "aria-label": "重试群聊身份恢复",
12859
- disabled: view.pending !== null,
12860
- onClick: () => {
12861
- props.retryGroupRebindRecovery();
12862
- },
12863
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline14, { size: 14 })
12864
- })
12865
- })]
12866
- }),
12867
- (0, react_jsx_runtime.jsxs)("div", {
12868
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationList,
12869
- children: [view.conversations.map((conversation) => (0, react_jsx_runtime.jsx)(ConversationRow, {
12870
- conversation,
12871
- active: conversation.id === view.selectedConversationId,
12872
- onSelect: () => {
12873
- props.selectConversation(conversation.id);
12874
- }
12875
- }, conversation.id)), view.conversations.length === 0 && (0, react_jsx_runtime.jsx)("p", {
12876
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.empty,
12877
- children: "还没有可用的私聊或群聊。"
12878
- })]
12879
- }),
12880
- view.conversationsHasMore && (0, react_jsx_runtime.jsx)("button", {
12881
- type: "button",
12882
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.more,
12883
- onClick: () => {
12884
- props.loadMoreConversations();
12885
- },
12886
- children: "加载更多会话"
12887
- })
12888
- ]
12889
- }), (0, react_jsx_runtime.jsx)("section", {
12890
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.thread,
12891
- "data-visible": selected !== void 0 || void 0,
12892
- children: selected === void 0 ? (0, react_jsx_runtime.jsxs)("div", {
12893
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadEmpty,
12894
- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGlobeOutline14, { size: 28 }), (0, react_jsx_runtime.jsx)("p", { children: "选择一个私聊或群聊查看消息。" })]
12895
- }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
12896
- (0, react_jsx_runtime.jsxs)("header", {
12897
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadHeader,
12898
- children: [
12899
- (0, react_jsx_runtime.jsx)("button", {
12900
- type: "button",
12901
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.back,
12902
- "aria-label": "返回会话列表",
12903
- onClick: () => {
12904
- props.selectConversation(null);
12905
- },
12906
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14, {})
12907
- }),
12908
- (0, react_jsx_runtime.jsxs)("div", {
12909
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadTitle,
12910
- children: [(0, react_jsx_runtime.jsx)("strong", { children: conversationLabel(selected) }), (0, react_jsx_runtime.jsx)("small", { children: selected.kind === "direct" ? "私聊" : "群聊" })]
12911
- }),
12912
- selected.kind === "group" && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
12913
- label: "群聊详情",
12914
- side: "bottom",
12915
- children: (0, react_jsx_runtime.jsx)("button", {
12916
- type: "button",
12917
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadAction,
12918
- "aria-label": "打开群聊详情",
12919
- "aria-expanded": groupDetailsOpen,
12920
- onClick: () => {
12921
- setGroupDetailsOpen((value) => !value);
12922
- },
12923
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSettingsOutline16, { size: 15 })
13762
+ children: [
13763
+ (0, react_jsx_runtime.jsxs)("aside", {
13764
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.roster,
13765
+ "data-hidden": selected !== void 0 || void 0,
13766
+ "aria-label": "会话",
13767
+ children: [
13768
+ (0, react_jsx_runtime.jsx)(AwikiProfileCard, {
13769
+ identity: view.identity,
13770
+ profile: view.profile,
13771
+ pending: view.pending !== null,
13772
+ updateProfile: props.updateProfile
13773
+ }),
13774
+ props.modeTabs,
13775
+ (0, react_jsx_runtime.jsxs)("div", {
13776
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.rosterHeader,
13777
+ children: [(0, react_jsx_runtime.jsx)("div", {
13778
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.rosterTitle,
13779
+ children: "会话"
13780
+ }), (0, react_jsx_runtime.jsxs)("div", {
13781
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.rosterActions,
13782
+ children: [view.hiddenConversations.length > 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13783
+ label: "查看已隐藏会话",
13784
+ side: "right",
13785
+ children: (0, react_jsx_runtime.jsxs)("button", {
13786
+ type: "button",
13787
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.rosterAction,
13788
+ "aria-label": `查看已隐藏会话,${view.hiddenConversations.length} 个`,
13789
+ onClick: () => {
13790
+ setConversationPreferenceError(null);
13791
+ setHiddenConversationsOpen(true);
13792
+ },
13793
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 15 }), (0, react_jsx_runtime.jsx)("small", { children: view.hiddenConversations.length > 99 ? "99+" : view.hiddenConversations.length })]
13794
+ })
13795
+ }), props.composeMenu]
13796
+ })]
13797
+ }),
13798
+ view.groupRecovery !== null && (0, react_jsx_runtime.jsxs)("div", {
13799
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.groupRecoveryNotice,
13800
+ "data-status": view.groupRecovery.status,
13801
+ role: view.groupRecovery.status === "blocked" ? "alert" : "status",
13802
+ children: [
13803
+ (0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("strong", { children: view.groupRecovery.status === "pending" ? "正在恢复旧群聊身份" : view.groupRecovery.status === "blocked" ? "部分旧群聊需要处理" : "暂时无法检查旧群聊身份" }), (0, react_jsx_runtime.jsx)("small", { children: view.groupRecovery.status === "pending" ? `${view.groupRecovery.pending} 个群聊尚未完成,其他会话不受影响。` : view.groupRecovery.status === "blocked" ? `${view.groupRecovery.blocked} 个群聊未能自动恢复,其他会话不受影响。` : "私聊和新群聊不受影响,可稍后重试。" })] }),
13804
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13805
+ label: "重试群聊身份恢复",
13806
+ side: "right",
13807
+ children: (0, react_jsx_runtime.jsx)("button", {
13808
+ type: "button",
13809
+ "aria-label": "重试群聊身份恢复",
13810
+ disabled: view.pending !== null,
13811
+ onClick: () => {
13812
+ props.retryGroupRebindRecovery();
13813
+ },
13814
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline14, { size: 14 })
13815
+ })
13816
+ }),
13817
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13818
+ label: "稍后处理",
13819
+ side: "right",
13820
+ children: (0, react_jsx_runtime.jsx)("button", {
13821
+ type: "button",
13822
+ "aria-label": "关闭旧群聊处理提示",
13823
+ disabled: view.pending !== null,
13824
+ onClick: () => {
13825
+ props.dismissGroupRecoveryNotice();
13826
+ },
13827
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
13828
+ })
12924
13829
  })
12925
- }),
12926
- (0, react_jsx_runtime.jsxs)("button", {
12927
- type: "button",
12928
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.summaryTrigger,
12929
- "aria-controls": summaryPanelId,
12930
- "aria-expanded": summary === void 0 ? void 0 : !summary.collapsed,
12931
- "aria-label": summary?.status === "loading" ? "正在生成 AI 总结" : summary?.collapsed === true ? "展开 AI 总结" : "生成 AI 总结",
12932
- disabled: summary?.status === "loading",
12933
- onClick: () => {
12934
- if (summary !== void 0 && !summary.collapsed && summary.status !== "error") props.setSummaryCollapsed(selected.id, true);
12935
- else if (summary?.collapsed === true) props.setSummaryCollapsed(selected.id, false);
12936
- else props.summarizeConversation();
13830
+ ]
13831
+ }),
13832
+ (0, react_jsx_runtime.jsxs)("div", {
13833
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationList,
13834
+ children: [view.conversations.map((conversation) => (0, react_jsx_runtime.jsx)(ConversationRow, {
13835
+ conversation,
13836
+ active: conversation.id === view.selectedConversationId,
13837
+ pending: view.pending !== null,
13838
+ onSelect: () => {
13839
+ props.selectConversation(conversation.id);
12937
13840
  },
12938
- children: [
12939
- summary?.status === "loading" ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 14 }) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkle16, { size: 14 }),
12940
- (0, react_jsx_runtime.jsx)("span", { children: summary?.status === "loading" ? "总结中" : "AI 总结" }),
12941
- summary !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { size: 12 })
12942
- ]
12943
- })
12944
- ]
12945
- }),
12946
- selected.kind === "group" && groupDetailsOpen && (0, react_jsx_runtime.jsx)(AwikiGroupDetails, {
12947
- group: view.selectedGroup,
12948
- members: view.groupMembers,
12949
- hasMore: view.groupMembersHasMore,
12950
- identity: view.identity,
12951
- pending: view.pending !== null,
12952
- refreshSelectedGroup: props.refreshSelectedGroup,
12953
- loadMoreGroupMembers: props.loadMoreGroupMembers,
12954
- addSelectedGroupMember: props.addSelectedGroupMember,
12955
- removeSelectedGroupMember: props.removeSelectedGroupMember,
12956
- leaveSelectedGroup: props.leaveSelectedGroup,
12957
- onClose: () => {
12958
- setGroupDetailsOpen(false);
12959
- }
12960
- }),
12961
- summary !== void 0 && (0, react_jsx_runtime.jsx)(SummaryPanel, {
12962
- id: summaryPanelId,
12963
- summary,
12964
- regenerate: () => {
12965
- props.summarizeConversation();
12966
- },
12967
- collapse: (collapsed) => {
12968
- props.setSummaryCollapsed(selected.id, collapsed);
12969
- },
12970
- viewSource: viewSummarySource
12971
- }),
12972
- (0, react_jsx_runtime.jsxs)("div", {
12973
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.historyShell,
12974
- children: [(0, react_jsx_runtime.jsxs)("div", {
12975
- ref: history,
12976
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.history,
12977
- role: "log",
12978
- "aria-label": "消息记录",
12979
- onScroll: syncHistoryPosition,
13841
+ onRemove: () => {
13842
+ setConversationPreferenceError(null);
13843
+ setRemoveCandidate(conversation);
13844
+ }
13845
+ }, conversation.id)), view.conversations.length === 0 && (0, react_jsx_runtime.jsx)("p", {
13846
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.empty,
13847
+ children: "还没有可用的私聊或群聊。"
13848
+ })]
13849
+ }),
13850
+ view.conversationsHasMore && (0, react_jsx_runtime.jsx)("button", {
13851
+ type: "button",
13852
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.more,
13853
+ onClick: () => {
13854
+ props.loadMoreConversations();
13855
+ },
13856
+ children: "加载更多会话"
13857
+ })
13858
+ ]
13859
+ }),
13860
+ (0, react_jsx_runtime.jsx)("section", {
13861
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.thread,
13862
+ "data-visible": selected !== void 0 || void 0,
13863
+ children: selected === void 0 ? (0, react_jsx_runtime.jsxs)("div", {
13864
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadEmpty,
13865
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGlobeOutline14, { size: 28 }), (0, react_jsx_runtime.jsx)("p", { children: "选择一个私聊或群聊查看消息。" })]
13866
+ }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13867
+ (0, react_jsx_runtime.jsxs)("header", {
13868
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadHeader,
12980
13869
  children: [
12981
- view.historyHasMore && (0, react_jsx_runtime.jsx)("button", {
13870
+ (0, react_jsx_runtime.jsx)("button", {
12982
13871
  type: "button",
12983
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.more,
13872
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.back,
13873
+ "aria-label": "返回会话列表",
12984
13874
  onClick: () => {
12985
- props.loadOlderHistory();
13875
+ props.selectConversation(null);
12986
13876
  },
12987
- children: "加载更早消息"
13877
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14, {})
12988
13878
  }),
12989
- view.localPending && (0, react_jsx_runtime.jsxs)("div", {
12990
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.historyLoading,
12991
- role: "status",
12992
- "aria-live": "polite",
12993
- "aria-label": "正在读取本地消息",
12994
- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 18 }), (0, react_jsx_runtime.jsx)("span", { children: "正在读取本地消息…" })]
13879
+ (0, react_jsx_runtime.jsxs)("div", {
13880
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadTitle,
13881
+ children: [(0, react_jsx_runtime.jsx)("strong", { children: conversationLabel(selected) }), (0, react_jsx_runtime.jsx)("small", { children: selected.kind === "direct" ? "私聊" : "群聊" })]
12995
13882
  }),
12996
- !view.localPending && view.refreshing && view.messages.length === 0 && (0, react_jsx_runtime.jsxs)("div", {
12997
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.historyLoading,
12998
- role: "status",
12999
- "aria-live": "polite",
13000
- "aria-label": "正在同步消息",
13001
- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 18 }), (0, react_jsx_runtime.jsx)("span", { children: "正在同步消息…" })]
13883
+ selected.kind === "group" && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13884
+ label: "群聊详情",
13885
+ side: "bottom",
13886
+ children: (0, react_jsx_runtime.jsx)("button", {
13887
+ type: "button",
13888
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadAction,
13889
+ "aria-label": "打开群聊详情",
13890
+ "aria-expanded": groupDetailsOpen,
13891
+ onClick: () => {
13892
+ setGroupDetailsOpen((value) => !value);
13893
+ },
13894
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSettingsOutline16, { size: 15 })
13895
+ })
13002
13896
  }),
13003
- view.messages.map((message) => (0, react_jsx_runtime.jsx)(MessageRow, {
13004
- message,
13005
- peerLabel: selected.kind === "direct" ? conversationLabel(selected) : void 0,
13006
- download: props.downloadAttachment,
13007
- onImageLoad: scrollAfterInitialImage
13008
- }, message.id)),
13009
- visibleSendingDraft !== null && (0, react_jsx_runtime.jsx)(PendingMessageRow, { draft: visibleSendingDraft }),
13010
- !view.localPending && !view.refreshing && view.messages.length === 0 && visibleSendingDraft === null && (0, react_jsx_runtime.jsx)("p", {
13011
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.empty,
13012
- children: "暂无消息。"
13897
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
13898
+ open: threadMenuOpen,
13899
+ onClose: () => {
13900
+ setThreadMenuOpen(false);
13901
+ },
13902
+ align: "end",
13903
+ portal: true,
13904
+ compact: true,
13905
+ items: [{
13906
+ id: "remove",
13907
+ label: "从会话列表移除",
13908
+ icon: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, { size: 14 })
13909
+ }],
13910
+ onSelect: () => {
13911
+ setThreadMenuOpen(false);
13912
+ setConversationPreferenceError(null);
13913
+ setRemoveCandidate(selected);
13914
+ },
13915
+ anchor: (0, react_jsx_runtime.jsx)("button", {
13916
+ type: "button",
13917
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.threadAction,
13918
+ "aria-label": "更多会话操作",
13919
+ "aria-expanded": threadMenuOpen,
13920
+ "aria-haspopup": "menu",
13921
+ disabled: view.pending !== null,
13922
+ onClick: () => {
13923
+ setThreadMenuOpen((value) => !value);
13924
+ },
13925
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, { size: 15 })
13926
+ })
13927
+ }),
13928
+ (0, react_jsx_runtime.jsxs)("button", {
13929
+ type: "button",
13930
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.summaryTrigger,
13931
+ "aria-controls": summaryPanelId,
13932
+ "aria-expanded": summary === void 0 ? void 0 : !summary.collapsed,
13933
+ "aria-label": summary?.status === "loading" ? "正在生成 AI 总结" : summary?.collapsed === true ? "展开 AI 总结" : "生成 AI 总结",
13934
+ disabled: summary?.status === "loading",
13935
+ onClick: () => {
13936
+ if (summary !== void 0 && !summary.collapsed && summary.status !== "error") props.setSummaryCollapsed(selected.id, true);
13937
+ else if (summary?.collapsed === true) props.setSummaryCollapsed(selected.id, false);
13938
+ else props.summarizeConversation();
13939
+ },
13940
+ children: [
13941
+ summary?.status === "loading" ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 14 }) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSparkle16, { size: 14 }),
13942
+ (0, react_jsx_runtime.jsx)("span", { children: summary?.status === "loading" ? "总结中" : "AI 总结" }),
13943
+ summary !== void 0 && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { size: 12 })
13944
+ ]
13013
13945
  })
13014
13946
  ]
13015
- }), historyAwayFromBottom && (0, react_jsx_runtime.jsxs)("button", {
13016
- type: "button",
13017
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.latestMessages,
13018
- "aria-label": unseenMessageCount === 0 ? "下滑到最新消息" : `有 ${unseenMessageCount} 条新消息,下滑到最新消息`,
13019
- onClick: () => {
13020
- scrollHistoryToLatest(true);
13947
+ }),
13948
+ selectedGroupAccess !== null && selectedGroupAccess.status !== "available" && (0, react_jsx_runtime.jsx)(AwikiGroupAccessNotice, {
13949
+ access: selectedGroupAccess,
13950
+ pending: view.pending !== null,
13951
+ onRetry: () => {
13952
+ props.refreshSelectedGroup();
13021
13953
  },
13022
- children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { size: 14 }), unseenMessageCount > 0 && (0, react_jsx_runtime.jsxs)("span", { children: [
13023
- "新消息(",
13024
- unseenMessageCount,
13025
- ")"
13026
- ] })]
13027
- })]
13028
- }),
13029
- (0, react_jsx_runtime.jsxs)("div", {
13030
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.composer,
13031
- children: [fileError !== null && (0, react_jsx_runtime.jsx)("small", {
13032
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.inlineError,
13033
- role: "alert",
13034
- children: fileError
13035
- }), (0, react_jsx_runtime.jsxs)("div", {
13036
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.composeInput,
13037
- children: [
13038
- file !== null && (0, react_jsx_runtime.jsxs)("div", {
13039
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePreview,
13040
- "data-image": previewUrl !== null || void 0,
13041
- children: [
13042
- previewUrl === null ? (0, react_jsx_runtime.jsx)("span", {
13043
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePreviewIcon,
13044
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPaperclipOutline16, {})
13045
- }) : (0, react_jsx_runtime.jsx)("img", {
13046
- src: previewUrl,
13047
- alt: file.name
13048
- }),
13049
- previewUrl === null && (0, react_jsx_runtime.jsx)("span", {
13050
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePreviewName,
13051
- children: file.name
13052
- }),
13053
- (0, react_jsx_runtime.jsx)("button", {
13054
- type: "button",
13055
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.removeFile,
13056
- "aria-label": `移除附件 ${file.name}`,
13057
- onClick: clearFile,
13058
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 12 })
13059
- })
13060
- ]
13061
- }),
13062
- mentionQuery !== null && candidates.length > 0 && (0, react_jsx_runtime.jsx)("div", {
13063
- id: mentionListId,
13064
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.mentionCandidates,
13065
- role: "listbox",
13066
- "aria-label": "可提及的群成员",
13067
- children: candidates.map((candidate, index) => (0, react_jsx_runtime.jsxs)("button", {
13954
+ onRejoin: () => {
13955
+ props.joinGroup(selectedGroupAccess.groupDid);
13956
+ },
13957
+ onBack: () => {
13958
+ props.selectConversation(null);
13959
+ },
13960
+ onRemove: () => {
13961
+ setConversationPreferenceError(null);
13962
+ setRemoveCandidate(selected);
13963
+ }
13964
+ }),
13965
+ selected.kind === "group" && groupDetailsOpen && (0, react_jsx_runtime.jsx)(AwikiGroupDetails, {
13966
+ group: view.selectedGroup,
13967
+ fallback: {
13968
+ groupDid: selected.groupDid,
13969
+ title: conversationLabel(selected)
13970
+ },
13971
+ access: selectedGroupAccess ?? {
13972
+ groupDid: selected.groupDid,
13973
+ status: "loading"
13974
+ },
13975
+ members: view.groupMembers,
13976
+ hasMore: view.groupMembersHasMore,
13977
+ identity: view.identity,
13978
+ pending: view.pending !== null,
13979
+ refreshSelectedGroup: props.refreshSelectedGroup,
13980
+ loadMoreGroupMembers: props.loadMoreGroupMembers,
13981
+ addSelectedGroupMember: props.addSelectedGroupMember,
13982
+ removeSelectedGroupMember: props.removeSelectedGroupMember,
13983
+ leaveSelectedGroup: props.leaveSelectedGroup,
13984
+ joinGroup: props.joinGroup,
13985
+ onClose: () => {
13986
+ setGroupDetailsOpen(false);
13987
+ },
13988
+ onRemove: () => {
13989
+ setConversationPreferenceError(null);
13990
+ setRemoveCandidate(selected);
13991
+ }
13992
+ }),
13993
+ summary !== void 0 && (0, react_jsx_runtime.jsx)(SummaryPanel, {
13994
+ id: summaryPanelId,
13995
+ summary,
13996
+ regenerate: () => {
13997
+ props.summarizeConversation();
13998
+ },
13999
+ collapse: (collapsed) => {
14000
+ props.setSummaryCollapsed(selected.id, collapsed);
14001
+ },
14002
+ viewSource: viewSummarySource
14003
+ }),
14004
+ (0, react_jsx_runtime.jsxs)("div", {
14005
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.historyShell,
14006
+ children: [(0, react_jsx_runtime.jsxs)("div", {
14007
+ ref: history,
14008
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.history,
14009
+ role: "log",
14010
+ "aria-label": "消息记录",
14011
+ onScroll: syncHistoryPosition,
14012
+ children: [
14013
+ view.historyHasMore && (0, react_jsx_runtime.jsx)("button", {
13068
14014
  type: "button",
13069
- role: "option",
13070
- "aria-selected": index === mentionCandidateIndex,
13071
- onMouseDown: (event) => {
13072
- event.preventDefault();
13073
- chooseMention(index);
14015
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.more,
14016
+ onClick: () => {
14017
+ props.loadOlderHistory();
13074
14018
  },
14019
+ children: "加载更早消息"
14020
+ }),
14021
+ view.localPending && (0, react_jsx_runtime.jsxs)("div", {
14022
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.historyLoading,
14023
+ role: "status",
14024
+ "aria-live": "polite",
14025
+ "aria-label": "正在读取本地消息",
14026
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 18 }), (0, react_jsx_runtime.jsx)("span", { children: "正在读取本地消息…" })]
14027
+ }),
14028
+ !view.localPending && view.refreshing && view.messages.length === 0 && (0, react_jsx_runtime.jsxs)("div", {
14029
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.historyLoading,
14030
+ role: "status",
14031
+ "aria-live": "polite",
14032
+ "aria-label": "正在同步消息",
14033
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLoadingOutline16, { size: 18 }), (0, react_jsx_runtime.jsx)("span", { children: "正在同步消息…" })]
14034
+ }),
14035
+ view.messages.map((message) => (0, react_jsx_runtime.jsx)(MessageRow, {
14036
+ message,
14037
+ peerLabel: selected.kind === "direct" ? conversationLabel(selected) : void 0,
14038
+ download: props.downloadAttachment,
14039
+ onImageLoad: scrollAfterInitialImage
14040
+ }, message.id)),
14041
+ visibleSendingDraft !== null && (0, react_jsx_runtime.jsx)(PendingMessageRow, { draft: visibleSendingDraft }),
14042
+ !view.localPending && !view.refreshing && view.messages.length === 0 && visibleSendingDraft === null && (0, react_jsx_runtime.jsx)("p", {
14043
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.empty,
14044
+ children: "暂无消息。"
14045
+ })
14046
+ ]
14047
+ }), historyAwayFromBottom && (0, react_jsx_runtime.jsxs)("button", {
14048
+ type: "button",
14049
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.latestMessages,
14050
+ "aria-label": unseenMessageCount === 0 ? "下滑到最新消息" : `有 ${unseenMessageCount} 条新消息,下滑到最新消息`,
14051
+ onClick: () => {
14052
+ scrollHistoryToLatest(true);
14053
+ },
14054
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { size: 14 }), unseenMessageCount > 0 && (0, react_jsx_runtime.jsxs)("span", { children: [
14055
+ "新消息(",
14056
+ unseenMessageCount,
14057
+ ")"
14058
+ ] })]
14059
+ })]
14060
+ }),
14061
+ (0, react_jsx_runtime.jsxs)("div", {
14062
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.composer,
14063
+ children: [fileError !== null && (0, react_jsx_runtime.jsx)("small", {
14064
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.inlineError,
14065
+ role: "alert",
14066
+ children: fileError
14067
+ }), (0, react_jsx_runtime.jsxs)("div", {
14068
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.composeInput,
14069
+ children: [
14070
+ file !== null && (0, react_jsx_runtime.jsxs)("div", {
14071
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePreview,
14072
+ "data-image": previewUrl !== null || void 0,
13075
14073
  children: [
13076
- (0, react_jsx_runtime.jsx)("span", { children: candidate.label.slice(0, 1).toLocaleUpperCase() }),
13077
- (0, react_jsx_runtime.jsx)("strong", { children: candidate.label }),
13078
- (0, react_jsx_runtime.jsx)("small", { children: candidate.member.handle ?? candidate.member.did })
14074
+ previewUrl === null ? (0, react_jsx_runtime.jsx)("span", {
14075
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePreviewIcon,
14076
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPaperclipOutline16, {})
14077
+ }) : (0, react_jsx_runtime.jsx)("img", {
14078
+ src: previewUrl,
14079
+ alt: file.name
14080
+ }),
14081
+ previewUrl === null && (0, react_jsx_runtime.jsx)("span", {
14082
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePreviewName,
14083
+ children: file.name
14084
+ }),
14085
+ (0, react_jsx_runtime.jsx)("button", {
14086
+ type: "button",
14087
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.removeFile,
14088
+ "aria-label": `移除附件 ${file.name}`,
14089
+ disabled: !groupWritable,
14090
+ onClick: clearFile,
14091
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 12 })
14092
+ })
13079
14093
  ]
13080
- }, candidate.member.did))
13081
- }),
13082
- (0, react_jsx_runtime.jsx)("textarea", {
13083
- ref: composer,
13084
- value: text,
13085
- "aria-controls": mentionQuery !== null && candidates.length > 0 ? mentionListId : void 0,
13086
- "aria-expanded": mentionQuery !== null && candidates.length > 0,
13087
- "aria-autocomplete": "list",
13088
- onChange: (event) => {
13089
- const next = event.target.value;
13090
- setMentionDrafts((current) => transformMentionDrafts(text, next, current));
13091
- setText(next);
13092
- syncMentionQuery(next, event.target.selectionStart);
13093
- },
13094
- onSelect: (event) => {
13095
- syncMentionQuery(text, event.currentTarget.selectionStart);
13096
- },
13097
- onKeyDown: (event) => {
13098
- if (mentionQuery !== null && candidates.length > 0) {
13099
- if (event.key === "ArrowDown") {
13100
- event.preventDefault();
13101
- setMentionCandidateIndex((index) => (index + 1) % candidates.length);
13102
- return;
13103
- }
13104
- if (event.key === "ArrowUp") {
13105
- event.preventDefault();
13106
- setMentionCandidateIndex((index) => (index - 1 + candidates.length) % candidates.length);
13107
- return;
13108
- }
13109
- if ((event.key === "Enter" || event.key === "Tab") && !event.nativeEvent.isComposing) {
13110
- event.preventDefault();
13111
- chooseMention(mentionCandidateIndex);
13112
- return;
13113
- }
13114
- if (event.key === "Escape") {
14094
+ }),
14095
+ mentionQuery !== null && candidates.length > 0 && (0, react_jsx_runtime.jsx)("div", {
14096
+ id: mentionListId,
14097
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.mentionCandidates,
14098
+ role: "listbox",
14099
+ "aria-label": "可提及的群成员",
14100
+ children: candidates.map((candidate, index) => (0, react_jsx_runtime.jsxs)("button", {
14101
+ type: "button",
14102
+ role: "option",
14103
+ "aria-selected": index === mentionCandidateIndex,
14104
+ onMouseDown: (event) => {
13115
14105
  event.preventDefault();
13116
- setMentionQuery(null);
13117
- return;
14106
+ chooseMention(index);
14107
+ },
14108
+ children: [
14109
+ (0, react_jsx_runtime.jsx)("span", { children: candidate.label.slice(0, 1).toLocaleUpperCase() }),
14110
+ (0, react_jsx_runtime.jsx)("strong", { children: candidate.label }),
14111
+ (0, react_jsx_runtime.jsx)("small", { children: candidate.member.handle ?? candidate.member.did })
14112
+ ]
14113
+ }, candidate.member.did))
14114
+ }),
14115
+ (0, react_jsx_runtime.jsx)("textarea", {
14116
+ ref: composer,
14117
+ value: text,
14118
+ disabled: !groupWritable,
14119
+ "aria-controls": mentionQuery !== null && candidates.length > 0 ? mentionListId : void 0,
14120
+ "aria-expanded": mentionQuery !== null && candidates.length > 0,
14121
+ "aria-autocomplete": "list",
14122
+ onChange: (event) => {
14123
+ const next = event.target.value;
14124
+ setMentionDrafts((current) => transformMentionDrafts(text, next, current));
14125
+ setText(next);
14126
+ syncMentionQuery(next, event.target.selectionStart);
14127
+ },
14128
+ onSelect: (event) => {
14129
+ syncMentionQuery(text, event.currentTarget.selectionStart);
14130
+ },
14131
+ onKeyDown: (event) => {
14132
+ if (mentionQuery !== null && candidates.length > 0) {
14133
+ if (event.key === "ArrowDown") {
14134
+ event.preventDefault();
14135
+ setMentionCandidateIndex((index) => (index + 1) % candidates.length);
14136
+ return;
14137
+ }
14138
+ if (event.key === "ArrowUp") {
14139
+ event.preventDefault();
14140
+ setMentionCandidateIndex((index) => (index - 1 + candidates.length) % candidates.length);
14141
+ return;
14142
+ }
14143
+ if ((event.key === "Enter" || event.key === "Tab") && !event.nativeEvent.isComposing) {
14144
+ event.preventDefault();
14145
+ chooseMention(mentionCandidateIndex);
14146
+ return;
14147
+ }
14148
+ if (event.key === "Escape") {
14149
+ event.preventDefault();
14150
+ setMentionQuery(null);
14151
+ return;
14152
+ }
13118
14153
  }
13119
- }
13120
- if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
13121
- event.preventDefault();
13122
- if (view.pending === null && sendingDraft === null && (file !== null || text.trim() !== "")) sendMessage();
13123
- },
13124
- placeholder: "输入消息",
13125
- rows: 2
13126
- }),
13127
- (0, react_jsx_runtime.jsxs)("div", {
13128
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.composeActions,
13129
- children: [
13130
- (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13131
- label: "添加附件",
13132
- side: "top",
13133
- children: (0, react_jsx_runtime.jsx)("button", {
14154
+ if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
14155
+ event.preventDefault();
14156
+ if (view.pending === null && sendingDraft === null && (file !== null || text.trim() !== "")) sendMessage();
14157
+ },
14158
+ placeholder: groupWritable ? "输入消息" : "当前群聊暂不可发送消息",
14159
+ rows: 2
14160
+ }),
14161
+ (0, react_jsx_runtime.jsxs)("div", {
14162
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.composeActions,
14163
+ children: [
14164
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
14165
+ label: "添加附件",
14166
+ side: "top",
14167
+ children: (0, react_jsx_runtime.jsx)("button", {
14168
+ type: "button",
14169
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePicker,
14170
+ "aria-label": "添加附件",
14171
+ disabled: !groupWritable || view.pending !== null || sendingDraft !== null,
14172
+ onClick: () => {
14173
+ input.current?.click();
14174
+ },
14175
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPaperclipOutline16, {})
14176
+ })
14177
+ }),
14178
+ (0, react_jsx_runtime.jsx)("input", {
14179
+ ref: input,
14180
+ type: "file",
14181
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.fileInput,
14182
+ "aria-label": "选择一个附件",
14183
+ disabled: !groupWritable,
14184
+ onChange: (event) => {
14185
+ setFile(event.target.files?.[0] ?? null);
14186
+ setFileError(null);
14187
+ }
14188
+ }),
14189
+ (0, react_jsx_runtime.jsx)("button", {
13134
14190
  type: "button",
13135
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.filePicker,
13136
- "aria-label": "添加附件",
13137
- disabled: view.pending !== null || sendingDraft !== null,
14191
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.send,
14192
+ "aria-label": "发送消息",
14193
+ disabled: !groupWritable || view.pending !== null || sendingDraft !== null || file === null && text.trim() === "",
13138
14194
  onClick: () => {
13139
- input.current?.click();
14195
+ sendMessage();
13140
14196
  },
13141
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPaperclipOutline16, {})
14197
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, {})
13142
14198
  })
13143
- }),
13144
- (0, react_jsx_runtime.jsx)("input", {
13145
- ref: input,
13146
- type: "file",
13147
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.fileInput,
13148
- "aria-label": "选择一个附件",
13149
- onChange: (event) => {
13150
- setFile(event.target.files?.[0] ?? null);
13151
- setFileError(null);
13152
- }
13153
- }),
13154
- (0, react_jsx_runtime.jsx)("button", {
13155
- type: "button",
13156
- className: _dsh_awiki_css_AwikiOverlay_module_css_default.send,
13157
- "aria-label": "发送消息",
13158
- disabled: view.pending !== null || sendingDraft !== null || file === null && text.trim() === "",
13159
- onClick: () => {
13160
- sendMessage();
13161
- },
13162
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline16, {})
13163
- })
13164
- ]
14199
+ ]
14200
+ })
14201
+ ]
14202
+ })]
14203
+ })
14204
+ ] })
14205
+ }),
14206
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
14207
+ open: removeCandidate !== null,
14208
+ onClose: () => {
14209
+ if (view.pending === null) {
14210
+ setRemoveCandidate(null);
14211
+ setConversationPreferenceError(null);
14212
+ }
14213
+ },
14214
+ title: "从会话列表移除",
14215
+ closeLabel: "取消",
14216
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.compactModal ?? "",
14217
+ description: removeCandidate === null ? "" : `“${conversationLabel(removeCandidate)}”只会从本机最近会话中移除,不会${removeCandidate.kind === "group" ? "退出群聊或" : ""}清除已有消息。收到新消息后可能重新出现。`,
14218
+ footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
14219
+ type: "button",
14220
+ variant: "outline",
14221
+ disabled: view.pending !== null,
14222
+ onClick: () => {
14223
+ setRemoveCandidate(null);
14224
+ setConversationPreferenceError(null);
14225
+ },
14226
+ children: "取消"
14227
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
14228
+ type: "button",
14229
+ variant: "outline",
14230
+ disabled: view.pending !== null,
14231
+ onClick: () => {
14232
+ removeConversation();
14233
+ },
14234
+ children: "确认移除"
14235
+ })] }),
14236
+ children: conversationPreferenceError !== null && (0, react_jsx_runtime.jsx)("div", {
14237
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationPreferenceError,
14238
+ role: "alert",
14239
+ children: conversationPreferenceError
14240
+ })
14241
+ }),
14242
+ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
14243
+ open: hiddenConversationsOpen,
14244
+ onClose: () => {
14245
+ if (view.pending === null) {
14246
+ setHiddenConversationsOpen(false);
14247
+ setConversationPreferenceError(null);
14248
+ }
14249
+ },
14250
+ title: "已隐藏会话",
14251
+ closeLabel: "关闭",
14252
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.compactModal ?? "",
14253
+ description: "这些会话只在本机列表中隐藏,消息和群成员关系没有改变。",
14254
+ footer: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
14255
+ type: "button",
14256
+ variant: "outline",
14257
+ disabled: view.pending !== null,
14258
+ onClick: () => {
14259
+ setHiddenConversationsOpen(false);
14260
+ setConversationPreferenceError(null);
14261
+ },
14262
+ children: "完成"
14263
+ }),
14264
+ children: [(0, react_jsx_runtime.jsx)("div", {
14265
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.hiddenConversationList,
14266
+ children: view.hiddenConversations.map((conversation) => (0, react_jsx_runtime.jsxs)("div", {
14267
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.hiddenConversationRow,
14268
+ children: [
14269
+ (0, react_jsx_runtime.jsx)("span", {
14270
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.avatar,
14271
+ children: conversation.kind === "direct" ? "私" : "群"
14272
+ }),
14273
+ (0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("strong", { children: conversationLabel(conversation) }), (0, react_jsx_runtime.jsx)("small", { children: conversation.lastMessagePreview ?? "暂无消息" })] }),
14274
+ (0, react_jsx_runtime.jsx)("button", {
14275
+ type: "button",
14276
+ disabled: view.pending !== null,
14277
+ onClick: () => {
14278
+ restoreConversation(conversation.id);
14279
+ },
14280
+ children: "恢复"
13165
14281
  })
13166
14282
  ]
13167
- })]
13168
- })
13169
- ] })
13170
- })]
14283
+ }, conversation.id))
14284
+ }), conversationPreferenceError !== null && (0, react_jsx_runtime.jsx)("div", {
14285
+ className: _dsh_awiki_css_AwikiOverlay_module_css_default.conversationPreferenceError,
14286
+ role: "alert",
14287
+ children: conversationPreferenceError
14288
+ })]
14289
+ })
14290
+ ]
13171
14291
  });
13172
14292
  }
13173
14293
  /**
@@ -13212,7 +14332,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
13212
14332
  const launcherDrag = (0, react.useRef)(null);
13213
14333
  const drawerDrag = (0, react.useRef)(null);
13214
14334
  const drawerResize = (0, react.useRef)(null);
13215
- const registered = view.status === "ready" && view.identity !== null;
14335
+ const registered = view.status === "ready" && view.sessionStatus === "active" && view.identity !== null;
13216
14336
  const unreadCount = view.conversations.reduce((total, conversation) => total + (conversation.unreadCount ?? 0), 0);
13217
14337
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
13218
14338
  const nominalDrawerWidth = Math.min(mode === "mail" ? MAIL_DRAWER_NOMINAL_WIDTH : DRAWER_NOMINAL_WIDTH, Math.max(1, window.innerWidth - (window.innerWidth <= 620 ? DRAWER_COMPACT_HORIZONTAL_RESERVE : DRAWER_HORIZONTAL_RESERVE)));
@@ -13681,11 +14801,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
13681
14801
  children: "重试"
13682
14802
  })]
13683
14803
  }),
13684
- view.status === "ready" && (view.sessionStatus === "unregistered" || view.sessionStatus === "signed-out") && (0, react_jsx_runtime.jsx)("div", {
14804
+ view.status === "ready" && (view.sessionStatus === "unregistered" || view.sessionStatus === "signed-out" || view.sessionStatus === "recovery-required") && (0, react_jsx_runtime.jsx)("div", {
13685
14805
  className: _dsh_awiki_css_AwikiOverlay_module_css_default.identityAccess,
13686
14806
  children: (0, react_jsx_runtime.jsx)(AwikiIdentityAccess, {
13687
14807
  ...props,
13688
14808
  sessionStatus: view.sessionStatus,
14809
+ identity: view.identity,
13689
14810
  recoveryOperationId: view.recoveryOperationId,
13690
14811
  recoveryProgress: view.recoveryProgress,
13691
14812
  pending: view.pending !== null
@@ -16592,7 +17713,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16592
17713
  children: [
16593
17714
  (0, react_jsx_runtime.jsx)("p", {
16594
17715
  className: _dsh_awiki_css_AwikiSettingsSection_module_css_default.notice,
16595
- children: view.sessionStatus === "signed-out" ? t("identitySignedOutRequired") : t("identityRegistrationRequired")
17716
+ children: view.sessionStatus === "recovery-required" ? t("identityRecoveryRequired") : view.sessionStatus === "signed-out" ? t("identitySignedOutRequired") : t("identityRegistrationRequired")
16596
17717
  }),
16597
17718
  view.sessionStatus === "signed-out" && (0, react_jsx_runtime.jsx)("div", {
16598
17719
  className: _dsh_awiki_css_AwikiSettingsSection_module_css_default.actions,
@@ -17589,7 +18710,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17589
18710
  capabilityProbe;
17590
18711
  disposed = false;
17591
18712
  generation = 0;
17592
- constructor(connection, identity, rechargeEnabled = false) {
18713
+ constructor(connection, identity, rechargeEnabled = true) {
17593
18714
  this.connection = connection;
17594
18715
  this.identity = identity;
17595
18716
  this.rechargeEnabled = rechargeEnabled;
@@ -17997,6 +19118,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17997
19118
  onboardingRegistrationDescription: "创建或使用当前设备的 AWiki 身份,即可通过 AWiki 托管代理服务访问 DeepSeek 模型。",
17998
19119
  onboardingRestoreTitle: "恢复 AWiki 身份",
17999
19120
  onboardingRestoreDescription: "这台设备保留了一个已退出的 AWiki 身份。恢复后可以继续使用原账户。",
19121
+ onboardingRecoveryRequiredTitle: "需要重新恢复 AWiki 身份",
19122
+ onboardingRecoveryRequiredDescription: "当前设备的旧身份凭证已失效。验证原绑定手机号并恢复后,才能继续使用 AWiki 账户和托管模型。",
18000
19123
  onboardingRestore: "恢复身份",
18001
19124
  onboardingEnableTitle: "启用 AWiki 托管模型",
18002
19125
  onboardingBypassDescription: "当前为开发联调模式,可直接启用模型,不会扣减账户余额。",
@@ -18007,6 +19130,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18007
19130
  identityLoading: "正在读取 AWiki 身份状态…",
18008
19131
  identitySignedOutRequired: "当前 AWiki 身份已退出。恢复这台设备保留的身份后,才能查看账户余额、充值和用量。",
18009
19132
  identityRegistrationRequired: "请先通过 AWiki 面板创建身份,再查看账户余额、充值和用量。",
19133
+ identityRecoveryRequired: "当前设备的 AWiki 身份凭证已失效。请在 AWiki 面板验证绑定手机号并恢复身份后,再查看账户余额、充值和用量。",
18010
19134
  identityRestoring: "正在恢复…",
18011
19135
  domainLabel: "默认域名",
18012
19136
  domainDescription: "输入纯域名,不要包含协议、路径或端口。",
@@ -18119,6 +19243,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18119
19243
  onboardingRegistrationDescription: "Create or use this device’s AWiki identity to access DeepSeek through AWiki’s hosted proxy service.",
18120
19244
  onboardingRestoreTitle: "Restore AWiki identity",
18121
19245
  onboardingRestoreDescription: "This device retains a signed-out AWiki identity. Restore it to continue using the existing account.",
19246
+ onboardingRecoveryRequiredTitle: "Recover the AWiki identity again",
19247
+ onboardingRecoveryRequiredDescription: "The previous identity credential on this device is no longer valid. Verify the bound phone and recover it before using the AWiki account or hosted models.",
18122
19248
  onboardingRestore: "Restore identity",
18123
19249
  onboardingEnableTitle: "Enable AWiki-hosted DeepSeek",
18124
19250
  onboardingBypassDescription: "Development bypass is active, so models can be enabled without reducing the account balance.",
@@ -18129,6 +19255,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18129
19255
  identityLoading: "Loading the AWiki identity…",
18130
19256
  identitySignedOutRequired: "The AWiki identity is signed out. Restore the identity retained on this device to view the account, recharge, and usage.",
18131
19257
  identityRegistrationRequired: "Create an identity from the AWiki panel before viewing the account, recharge, and usage.",
19258
+ identityRecoveryRequired: "The AWiki credential on this device is no longer valid. Recover the identity from the AWiki panel before viewing the account, recharge, and usage.",
18132
19259
  identityRestoring: "Restoring…",
18133
19260
  domainLabel: "Default domain",
18134
19261
  domainDescription: "Enter a bare domain without a protocol, path, or port.",
@@ -18367,7 +19494,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18367
19494
  awikiController = awiki;
18368
19495
  const availability = new ModelAvailabilityController(connection);
18369
19496
  availabilityController = availability;
18370
- const models = new AwikiModelProxyController(connection, awiki, false);
19497
+ const models = new AwikiModelProxyController(connection, awiki, true);
18371
19498
  modelController = models;
18372
19499
  await Promise.all([settings.load(), models.probe()]);
18373
19500
  ctx.effect(() => {
@@ -18417,6 +19544,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18417
19544
  discardRecovery: () => awiki.discardRecovery(),
18418
19545
  loadMoreConversations: () => awiki.loadMoreConversations(),
18419
19546
  retryGroupRebindRecovery: () => awiki.retryGroupRebindRecovery(),
19547
+ dismissGroupRecoveryNotice: () => awiki.dismissGroupRecoveryNotice(),
19548
+ hideConversation: (conversationId) => awiki.hideConversation(conversationId),
19549
+ restoreConversation: (conversationId) => awiki.restoreConversation(conversationId),
18420
19550
  startDirectChat: (handle) => awiki.startDirectChat(handle),
18421
19551
  createGroup: (name, members) => awiki.createGroup(name, members),
18422
19552
  joinGroup: (groupDid) => awiki.joinGroup(groupDid),
@@ -18460,7 +19590,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18460
19590
  },
18461
19591
  identity: awiki,
18462
19592
  models,
18463
- rechargeEnabled: false,
19593
+ rechargeEnabled: true,
18464
19594
  saveDomain: async (raw) => {
18465
19595
  const domain = normalizeAwikiDomain(raw);
18466
19596
  await settings.set(AWIKI_DOMAIN_FIELD, domain);
@@ -18499,7 +19629,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18499
19629
  identity: awiki,
18500
19630
  availability,
18501
19631
  models,
18502
- rechargeEnabled: false
19632
+ rechargeEnabled: true
18503
19633
  })
18504
19634
  }, AwikiOnboarding));
18505
19635
  } catch (error) {