@followgate/js 0.8.1 → 0.9.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/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +80 -9
- package/dist/index.mjs +80 -9
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -83,6 +83,8 @@ interface VerificationStatus {
|
|
|
83
83
|
*/
|
|
84
84
|
declare class FollowGateClient {
|
|
85
85
|
private config;
|
|
86
|
+
private serverConfig;
|
|
87
|
+
private configFetched;
|
|
86
88
|
private listeners;
|
|
87
89
|
private currentUser;
|
|
88
90
|
private completedActions;
|
|
@@ -92,11 +94,15 @@ declare class FollowGateClient {
|
|
|
92
94
|
* Initialize the SDK
|
|
93
95
|
*/
|
|
94
96
|
init(config: FollowGateConfig): void;
|
|
97
|
+
/**
|
|
98
|
+
* Fetch app configuration from server
|
|
99
|
+
*/
|
|
100
|
+
private fetchServerConfig;
|
|
95
101
|
/**
|
|
96
102
|
* Show the FollowGate modal
|
|
97
103
|
* If user is already unlocked, calls onComplete immediately
|
|
98
104
|
*/
|
|
99
|
-
show(): void
|
|
105
|
+
show(): Promise<void>;
|
|
100
106
|
/**
|
|
101
107
|
* Hide the modal
|
|
102
108
|
*/
|
|
@@ -107,6 +113,7 @@ declare class FollowGateClient {
|
|
|
107
113
|
private renderUsernameStep;
|
|
108
114
|
private handleUsernameSubmit;
|
|
109
115
|
private renderFollowStep;
|
|
116
|
+
private handleSkipFollow;
|
|
110
117
|
private handleFollowClick;
|
|
111
118
|
private showFollowConfirmation;
|
|
112
119
|
private handleFollowConfirm;
|
package/dist/index.d.ts
CHANGED
|
@@ -83,6 +83,8 @@ interface VerificationStatus {
|
|
|
83
83
|
*/
|
|
84
84
|
declare class FollowGateClient {
|
|
85
85
|
private config;
|
|
86
|
+
private serverConfig;
|
|
87
|
+
private configFetched;
|
|
86
88
|
private listeners;
|
|
87
89
|
private currentUser;
|
|
88
90
|
private completedActions;
|
|
@@ -92,11 +94,15 @@ declare class FollowGateClient {
|
|
|
92
94
|
* Initialize the SDK
|
|
93
95
|
*/
|
|
94
96
|
init(config: FollowGateConfig): void;
|
|
97
|
+
/**
|
|
98
|
+
* Fetch app configuration from server
|
|
99
|
+
*/
|
|
100
|
+
private fetchServerConfig;
|
|
95
101
|
/**
|
|
96
102
|
* Show the FollowGate modal
|
|
97
103
|
* If user is already unlocked, calls onComplete immediately
|
|
98
104
|
*/
|
|
99
|
-
show(): void
|
|
105
|
+
show(): Promise<void>;
|
|
100
106
|
/**
|
|
101
107
|
* Hide the modal
|
|
102
108
|
*/
|
|
@@ -107,6 +113,7 @@ declare class FollowGateClient {
|
|
|
107
113
|
private renderUsernameStep;
|
|
108
114
|
private handleUsernameSubmit;
|
|
109
115
|
private renderFollowStep;
|
|
116
|
+
private handleSkipFollow;
|
|
110
117
|
private handleFollowClick;
|
|
111
118
|
private showFollowConfirmation;
|
|
112
119
|
private handleFollowConfirm;
|
package/dist/index.js
CHANGED
|
@@ -313,32 +313,35 @@ var MODAL_STYLES = `
|
|
|
313
313
|
background: rgba(59, 130, 246, 0.05);
|
|
314
314
|
border: 1px solid rgba(96, 165, 250, 0.5);
|
|
315
315
|
border-radius: 12px;
|
|
316
|
-
padding:
|
|
316
|
+
padding: 10px 14px;
|
|
317
317
|
margin-bottom: 8px;
|
|
318
318
|
display: flex;
|
|
319
319
|
align-items: center;
|
|
320
320
|
justify-content: space-between;
|
|
321
|
-
gap:
|
|
321
|
+
gap: 10px;
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
.fg-verify-box-left {
|
|
325
325
|
display: flex;
|
|
326
326
|
align-items: center;
|
|
327
327
|
gap: 8px;
|
|
328
|
+
flex-shrink: 0;
|
|
328
329
|
}
|
|
329
330
|
|
|
330
331
|
.fg-verify-spinner {
|
|
331
|
-
width:
|
|
332
|
-
height:
|
|
332
|
+
width: 18px;
|
|
333
|
+
height: 18px;
|
|
333
334
|
border: 2px solid rgba(96, 165, 250, 0.3);
|
|
334
335
|
border-top-color: #60a5fa;
|
|
335
336
|
border-radius: 50%;
|
|
336
337
|
animation: fg-spin 1s linear infinite;
|
|
338
|
+
flex-shrink: 0;
|
|
337
339
|
}
|
|
338
340
|
|
|
339
341
|
.fg-verify-text {
|
|
340
|
-
font-size:
|
|
342
|
+
font-size: 13px;
|
|
341
343
|
color: #93c5fd;
|
|
344
|
+
white-space: nowrap;
|
|
342
345
|
}
|
|
343
346
|
|
|
344
347
|
.fg-verify-hint {
|
|
@@ -349,6 +352,20 @@ var MODAL_STYLES = `
|
|
|
349
352
|
margin-top: 2px;
|
|
350
353
|
}
|
|
351
354
|
|
|
355
|
+
.fg-skip-link {
|
|
356
|
+
display: block;
|
|
357
|
+
text-align: center;
|
|
358
|
+
font-size: 12px;
|
|
359
|
+
color: #64748b;
|
|
360
|
+
margin-top: 16px;
|
|
361
|
+
cursor: pointer;
|
|
362
|
+
transition: color 0.2s;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.fg-skip-link:hover {
|
|
366
|
+
color: #94a3b8;
|
|
367
|
+
}
|
|
368
|
+
|
|
352
369
|
.fg-warning-box p {
|
|
353
370
|
font-size: 14px;
|
|
354
371
|
color: #fde68a;
|
|
@@ -447,6 +464,8 @@ var ICONS = {
|
|
|
447
464
|
};
|
|
448
465
|
var FollowGateClient = class {
|
|
449
466
|
config = null;
|
|
467
|
+
serverConfig = null;
|
|
468
|
+
configFetched = false;
|
|
450
469
|
listeners = /* @__PURE__ */ new Map();
|
|
451
470
|
currentUser = null;
|
|
452
471
|
completedActions = [];
|
|
@@ -508,11 +527,46 @@ var FollowGateClient = class {
|
|
|
508
527
|
// ============================================
|
|
509
528
|
// Modal UI Methods
|
|
510
529
|
// ============================================
|
|
530
|
+
/**
|
|
531
|
+
* Fetch app configuration from server
|
|
532
|
+
*/
|
|
533
|
+
async fetchServerConfig() {
|
|
534
|
+
if (!this.config || this.configFetched) return;
|
|
535
|
+
try {
|
|
536
|
+
const response = await fetch(`${this.config.apiUrl}/api/v1/config`, {
|
|
537
|
+
headers: {
|
|
538
|
+
Authorization: `Bearer ${this.config.apiKey}`
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
if (response.ok) {
|
|
542
|
+
const data = await response.json();
|
|
543
|
+
if (data.success && data.data) {
|
|
544
|
+
this.serverConfig = data.data;
|
|
545
|
+
if (this.config.debug) {
|
|
546
|
+
console.log(
|
|
547
|
+
"[FollowGate] Server config loaded:",
|
|
548
|
+
this.serverConfig
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
} else if (this.config.debug) {
|
|
553
|
+
console.warn(
|
|
554
|
+
"[FollowGate] Failed to fetch server config:",
|
|
555
|
+
response.status
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
} catch (error) {
|
|
559
|
+
if (this.config.debug) {
|
|
560
|
+
console.warn("[FollowGate] Failed to fetch server config:", error);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
this.configFetched = true;
|
|
564
|
+
}
|
|
511
565
|
/**
|
|
512
566
|
* Show the FollowGate modal
|
|
513
567
|
* If user is already unlocked, calls onComplete immediately
|
|
514
568
|
*/
|
|
515
|
-
show() {
|
|
569
|
+
async show() {
|
|
516
570
|
if (!this.config) {
|
|
517
571
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
518
572
|
}
|
|
@@ -523,6 +577,7 @@ var FollowGateClient = class {
|
|
|
523
577
|
this.config.onComplete?.();
|
|
524
578
|
return;
|
|
525
579
|
}
|
|
580
|
+
await this.fetchServerConfig();
|
|
526
581
|
this.injectStyles();
|
|
527
582
|
this.createModal();
|
|
528
583
|
}
|
|
@@ -652,10 +707,22 @@ var FollowGateClient = class {
|
|
|
652
707
|
</button>
|
|
653
708
|
</div>
|
|
654
709
|
<p class="fg-hint">A new window will open. Return here after following.</p>
|
|
710
|
+
${this.serverConfig?.allowSkip ? '<span class="fg-skip-link" id="fg-skip-follow">skip this step</span>' : ""}
|
|
655
711
|
`;
|
|
656
712
|
document.getElementById("fg-follow-btn")?.addEventListener("click", () => {
|
|
657
713
|
this.handleFollowClick();
|
|
658
714
|
});
|
|
715
|
+
document.getElementById("fg-skip-follow")?.addEventListener("click", () => {
|
|
716
|
+
this.handleSkipFollow();
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
handleSkipFollow() {
|
|
720
|
+
if (!this.config?.twitter) return;
|
|
721
|
+
if (this.config.twitter.tweetId) {
|
|
722
|
+
this.renderRepostStep();
|
|
723
|
+
} else {
|
|
724
|
+
this.renderConfirmStep();
|
|
725
|
+
}
|
|
659
726
|
}
|
|
660
727
|
handleFollowClick() {
|
|
661
728
|
if (!this.config?.twitter) return;
|
|
@@ -751,10 +818,14 @@ var FollowGateClient = class {
|
|
|
751
818
|
</button>
|
|
752
819
|
</div>
|
|
753
820
|
<p class="fg-hint">A new window will open. Return here after reposting.</p>
|
|
821
|
+
${this.serverConfig?.allowSkip ? '<span class="fg-skip-link" id="fg-skip-repost">skip this step</span>' : ""}
|
|
754
822
|
`;
|
|
755
823
|
document.getElementById("fg-repost-btn")?.addEventListener("click", () => {
|
|
756
824
|
this.handleRepostClick();
|
|
757
825
|
});
|
|
826
|
+
document.getElementById("fg-skip-repost")?.addEventListener("click", () => {
|
|
827
|
+
this.renderConfirmStep();
|
|
828
|
+
});
|
|
758
829
|
}
|
|
759
830
|
handleRepostClick() {
|
|
760
831
|
if (!this.config?.twitter?.tweetId) return;
|
|
@@ -832,9 +903,9 @@ var FollowGateClient = class {
|
|
|
832
903
|
<span class="fg-verify-text">Verifying follow & repost</span>
|
|
833
904
|
</div>
|
|
834
905
|
${username ? `
|
|
835
|
-
<div class="fg-user-badge" style="margin: 0;">
|
|
836
|
-
<div class="fg-user-badge-dot" style="background: #facc15;"></div>
|
|
837
|
-
<span class="fg-user-badge-text">@${username}</span>
|
|
906
|
+
<div class="fg-user-badge" style="margin: 0; padding: 4px 10px; gap: 6px;">
|
|
907
|
+
<div class="fg-user-badge-dot" style="background: #facc15; width: 6px; height: 6px;"></div>
|
|
908
|
+
<span class="fg-user-badge-text" style="font-size: 12px;">@${username}</span>
|
|
838
909
|
</div>
|
|
839
910
|
` : ""}
|
|
840
911
|
</div>
|
package/dist/index.mjs
CHANGED
|
@@ -287,32 +287,35 @@ var MODAL_STYLES = `
|
|
|
287
287
|
background: rgba(59, 130, 246, 0.05);
|
|
288
288
|
border: 1px solid rgba(96, 165, 250, 0.5);
|
|
289
289
|
border-radius: 12px;
|
|
290
|
-
padding:
|
|
290
|
+
padding: 10px 14px;
|
|
291
291
|
margin-bottom: 8px;
|
|
292
292
|
display: flex;
|
|
293
293
|
align-items: center;
|
|
294
294
|
justify-content: space-between;
|
|
295
|
-
gap:
|
|
295
|
+
gap: 10px;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
.fg-verify-box-left {
|
|
299
299
|
display: flex;
|
|
300
300
|
align-items: center;
|
|
301
301
|
gap: 8px;
|
|
302
|
+
flex-shrink: 0;
|
|
302
303
|
}
|
|
303
304
|
|
|
304
305
|
.fg-verify-spinner {
|
|
305
|
-
width:
|
|
306
|
-
height:
|
|
306
|
+
width: 18px;
|
|
307
|
+
height: 18px;
|
|
307
308
|
border: 2px solid rgba(96, 165, 250, 0.3);
|
|
308
309
|
border-top-color: #60a5fa;
|
|
309
310
|
border-radius: 50%;
|
|
310
311
|
animation: fg-spin 1s linear infinite;
|
|
312
|
+
flex-shrink: 0;
|
|
311
313
|
}
|
|
312
314
|
|
|
313
315
|
.fg-verify-text {
|
|
314
|
-
font-size:
|
|
316
|
+
font-size: 13px;
|
|
315
317
|
color: #93c5fd;
|
|
318
|
+
white-space: nowrap;
|
|
316
319
|
}
|
|
317
320
|
|
|
318
321
|
.fg-verify-hint {
|
|
@@ -323,6 +326,20 @@ var MODAL_STYLES = `
|
|
|
323
326
|
margin-top: 2px;
|
|
324
327
|
}
|
|
325
328
|
|
|
329
|
+
.fg-skip-link {
|
|
330
|
+
display: block;
|
|
331
|
+
text-align: center;
|
|
332
|
+
font-size: 12px;
|
|
333
|
+
color: #64748b;
|
|
334
|
+
margin-top: 16px;
|
|
335
|
+
cursor: pointer;
|
|
336
|
+
transition: color 0.2s;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.fg-skip-link:hover {
|
|
340
|
+
color: #94a3b8;
|
|
341
|
+
}
|
|
342
|
+
|
|
326
343
|
.fg-warning-box p {
|
|
327
344
|
font-size: 14px;
|
|
328
345
|
color: #fde68a;
|
|
@@ -421,6 +438,8 @@ var ICONS = {
|
|
|
421
438
|
};
|
|
422
439
|
var FollowGateClient = class {
|
|
423
440
|
config = null;
|
|
441
|
+
serverConfig = null;
|
|
442
|
+
configFetched = false;
|
|
424
443
|
listeners = /* @__PURE__ */ new Map();
|
|
425
444
|
currentUser = null;
|
|
426
445
|
completedActions = [];
|
|
@@ -482,11 +501,46 @@ var FollowGateClient = class {
|
|
|
482
501
|
// ============================================
|
|
483
502
|
// Modal UI Methods
|
|
484
503
|
// ============================================
|
|
504
|
+
/**
|
|
505
|
+
* Fetch app configuration from server
|
|
506
|
+
*/
|
|
507
|
+
async fetchServerConfig() {
|
|
508
|
+
if (!this.config || this.configFetched) return;
|
|
509
|
+
try {
|
|
510
|
+
const response = await fetch(`${this.config.apiUrl}/api/v1/config`, {
|
|
511
|
+
headers: {
|
|
512
|
+
Authorization: `Bearer ${this.config.apiKey}`
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
if (response.ok) {
|
|
516
|
+
const data = await response.json();
|
|
517
|
+
if (data.success && data.data) {
|
|
518
|
+
this.serverConfig = data.data;
|
|
519
|
+
if (this.config.debug) {
|
|
520
|
+
console.log(
|
|
521
|
+
"[FollowGate] Server config loaded:",
|
|
522
|
+
this.serverConfig
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
} else if (this.config.debug) {
|
|
527
|
+
console.warn(
|
|
528
|
+
"[FollowGate] Failed to fetch server config:",
|
|
529
|
+
response.status
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
} catch (error) {
|
|
533
|
+
if (this.config.debug) {
|
|
534
|
+
console.warn("[FollowGate] Failed to fetch server config:", error);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
this.configFetched = true;
|
|
538
|
+
}
|
|
485
539
|
/**
|
|
486
540
|
* Show the FollowGate modal
|
|
487
541
|
* If user is already unlocked, calls onComplete immediately
|
|
488
542
|
*/
|
|
489
|
-
show() {
|
|
543
|
+
async show() {
|
|
490
544
|
if (!this.config) {
|
|
491
545
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
492
546
|
}
|
|
@@ -497,6 +551,7 @@ var FollowGateClient = class {
|
|
|
497
551
|
this.config.onComplete?.();
|
|
498
552
|
return;
|
|
499
553
|
}
|
|
554
|
+
await this.fetchServerConfig();
|
|
500
555
|
this.injectStyles();
|
|
501
556
|
this.createModal();
|
|
502
557
|
}
|
|
@@ -626,10 +681,22 @@ var FollowGateClient = class {
|
|
|
626
681
|
</button>
|
|
627
682
|
</div>
|
|
628
683
|
<p class="fg-hint">A new window will open. Return here after following.</p>
|
|
684
|
+
${this.serverConfig?.allowSkip ? '<span class="fg-skip-link" id="fg-skip-follow">skip this step</span>' : ""}
|
|
629
685
|
`;
|
|
630
686
|
document.getElementById("fg-follow-btn")?.addEventListener("click", () => {
|
|
631
687
|
this.handleFollowClick();
|
|
632
688
|
});
|
|
689
|
+
document.getElementById("fg-skip-follow")?.addEventListener("click", () => {
|
|
690
|
+
this.handleSkipFollow();
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
handleSkipFollow() {
|
|
694
|
+
if (!this.config?.twitter) return;
|
|
695
|
+
if (this.config.twitter.tweetId) {
|
|
696
|
+
this.renderRepostStep();
|
|
697
|
+
} else {
|
|
698
|
+
this.renderConfirmStep();
|
|
699
|
+
}
|
|
633
700
|
}
|
|
634
701
|
handleFollowClick() {
|
|
635
702
|
if (!this.config?.twitter) return;
|
|
@@ -725,10 +792,14 @@ var FollowGateClient = class {
|
|
|
725
792
|
</button>
|
|
726
793
|
</div>
|
|
727
794
|
<p class="fg-hint">A new window will open. Return here after reposting.</p>
|
|
795
|
+
${this.serverConfig?.allowSkip ? '<span class="fg-skip-link" id="fg-skip-repost">skip this step</span>' : ""}
|
|
728
796
|
`;
|
|
729
797
|
document.getElementById("fg-repost-btn")?.addEventListener("click", () => {
|
|
730
798
|
this.handleRepostClick();
|
|
731
799
|
});
|
|
800
|
+
document.getElementById("fg-skip-repost")?.addEventListener("click", () => {
|
|
801
|
+
this.renderConfirmStep();
|
|
802
|
+
});
|
|
732
803
|
}
|
|
733
804
|
handleRepostClick() {
|
|
734
805
|
if (!this.config?.twitter?.tweetId) return;
|
|
@@ -806,9 +877,9 @@ var FollowGateClient = class {
|
|
|
806
877
|
<span class="fg-verify-text">Verifying follow & repost</span>
|
|
807
878
|
</div>
|
|
808
879
|
${username ? `
|
|
809
|
-
<div class="fg-user-badge" style="margin: 0;">
|
|
810
|
-
<div class="fg-user-badge-dot" style="background: #facc15;"></div>
|
|
811
|
-
<span class="fg-user-badge-text">@${username}</span>
|
|
880
|
+
<div class="fg-user-badge" style="margin: 0; padding: 4px 10px; gap: 6px;">
|
|
881
|
+
<div class="fg-user-badge-dot" style="background: #facc15; width: 6px; height: 6px;"></div>
|
|
882
|
+
<span class="fg-user-badge-text" style="font-size: 12px;">@${username}</span>
|
|
812
883
|
</div>
|
|
813
884
|
` : ""}
|
|
814
885
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@followgate/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "FollowGate SDK - Grow your audience with every download. Require social actions (follow, repost) before users can access your app.",
|
|
5
5
|
"author": "FollowGate <hello@followgate.app>",
|
|
6
6
|
"homepage": "https://followgate.app",
|