@jtalk22/slack-mcp 1.2.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -61
- package/docs/CLOUDFLARE-BROWSER-TOOLKIT.md +67 -0
- package/docs/DEPLOYMENT-MODES.md +10 -3
- package/docs/HN-LAUNCH.md +45 -36
- package/docs/INDEX.md +9 -0
- package/docs/INSTALL-PROOF.md +18 -0
- package/docs/LAUNCH-COPY-v3.0.0.md +73 -0
- package/docs/LAUNCH-MATRIX.md +22 -0
- package/docs/LAUNCH-OPS.md +71 -0
- package/docs/RELEASE-HEALTH.md +24 -0
- package/docs/TROUBLESHOOTING.md +27 -0
- package/docs/WEB-API.md +13 -4
- package/docs/images/demo-channel-messages.png +0 -0
- package/docs/images/demo-channels.png +0 -0
- package/docs/images/demo-claude-mobile-360x800.png +0 -0
- package/docs/images/demo-claude-mobile-390x844.png +0 -0
- package/docs/images/demo-main-mobile-360x800.png +0 -0
- package/docs/images/demo-main-mobile-390x844.png +0 -0
- package/docs/images/demo-main.png +0 -0
- package/docs/images/demo-poster.png +0 -0
- package/docs/images/demo-sidebar.png +0 -0
- package/docs/images/web-api-mobile-360x800.png +0 -0
- package/docs/images/web-api-mobile-390x844.png +0 -0
- package/lib/handlers.js +14 -6
- package/lib/slack-client.js +17 -1
- package/package.json +28 -12
- package/public/demo-claude.html +83 -10
- package/public/demo-video.html +33 -4
- package/public/demo.html +136 -2
- package/public/index.html +132 -69
- package/scripts/capture-screenshots.js +103 -53
- package/scripts/check-version-parity.js +176 -0
- package/scripts/cloudflare-browser-tool.js +237 -0
- package/scripts/collect-release-health.js +1 -1
- package/scripts/record-demo.js +22 -9
- package/scripts/release-preflight.js +243 -0
- package/scripts/setup-wizard.js +12 -2
- package/scripts/verify-install-flow.js +38 -2
- package/scripts/verify-web.js +49 -1
- package/server.json +47 -0
- package/smithery.yaml +34 -0
- package/src/server-http.js +123 -8
- package/src/server.js +36 -8
- package/src/web-server.js +60 -20
- package/docs/images/demo-claude-v1.2.gif +0 -0
- package/docs/images/demo-readme.gif +0 -0
- package/docs/release-health/2026-02-25.md +0 -33
- package/docs/release-health/2026-02-26.md +0 -33
- package/docs/release-health/24h-delta.md +0 -21
- package/docs/release-health/24h-end.md +0 -33
- package/docs/release-health/24h-start.md +0 -33
- package/docs/release-health/latest.md +0 -33
- package/docs/videos/.gitkeep +0 -0
- package/docs/videos/demo-claude-v1.2.webm +0 -0
package/public/demo.html
CHANGED
|
@@ -22,9 +22,11 @@
|
|
|
22
22
|
<meta name="description" content="Session-based Slack access for Claude with your existing workspace permissions. Interactive demo for DMs, channels, search, and thread workflows.">
|
|
23
23
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
24
24
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
25
|
-
<link href="https://fonts.googleapis.com/css2?family=
|
|
25
|
+
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet">
|
|
26
26
|
<style>
|
|
27
27
|
:root {
|
|
28
|
+
--font-heading: "Space Grotesk", "Avenir Next", "Segoe UI", sans-serif;
|
|
29
|
+
--font-body: "IBM Plex Sans", "Inter", "Segoe UI", sans-serif;
|
|
28
30
|
--bg-primary: #0f0f1a;
|
|
29
31
|
--bg-secondary: #1a1a2e;
|
|
30
32
|
--bg-tertiary: #16213e;
|
|
@@ -45,7 +47,7 @@
|
|
|
45
47
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
46
48
|
|
|
47
49
|
body {
|
|
48
|
-
font-family:
|
|
50
|
+
font-family: var(--font-body);
|
|
49
51
|
background: var(--bg-primary);
|
|
50
52
|
color: var(--text-primary);
|
|
51
53
|
min-height: 100vh;
|
|
@@ -150,6 +152,7 @@
|
|
|
150
152
|
font-size: 16px;
|
|
151
153
|
font-weight: 600;
|
|
152
154
|
color: var(--text-primary);
|
|
155
|
+
font-family: var(--font-heading);
|
|
153
156
|
}
|
|
154
157
|
.claude-header .subtitle {
|
|
155
158
|
font-size: 12px;
|
|
@@ -276,6 +279,7 @@
|
|
|
276
279
|
letter-spacing: 1px;
|
|
277
280
|
color: var(--text-muted);
|
|
278
281
|
margin-bottom: 12px;
|
|
282
|
+
font-family: var(--font-heading);
|
|
279
283
|
}
|
|
280
284
|
|
|
281
285
|
.try-buttons .scenarios {
|
|
@@ -352,6 +356,7 @@
|
|
|
352
356
|
.dashboard-title h2 {
|
|
353
357
|
font-size: 18px;
|
|
354
358
|
font-weight: 600;
|
|
359
|
+
font-family: var(--font-heading);
|
|
355
360
|
}
|
|
356
361
|
|
|
357
362
|
.status-badge {
|
|
@@ -475,6 +480,7 @@
|
|
|
475
480
|
display: flex;
|
|
476
481
|
align-items: center;
|
|
477
482
|
gap: 8px;
|
|
483
|
+
font-family: var(--font-heading);
|
|
478
484
|
}
|
|
479
485
|
|
|
480
486
|
.online-dot {
|
|
@@ -490,6 +496,75 @@
|
|
|
490
496
|
padding: 20px 24px;
|
|
491
497
|
}
|
|
492
498
|
|
|
499
|
+
.mobile-scenario-rail {
|
|
500
|
+
display: none;
|
|
501
|
+
padding: 14px 16px;
|
|
502
|
+
background: rgba(15, 52, 96, 0.55);
|
|
503
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.mobile-rail-head {
|
|
507
|
+
display: flex;
|
|
508
|
+
align-items: center;
|
|
509
|
+
justify-content: space-between;
|
|
510
|
+
gap: 10px;
|
|
511
|
+
margin-bottom: 10px;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.mobile-rail-head h4 {
|
|
515
|
+
font-size: 12px;
|
|
516
|
+
letter-spacing: 0.08em;
|
|
517
|
+
text-transform: uppercase;
|
|
518
|
+
color: var(--text-muted);
|
|
519
|
+
font-family: var(--font-heading);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.mobile-scenario-buttons {
|
|
523
|
+
display: grid;
|
|
524
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
525
|
+
gap: 8px;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.mobile-scenario-btn {
|
|
529
|
+
background: rgba(255, 255, 255, 0.06);
|
|
530
|
+
color: var(--text-primary);
|
|
531
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
532
|
+
border-radius: 10px;
|
|
533
|
+
padding: 10px 8px;
|
|
534
|
+
font-size: 12px;
|
|
535
|
+
font-weight: 600;
|
|
536
|
+
display: flex;
|
|
537
|
+
flex-direction: column;
|
|
538
|
+
align-items: center;
|
|
539
|
+
justify-content: center;
|
|
540
|
+
gap: 3px;
|
|
541
|
+
cursor: pointer;
|
|
542
|
+
transition: var(--transition);
|
|
543
|
+
text-align: center;
|
|
544
|
+
font-family: var(--font-body);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.mobile-scenario-btn:hover {
|
|
548
|
+
border-color: var(--accent);
|
|
549
|
+
background: rgba(78, 205, 196, 0.15);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.mobile-scenario-btn .icon {
|
|
553
|
+
font-size: 16px;
|
|
554
|
+
line-height: 1;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.mobile-cta {
|
|
558
|
+
margin-top: 10px;
|
|
559
|
+
font-size: 12px;
|
|
560
|
+
color: var(--text-secondary);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
.mobile-reset {
|
|
564
|
+
padding: 4px 10px;
|
|
565
|
+
font-size: 11px;
|
|
566
|
+
}
|
|
567
|
+
|
|
493
568
|
.message {
|
|
494
569
|
display: flex;
|
|
495
570
|
gap: 14px;
|
|
@@ -614,16 +689,53 @@
|
|
|
614
689
|
@media (max-width: 1000px) {
|
|
615
690
|
.split-container {
|
|
616
691
|
grid-template-columns: 1fr;
|
|
692
|
+
height: auto;
|
|
693
|
+
min-height: calc(100vh - 88px);
|
|
617
694
|
}
|
|
618
695
|
.claude-panel {
|
|
619
696
|
display: none;
|
|
620
697
|
}
|
|
698
|
+
.mobile-scenario-rail {
|
|
699
|
+
display: block;
|
|
700
|
+
}
|
|
621
701
|
.dashboard-content {
|
|
622
702
|
grid-template-columns: 1fr;
|
|
623
703
|
}
|
|
624
704
|
.sidebar {
|
|
625
705
|
display: none;
|
|
626
706
|
}
|
|
707
|
+
.main-header {
|
|
708
|
+
padding: 14px 16px;
|
|
709
|
+
}
|
|
710
|
+
.messages-container {
|
|
711
|
+
padding: 16px;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
@media (max-width: 640px) {
|
|
716
|
+
.cta-strip {
|
|
717
|
+
gap: 8px;
|
|
718
|
+
padding: 10px 12px;
|
|
719
|
+
}
|
|
720
|
+
.mobile-scenario-buttons {
|
|
721
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
722
|
+
}
|
|
723
|
+
.mobile-scenario-btn {
|
|
724
|
+
padding: 10px 6px;
|
|
725
|
+
}
|
|
726
|
+
.dashboard-header {
|
|
727
|
+
padding: 14px 12px;
|
|
728
|
+
}
|
|
729
|
+
.dashboard-title h2 {
|
|
730
|
+
font-size: 16px;
|
|
731
|
+
}
|
|
732
|
+
.status-badge {
|
|
733
|
+
font-size: 11px;
|
|
734
|
+
padding: 3px 10px;
|
|
735
|
+
}
|
|
736
|
+
.messages-container {
|
|
737
|
+
min-height: 48vh;
|
|
738
|
+
}
|
|
627
739
|
}
|
|
628
740
|
</style>
|
|
629
741
|
</head>
|
|
@@ -706,6 +818,28 @@
|
|
|
706
818
|
</div>
|
|
707
819
|
</div>
|
|
708
820
|
|
|
821
|
+
<div class="mobile-scenario-rail" aria-label="Scenario shortcuts">
|
|
822
|
+
<div class="mobile-rail-head">
|
|
823
|
+
<h4>Try a Scenario</h4>
|
|
824
|
+
<button class="reset-btn mobile-reset" onclick="resetDemo()">Reset Demo</button>
|
|
825
|
+
</div>
|
|
826
|
+
<div class="mobile-scenario-buttons">
|
|
827
|
+
<button class="mobile-scenario-btn" onclick="runScenario('findKey')">
|
|
828
|
+
<span class="icon">🔑</span>
|
|
829
|
+
<span>Find Key</span>
|
|
830
|
+
</button>
|
|
831
|
+
<button class="mobile-scenario-btn" onclick="runScenario('listChannels')">
|
|
832
|
+
<span class="icon">📋</span>
|
|
833
|
+
<span>Channels</span>
|
|
834
|
+
</button>
|
|
835
|
+
<button class="mobile-scenario-btn" onclick="runScenario('whoIsAlex')">
|
|
836
|
+
<span class="icon">👤</span>
|
|
837
|
+
<span>Who is Alex?</span>
|
|
838
|
+
</button>
|
|
839
|
+
</div>
|
|
840
|
+
<p class="mobile-cta">Tap a scenario to drive the live preview with one click.</p>
|
|
841
|
+
</div>
|
|
842
|
+
|
|
709
843
|
<div class="dashboard-content">
|
|
710
844
|
<aside class="sidebar">
|
|
711
845
|
<div class="sidebar-section">
|
package/public/index.html
CHANGED
|
@@ -5,79 +5,92 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Slack Web API</title>
|
|
7
7
|
<style>
|
|
8
|
+
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap');
|
|
9
|
+
|
|
10
|
+
:root {
|
|
11
|
+
--font-heading: "Space Grotesk", "Avenir Next", "Segoe UI", sans-serif;
|
|
12
|
+
--font-body: "IBM Plex Sans", "Inter", "Segoe UI", sans-serif;
|
|
13
|
+
--bg: #0f1736;
|
|
14
|
+
--panel: #16213e;
|
|
15
|
+
--panel-alt: #0f3460;
|
|
16
|
+
--teal: #4ecdc4;
|
|
17
|
+
--teal-hover: #45b7aa;
|
|
18
|
+
--danger: #ff6b6b;
|
|
19
|
+
--search: #e94560;
|
|
20
|
+
--text: #e8ecff;
|
|
21
|
+
--muted: #9fb0cf;
|
|
22
|
+
}
|
|
23
|
+
|
|
8
24
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
9
25
|
body {
|
|
10
|
-
font-family: -
|
|
11
|
-
background: #
|
|
12
|
-
color:
|
|
26
|
+
font-family: var(--font-body);
|
|
27
|
+
background: radial-gradient(circle at 20% -10%, #1b2f67 0%, var(--bg) 48%);
|
|
28
|
+
color: var(--text);
|
|
13
29
|
min-height: 100vh;
|
|
14
30
|
padding: 20px;
|
|
31
|
+
overflow-x: hidden;
|
|
15
32
|
}
|
|
16
33
|
.container { max-width: 1200px; margin: 0 auto; }
|
|
17
|
-
h1 {
|
|
18
|
-
|
|
19
|
-
background: #16213e;
|
|
20
|
-
padding: 20px;
|
|
21
|
-
border-radius: 8px;
|
|
34
|
+
h1 {
|
|
35
|
+
color: var(--teal);
|
|
22
36
|
margin-bottom: 20px;
|
|
37
|
+
font-family: var(--font-heading);
|
|
38
|
+
font-size: clamp(1.9rem, 2vw, 2.35rem);
|
|
39
|
+
line-height: 1.1;
|
|
40
|
+
letter-spacing: -0.02em;
|
|
23
41
|
}
|
|
24
|
-
.auth-section input {
|
|
25
|
-
width: 300px;
|
|
26
|
-
padding: 10px;
|
|
27
|
-
border: none;
|
|
28
|
-
border-radius: 4px;
|
|
29
|
-
background: #0f3460;
|
|
30
|
-
color: #fff;
|
|
31
|
-
margin-right: 10px;
|
|
32
|
-
}
|
|
33
|
-
.auth-section button {
|
|
34
|
-
padding: 10px 20px;
|
|
35
|
-
background: #4ecdc4;
|
|
36
|
-
color: #1a1a2e;
|
|
37
|
-
border: none;
|
|
38
|
-
border-radius: 4px;
|
|
39
|
-
cursor: pointer;
|
|
40
|
-
font-weight: bold;
|
|
41
|
-
}
|
|
42
|
-
.auth-section button:hover { background: #45b7aa; }
|
|
43
42
|
.status { display: inline-block; margin-left: 15px; }
|
|
44
|
-
.status.ok { color:
|
|
45
|
-
.status.error { color:
|
|
46
|
-
.grid { display: grid; grid-template-columns:
|
|
43
|
+
.status.ok { color: var(--teal); }
|
|
44
|
+
.status.error { color: var(--danger); }
|
|
45
|
+
.grid { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 20px; }
|
|
47
46
|
.sidebar {
|
|
48
|
-
background:
|
|
49
|
-
border-radius:
|
|
47
|
+
background: var(--panel);
|
|
48
|
+
border-radius: 12px;
|
|
50
49
|
padding: 15px;
|
|
51
50
|
height: fit-content;
|
|
51
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
52
|
+
}
|
|
53
|
+
.sidebar h3 {
|
|
54
|
+
color: var(--teal);
|
|
55
|
+
margin-bottom: 15px;
|
|
56
|
+
font-size: 13px;
|
|
57
|
+
letter-spacing: 0.08em;
|
|
58
|
+
text-transform: uppercase;
|
|
59
|
+
font-family: var(--font-heading);
|
|
52
60
|
}
|
|
53
|
-
.sidebar h3 { color: #4ecdc4; margin-bottom: 15px; font-size: 14px; }
|
|
54
61
|
.conversation-list { list-style: none; }
|
|
55
62
|
.conversation-list li {
|
|
56
63
|
padding: 10px;
|
|
57
64
|
border-radius: 4px;
|
|
58
65
|
cursor: pointer;
|
|
59
66
|
margin-bottom: 5px;
|
|
60
|
-
background:
|
|
67
|
+
background: var(--panel-alt);
|
|
61
68
|
}
|
|
62
69
|
.conversation-list li:hover { background: #1a4a7a; }
|
|
63
|
-
.conversation-list li.active { background:
|
|
70
|
+
.conversation-list li.active { background: var(--teal); color: #1a1a2e; }
|
|
64
71
|
.conversation-list .type { font-size: 11px; opacity: 0.7; }
|
|
65
72
|
.main-panel {
|
|
66
|
-
background:
|
|
67
|
-
border-radius:
|
|
73
|
+
background: var(--panel);
|
|
74
|
+
border-radius: 12px;
|
|
68
75
|
padding: 20px;
|
|
69
76
|
min-height: 500px;
|
|
77
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
78
|
+
}
|
|
79
|
+
.main-panel h2 {
|
|
80
|
+
color: var(--teal);
|
|
81
|
+
margin-bottom: 15px;
|
|
82
|
+
font-family: var(--font-heading);
|
|
83
|
+
letter-spacing: -0.01em;
|
|
70
84
|
}
|
|
71
|
-
.main-panel h2 { color: #4ecdc4; margin-bottom: 15px; }
|
|
72
85
|
.messages { max-height: 400px; overflow-y: auto; margin-bottom: 15px; }
|
|
73
86
|
.message {
|
|
74
|
-
background:
|
|
87
|
+
background: var(--panel-alt);
|
|
75
88
|
padding: 12px;
|
|
76
89
|
border-radius: 8px;
|
|
77
90
|
margin-bottom: 10px;
|
|
78
91
|
}
|
|
79
92
|
.message .header { display: flex; justify-content: space-between; margin-bottom: 8px; }
|
|
80
|
-
.message .user { font-weight: bold; color:
|
|
93
|
+
.message .user { font-weight: bold; color: var(--teal); }
|
|
81
94
|
.message .time { font-size: 12px; opacity: 0.6; }
|
|
82
95
|
.message .text { line-height: 1.5; white-space: pre-wrap; }
|
|
83
96
|
.send-box { display: flex; gap: 10px; }
|
|
@@ -86,17 +99,19 @@
|
|
|
86
99
|
padding: 12px;
|
|
87
100
|
border: none;
|
|
88
101
|
border-radius: 4px;
|
|
89
|
-
background:
|
|
102
|
+
background: var(--panel-alt);
|
|
90
103
|
color: #fff;
|
|
104
|
+
min-width: 0;
|
|
91
105
|
}
|
|
92
106
|
.send-box button {
|
|
93
107
|
padding: 12px 24px;
|
|
94
|
-
background:
|
|
108
|
+
background: var(--teal);
|
|
95
109
|
color: #1a1a2e;
|
|
96
110
|
border: none;
|
|
97
111
|
border-radius: 4px;
|
|
98
112
|
cursor: pointer;
|
|
99
113
|
font-weight: bold;
|
|
114
|
+
white-space: nowrap;
|
|
100
115
|
}
|
|
101
116
|
.search-section { margin-bottom: 20px; display: flex; gap: 10px; }
|
|
102
117
|
.search-section input {
|
|
@@ -104,29 +119,31 @@
|
|
|
104
119
|
padding: 10px;
|
|
105
120
|
border: none;
|
|
106
121
|
border-radius: 4px;
|
|
107
|
-
background:
|
|
122
|
+
background: var(--panel-alt);
|
|
108
123
|
color: #fff;
|
|
124
|
+
min-width: 0;
|
|
109
125
|
}
|
|
110
126
|
.search-section button {
|
|
111
127
|
padding: 10px 20px;
|
|
112
|
-
background:
|
|
128
|
+
background: var(--search);
|
|
113
129
|
color: #fff;
|
|
114
130
|
border: none;
|
|
115
131
|
border-radius: 4px;
|
|
116
132
|
cursor: pointer;
|
|
133
|
+
white-space: nowrap;
|
|
117
134
|
}
|
|
118
|
-
.loading { text-align: center; padding: 40px; opacity: 0.6; }
|
|
119
|
-
.error-msg { background: #ff6b6b22; color:
|
|
135
|
+
.loading { text-align: center; padding: 40px; opacity: 0.6; color: var(--muted); }
|
|
136
|
+
.error-msg { background: #ff6b6b22; color: var(--danger); padding: 15px; border-radius: 8px; }
|
|
120
137
|
.tabs { display: flex; gap: 5px; margin-bottom: 15px; }
|
|
121
138
|
.tabs button {
|
|
122
139
|
padding: 8px 16px;
|
|
123
|
-
background:
|
|
140
|
+
background: var(--panel-alt);
|
|
124
141
|
color: #fff;
|
|
125
142
|
border: none;
|
|
126
143
|
border-radius: 4px;
|
|
127
144
|
cursor: pointer;
|
|
128
145
|
}
|
|
129
|
-
.tabs button.active { background:
|
|
146
|
+
.tabs button.active { background: var(--teal); color: #1a1a2e; }
|
|
130
147
|
/* Auth Modal */
|
|
131
148
|
.modal-overlay {
|
|
132
149
|
position: fixed;
|
|
@@ -139,36 +156,43 @@
|
|
|
139
156
|
}
|
|
140
157
|
.modal-overlay.hidden { display: none; }
|
|
141
158
|
.modal {
|
|
142
|
-
background:
|
|
143
|
-
padding:
|
|
159
|
+
background: var(--panel);
|
|
160
|
+
padding: 36px;
|
|
144
161
|
border-radius: 12px;
|
|
145
|
-
|
|
162
|
+
width: min(92vw, 460px);
|
|
146
163
|
text-align: center;
|
|
147
|
-
border: 2px solid
|
|
164
|
+
border: 2px solid var(--teal);
|
|
165
|
+
max-height: calc(100vh - 40px);
|
|
166
|
+
overflow-y: auto;
|
|
167
|
+
}
|
|
168
|
+
.modal h2 {
|
|
169
|
+
color: var(--teal);
|
|
170
|
+
margin-bottom: 20px;
|
|
171
|
+
font-family: var(--font-heading);
|
|
172
|
+
letter-spacing: -0.01em;
|
|
148
173
|
}
|
|
149
|
-
.modal
|
|
150
|
-
.modal p { color: #aaa; margin-bottom: 25px; line-height: 1.6; }
|
|
174
|
+
.modal p { color: #c2c7d6; margin-bottom: 25px; line-height: 1.6; }
|
|
151
175
|
.modal code {
|
|
152
|
-
background:
|
|
176
|
+
background: var(--panel-alt);
|
|
153
177
|
padding: 3px 8px;
|
|
154
178
|
border-radius: 4px;
|
|
155
|
-
color:
|
|
179
|
+
color: var(--teal);
|
|
156
180
|
}
|
|
157
181
|
.modal input {
|
|
158
182
|
width: 100%;
|
|
159
183
|
padding: 14px;
|
|
160
|
-
border: 2px solid
|
|
184
|
+
border: 2px solid var(--panel-alt);
|
|
161
185
|
border-radius: 6px;
|
|
162
|
-
background:
|
|
186
|
+
background: var(--panel-alt);
|
|
163
187
|
color: #fff;
|
|
164
188
|
font-size: 14px;
|
|
165
189
|
margin-bottom: 15px;
|
|
166
190
|
}
|
|
167
|
-
.modal input:focus { border-color:
|
|
191
|
+
.modal input:focus { border-color: var(--teal); outline: none; }
|
|
168
192
|
.modal button {
|
|
169
193
|
width: 100%;
|
|
170
194
|
padding: 14px;
|
|
171
|
-
background:
|
|
195
|
+
background: var(--teal);
|
|
172
196
|
color: #1a1a2e;
|
|
173
197
|
border: none;
|
|
174
198
|
border-radius: 6px;
|
|
@@ -176,8 +200,44 @@
|
|
|
176
200
|
font-weight: bold;
|
|
177
201
|
font-size: 16px;
|
|
178
202
|
}
|
|
179
|
-
.modal button:hover { background:
|
|
180
|
-
.modal .error { color:
|
|
203
|
+
.modal button:hover { background: var(--teal-hover); }
|
|
204
|
+
.modal .error { color: var(--danger); margin-top: 10px; font-size: 14px; }
|
|
205
|
+
|
|
206
|
+
@media (max-width: 960px) {
|
|
207
|
+
body { padding: 16px; }
|
|
208
|
+
.grid { grid-template-columns: minmax(0, 1fr); }
|
|
209
|
+
.sidebar, .main-panel { padding: 16px; }
|
|
210
|
+
.messages { max-height: 50vh; }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@media (max-width: 640px) {
|
|
214
|
+
body { padding: 12px; }
|
|
215
|
+
h1 {
|
|
216
|
+
display: flex;
|
|
217
|
+
flex-direction: column;
|
|
218
|
+
gap: 8px;
|
|
219
|
+
}
|
|
220
|
+
.status {
|
|
221
|
+
margin-left: 0;
|
|
222
|
+
font-size: 14px;
|
|
223
|
+
}
|
|
224
|
+
.tabs {
|
|
225
|
+
display: grid;
|
|
226
|
+
grid-template-columns: 1fr 1fr;
|
|
227
|
+
}
|
|
228
|
+
.search-section,
|
|
229
|
+
.send-box {
|
|
230
|
+
flex-direction: column;
|
|
231
|
+
}
|
|
232
|
+
.search-section button,
|
|
233
|
+
.send-box button {
|
|
234
|
+
width: 100%;
|
|
235
|
+
}
|
|
236
|
+
.modal {
|
|
237
|
+
width: min(92vw, 460px);
|
|
238
|
+
padding: 24px 18px;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
181
241
|
</style>
|
|
182
242
|
</head>
|
|
183
243
|
<body>
|
|
@@ -198,8 +258,8 @@
|
|
|
198
258
|
<div class="sidebar">
|
|
199
259
|
<h3>CONVERSATIONS</h3>
|
|
200
260
|
<div class="tabs">
|
|
201
|
-
<button class="active" onclick="loadConversations('im,mpim')">DMs</button>
|
|
202
|
-
<button onclick="loadConversations('public_channel,private_channel')">Channels</button>
|
|
261
|
+
<button class="active" onclick="loadConversations('im,mpim', this)">DMs</button>
|
|
262
|
+
<button onclick="loadConversations('public_channel,private_channel', this)">Channels</button>
|
|
203
263
|
</div>
|
|
204
264
|
<ul id="conversationList" class="conversation-list">
|
|
205
265
|
<li class="loading">Enter API key to connect</li>
|
|
@@ -306,23 +366,26 @@
|
|
|
306
366
|
}
|
|
307
367
|
}
|
|
308
368
|
}
|
|
309
|
-
async function loadConversations(types) {
|
|
369
|
+
async function loadConversations(types, sourceButton = null) {
|
|
310
370
|
const list = document.getElementById('conversationList');
|
|
311
371
|
list.innerHTML = '<li class="loading">Loading...</li>';
|
|
312
372
|
document.querySelectorAll('.tabs button').forEach(b => b.classList.remove('active'));
|
|
313
|
-
if (
|
|
373
|
+
if (!sourceButton) {
|
|
374
|
+
sourceButton = document.querySelector('.tabs button:first-child');
|
|
375
|
+
}
|
|
376
|
+
if (sourceButton) sourceButton.classList.add('active');
|
|
314
377
|
try {
|
|
315
378
|
const data = await api('/conversations?types=' + types);
|
|
316
379
|
list.innerHTML = data.conversations.map(c =>
|
|
317
|
-
'<li onclick="loadHistory(\'' + c.id + '\', \'' + c.name.replace(/'/g, "\\'") + '\')"><div>' + c.name + '</div><div class="type">' + c.type + '</div></li>'
|
|
380
|
+
'<li onclick="loadHistory(\'' + c.id + '\', \'' + c.name.replace(/'/g, "\\'") + '\', this)"><div>' + c.name + '</div><div class="type">' + c.type + '</div></li>'
|
|
318
381
|
).join('');
|
|
319
382
|
} catch (e) { list.innerHTML = '<li class="error-msg">' + e.message + '</li>'; }
|
|
320
383
|
}
|
|
321
|
-
async function loadHistory(channelId, name) {
|
|
384
|
+
async function loadHistory(channelId, name, sourceItem = null) {
|
|
322
385
|
currentChannel = channelId;
|
|
323
386
|
document.getElementById('channelName').textContent = name;
|
|
324
387
|
document.querySelectorAll('.conversation-list li').forEach(li => li.classList.remove('active'));
|
|
325
|
-
|
|
388
|
+
if (sourceItem) sourceItem.classList.add('active');
|
|
326
389
|
const container = document.getElementById('messages');
|
|
327
390
|
container.innerHTML = '<div class="loading">Loading messages...</div>';
|
|
328
391
|
try {
|