@followgate/js 0.11.0 → 0.12.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 +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +73 -14
- package/dist/index.mjs +73 -14
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -10,7 +10,8 @@ type SocialAction = 'follow' | 'repost' | 'like';
|
|
|
10
10
|
* Twitter/X configuration
|
|
11
11
|
*/
|
|
12
12
|
interface TwitterConfig {
|
|
13
|
-
handle
|
|
13
|
+
handle?: string;
|
|
14
|
+
overrideHandle?: string;
|
|
14
15
|
tweetId?: string;
|
|
15
16
|
username?: string;
|
|
16
17
|
}
|
|
@@ -112,6 +113,13 @@ declare class FollowGateClient {
|
|
|
112
113
|
private injectStyles;
|
|
113
114
|
private createModal;
|
|
114
115
|
private getContentElement;
|
|
116
|
+
/**
|
|
117
|
+
* Get target handle with priority:
|
|
118
|
+
* 1. config.twitter.overrideHandle (explicit override)
|
|
119
|
+
* 2. serverConfig.targetHandle (from Dashboard)
|
|
120
|
+
* 3. config.twitter.handle (legacy fallback, deprecated)
|
|
121
|
+
*/
|
|
122
|
+
private getTargetHandle;
|
|
115
123
|
private renderUsernameStep;
|
|
116
124
|
private handleUsernameSubmit;
|
|
117
125
|
private renderFollowStep;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,8 @@ type SocialAction = 'follow' | 'repost' | 'like';
|
|
|
10
10
|
* Twitter/X configuration
|
|
11
11
|
*/
|
|
12
12
|
interface TwitterConfig {
|
|
13
|
-
handle
|
|
13
|
+
handle?: string;
|
|
14
|
+
overrideHandle?: string;
|
|
14
15
|
tweetId?: string;
|
|
15
16
|
username?: string;
|
|
16
17
|
}
|
|
@@ -112,6 +113,13 @@ declare class FollowGateClient {
|
|
|
112
113
|
private injectStyles;
|
|
113
114
|
private createModal;
|
|
114
115
|
private getContentElement;
|
|
116
|
+
/**
|
|
117
|
+
* Get target handle with priority:
|
|
118
|
+
* 1. config.twitter.overrideHandle (explicit override)
|
|
119
|
+
* 2. serverConfig.targetHandle (from Dashboard)
|
|
120
|
+
* 3. config.twitter.handle (legacy fallback, deprecated)
|
|
121
|
+
*/
|
|
122
|
+
private getTargetHandle;
|
|
115
123
|
private renderUsernameStep;
|
|
116
124
|
private handleUsernameSubmit;
|
|
117
125
|
private renderFollowStep;
|
package/dist/index.js
CHANGED
|
@@ -446,6 +446,35 @@ var MODAL_STYLES = `
|
|
|
446
446
|
color: #94a3b8;
|
|
447
447
|
}
|
|
448
448
|
|
|
449
|
+
.fg-close-btn {
|
|
450
|
+
position: absolute;
|
|
451
|
+
top: 16px;
|
|
452
|
+
right: 16px;
|
|
453
|
+
width: 32px;
|
|
454
|
+
height: 32px;
|
|
455
|
+
border-radius: 8px;
|
|
456
|
+
background: transparent;
|
|
457
|
+
border: 1px solid #334155;
|
|
458
|
+
color: #64748b;
|
|
459
|
+
cursor: pointer;
|
|
460
|
+
display: flex;
|
|
461
|
+
align-items: center;
|
|
462
|
+
justify-content: center;
|
|
463
|
+
transition: all 0.2s;
|
|
464
|
+
padding: 0;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.fg-close-btn:hover {
|
|
468
|
+
background: #1e293b;
|
|
469
|
+
color: #94a3b8;
|
|
470
|
+
border-color: #475569;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.fg-close-btn svg {
|
|
474
|
+
width: 16px;
|
|
475
|
+
height: 16px;
|
|
476
|
+
}
|
|
477
|
+
|
|
449
478
|
.fg-btn-row {
|
|
450
479
|
display: flex;
|
|
451
480
|
gap: 8px;
|
|
@@ -462,7 +491,8 @@ var ICONS = {
|
|
|
462
491
|
x: '<svg viewBox="0 0 24 24"><path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>',
|
|
463
492
|
check: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>',
|
|
464
493
|
repost: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>',
|
|
465
|
-
warning: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>'
|
|
494
|
+
warning: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>',
|
|
495
|
+
close: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>'
|
|
466
496
|
};
|
|
467
497
|
var FollowGateClient = class {
|
|
468
498
|
config = null;
|
|
@@ -635,6 +665,9 @@ var FollowGateClient = class {
|
|
|
635
665
|
backdrop.className = "fg-modal-backdrop";
|
|
636
666
|
backdrop.innerHTML = `
|
|
637
667
|
<div class="fg-modal">
|
|
668
|
+
<button class="fg-close-btn" id="fg-close-btn" aria-label="Close">
|
|
669
|
+
${ICONS.close}
|
|
670
|
+
</button>
|
|
638
671
|
<div id="fg-content"></div>
|
|
639
672
|
<div class="fg-footer">
|
|
640
673
|
<p>Powered by <a href="https://followgate.app" target="_blank" rel="noopener">FollowGate</a></p>
|
|
@@ -643,6 +676,9 @@ var FollowGateClient = class {
|
|
|
643
676
|
`;
|
|
644
677
|
document.body.appendChild(backdrop);
|
|
645
678
|
this.modalElement = backdrop;
|
|
679
|
+
document.getElementById("fg-close-btn")?.addEventListener("click", () => {
|
|
680
|
+
this.hide(true);
|
|
681
|
+
});
|
|
646
682
|
requestAnimationFrame(() => {
|
|
647
683
|
backdrop.classList.add("fg-visible");
|
|
648
684
|
});
|
|
@@ -655,10 +691,28 @@ var FollowGateClient = class {
|
|
|
655
691
|
getContentElement() {
|
|
656
692
|
return document.getElementById("fg-content");
|
|
657
693
|
}
|
|
694
|
+
/**
|
|
695
|
+
* Get target handle with priority:
|
|
696
|
+
* 1. config.twitter.overrideHandle (explicit override)
|
|
697
|
+
* 2. serverConfig.targetHandle (from Dashboard)
|
|
698
|
+
* 3. config.twitter.handle (legacy fallback, deprecated)
|
|
699
|
+
*/
|
|
700
|
+
getTargetHandle() {
|
|
701
|
+
if (this.config?.twitter?.overrideHandle) {
|
|
702
|
+
return this.config.twitter.overrideHandle;
|
|
703
|
+
}
|
|
704
|
+
if (this.serverConfig?.targetHandle) {
|
|
705
|
+
return this.serverConfig.targetHandle;
|
|
706
|
+
}
|
|
707
|
+
if (this.config?.twitter?.handle) {
|
|
708
|
+
return this.config.twitter.handle;
|
|
709
|
+
}
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
658
712
|
renderUsernameStep() {
|
|
659
713
|
const content = this.getContentElement();
|
|
660
714
|
if (!content) return;
|
|
661
|
-
const handle = this.
|
|
715
|
+
const handle = this.getTargetHandle();
|
|
662
716
|
const hasRepost = !!this.config?.twitter?.tweetId;
|
|
663
717
|
const allowSkip = this.serverConfig?.allowSkip ?? false;
|
|
664
718
|
const welcomeTitle = this.serverConfig?.welcomeTitle || "Unlock Free Access";
|
|
@@ -713,9 +767,13 @@ var FollowGateClient = class {
|
|
|
713
767
|
}
|
|
714
768
|
renderFollowStep() {
|
|
715
769
|
const content = this.getContentElement();
|
|
716
|
-
if (!content
|
|
717
|
-
const handle = this.
|
|
718
|
-
|
|
770
|
+
if (!content) return;
|
|
771
|
+
const handle = this.getTargetHandle();
|
|
772
|
+
if (!handle) {
|
|
773
|
+
console.error("[FollowGate] No target handle configured. Set it in Dashboard or use overrideHandle.");
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
const hasRepost = !!this.config?.twitter?.tweetId;
|
|
719
777
|
content.innerHTML = `
|
|
720
778
|
${hasRepost ? this.renderStepIndicator(1) : ""}
|
|
721
779
|
<div class="fg-icon-box">
|
|
@@ -754,8 +812,8 @@ var FollowGateClient = class {
|
|
|
754
812
|
}
|
|
755
813
|
}
|
|
756
814
|
handleFollowClick() {
|
|
757
|
-
|
|
758
|
-
|
|
815
|
+
const handle = this.getTargetHandle();
|
|
816
|
+
if (!handle) return;
|
|
759
817
|
this.openIntent({
|
|
760
818
|
platform: "twitter",
|
|
761
819
|
action: "follow",
|
|
@@ -764,8 +822,8 @@ var FollowGateClient = class {
|
|
|
764
822
|
this.showFollowConfirmation();
|
|
765
823
|
}
|
|
766
824
|
showFollowConfirmation() {
|
|
767
|
-
|
|
768
|
-
|
|
825
|
+
const handle = this.getTargetHandle();
|
|
826
|
+
if (!handle) return;
|
|
769
827
|
const subtitle = document.getElementById("fg-follow-subtitle");
|
|
770
828
|
const actions = document.getElementById("fg-follow-actions");
|
|
771
829
|
if (subtitle) {
|
|
@@ -811,14 +869,14 @@ var FollowGateClient = class {
|
|
|
811
869
|
}
|
|
812
870
|
}
|
|
813
871
|
async handleFollowConfirm() {
|
|
814
|
-
|
|
815
|
-
|
|
872
|
+
const handle = this.getTargetHandle();
|
|
873
|
+
if (!handle) return;
|
|
816
874
|
await this.complete({
|
|
817
875
|
platform: "twitter",
|
|
818
876
|
action: "follow",
|
|
819
877
|
target: handle
|
|
820
878
|
});
|
|
821
|
-
if (this.config
|
|
879
|
+
if (this.config?.twitter?.tweetId) {
|
|
822
880
|
this.renderRepostStep();
|
|
823
881
|
} else {
|
|
824
882
|
this.renderConfirmStep();
|
|
@@ -969,11 +1027,12 @@ var FollowGateClient = class {
|
|
|
969
1027
|
this.handleFinish();
|
|
970
1028
|
});
|
|
971
1029
|
document.getElementById("fg-redo-follow")?.addEventListener("click", () => {
|
|
972
|
-
|
|
1030
|
+
const handle = this.getTargetHandle();
|
|
1031
|
+
if (handle) {
|
|
973
1032
|
this.openIntent({
|
|
974
1033
|
platform: "twitter",
|
|
975
1034
|
action: "follow",
|
|
976
|
-
target:
|
|
1035
|
+
target: handle
|
|
977
1036
|
});
|
|
978
1037
|
}
|
|
979
1038
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -420,6 +420,35 @@ var MODAL_STYLES = `
|
|
|
420
420
|
color: #94a3b8;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
.fg-close-btn {
|
|
424
|
+
position: absolute;
|
|
425
|
+
top: 16px;
|
|
426
|
+
right: 16px;
|
|
427
|
+
width: 32px;
|
|
428
|
+
height: 32px;
|
|
429
|
+
border-radius: 8px;
|
|
430
|
+
background: transparent;
|
|
431
|
+
border: 1px solid #334155;
|
|
432
|
+
color: #64748b;
|
|
433
|
+
cursor: pointer;
|
|
434
|
+
display: flex;
|
|
435
|
+
align-items: center;
|
|
436
|
+
justify-content: center;
|
|
437
|
+
transition: all 0.2s;
|
|
438
|
+
padding: 0;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.fg-close-btn:hover {
|
|
442
|
+
background: #1e293b;
|
|
443
|
+
color: #94a3b8;
|
|
444
|
+
border-color: #475569;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.fg-close-btn svg {
|
|
448
|
+
width: 16px;
|
|
449
|
+
height: 16px;
|
|
450
|
+
}
|
|
451
|
+
|
|
423
452
|
.fg-btn-row {
|
|
424
453
|
display: flex;
|
|
425
454
|
gap: 8px;
|
|
@@ -436,7 +465,8 @@ var ICONS = {
|
|
|
436
465
|
x: '<svg viewBox="0 0 24 24"><path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>',
|
|
437
466
|
check: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>',
|
|
438
467
|
repost: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>',
|
|
439
|
-
warning: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>'
|
|
468
|
+
warning: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>',
|
|
469
|
+
close: '<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>'
|
|
440
470
|
};
|
|
441
471
|
var FollowGateClient = class {
|
|
442
472
|
config = null;
|
|
@@ -609,6 +639,9 @@ var FollowGateClient = class {
|
|
|
609
639
|
backdrop.className = "fg-modal-backdrop";
|
|
610
640
|
backdrop.innerHTML = `
|
|
611
641
|
<div class="fg-modal">
|
|
642
|
+
<button class="fg-close-btn" id="fg-close-btn" aria-label="Close">
|
|
643
|
+
${ICONS.close}
|
|
644
|
+
</button>
|
|
612
645
|
<div id="fg-content"></div>
|
|
613
646
|
<div class="fg-footer">
|
|
614
647
|
<p>Powered by <a href="https://followgate.app" target="_blank" rel="noopener">FollowGate</a></p>
|
|
@@ -617,6 +650,9 @@ var FollowGateClient = class {
|
|
|
617
650
|
`;
|
|
618
651
|
document.body.appendChild(backdrop);
|
|
619
652
|
this.modalElement = backdrop;
|
|
653
|
+
document.getElementById("fg-close-btn")?.addEventListener("click", () => {
|
|
654
|
+
this.hide(true);
|
|
655
|
+
});
|
|
620
656
|
requestAnimationFrame(() => {
|
|
621
657
|
backdrop.classList.add("fg-visible");
|
|
622
658
|
});
|
|
@@ -629,10 +665,28 @@ var FollowGateClient = class {
|
|
|
629
665
|
getContentElement() {
|
|
630
666
|
return document.getElementById("fg-content");
|
|
631
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* Get target handle with priority:
|
|
670
|
+
* 1. config.twitter.overrideHandle (explicit override)
|
|
671
|
+
* 2. serverConfig.targetHandle (from Dashboard)
|
|
672
|
+
* 3. config.twitter.handle (legacy fallback, deprecated)
|
|
673
|
+
*/
|
|
674
|
+
getTargetHandle() {
|
|
675
|
+
if (this.config?.twitter?.overrideHandle) {
|
|
676
|
+
return this.config.twitter.overrideHandle;
|
|
677
|
+
}
|
|
678
|
+
if (this.serverConfig?.targetHandle) {
|
|
679
|
+
return this.serverConfig.targetHandle;
|
|
680
|
+
}
|
|
681
|
+
if (this.config?.twitter?.handle) {
|
|
682
|
+
return this.config.twitter.handle;
|
|
683
|
+
}
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
632
686
|
renderUsernameStep() {
|
|
633
687
|
const content = this.getContentElement();
|
|
634
688
|
if (!content) return;
|
|
635
|
-
const handle = this.
|
|
689
|
+
const handle = this.getTargetHandle();
|
|
636
690
|
const hasRepost = !!this.config?.twitter?.tweetId;
|
|
637
691
|
const allowSkip = this.serverConfig?.allowSkip ?? false;
|
|
638
692
|
const welcomeTitle = this.serverConfig?.welcomeTitle || "Unlock Free Access";
|
|
@@ -687,9 +741,13 @@ var FollowGateClient = class {
|
|
|
687
741
|
}
|
|
688
742
|
renderFollowStep() {
|
|
689
743
|
const content = this.getContentElement();
|
|
690
|
-
if (!content
|
|
691
|
-
const handle = this.
|
|
692
|
-
|
|
744
|
+
if (!content) return;
|
|
745
|
+
const handle = this.getTargetHandle();
|
|
746
|
+
if (!handle) {
|
|
747
|
+
console.error("[FollowGate] No target handle configured. Set it in Dashboard or use overrideHandle.");
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const hasRepost = !!this.config?.twitter?.tweetId;
|
|
693
751
|
content.innerHTML = `
|
|
694
752
|
${hasRepost ? this.renderStepIndicator(1) : ""}
|
|
695
753
|
<div class="fg-icon-box">
|
|
@@ -728,8 +786,8 @@ var FollowGateClient = class {
|
|
|
728
786
|
}
|
|
729
787
|
}
|
|
730
788
|
handleFollowClick() {
|
|
731
|
-
|
|
732
|
-
|
|
789
|
+
const handle = this.getTargetHandle();
|
|
790
|
+
if (!handle) return;
|
|
733
791
|
this.openIntent({
|
|
734
792
|
platform: "twitter",
|
|
735
793
|
action: "follow",
|
|
@@ -738,8 +796,8 @@ var FollowGateClient = class {
|
|
|
738
796
|
this.showFollowConfirmation();
|
|
739
797
|
}
|
|
740
798
|
showFollowConfirmation() {
|
|
741
|
-
|
|
742
|
-
|
|
799
|
+
const handle = this.getTargetHandle();
|
|
800
|
+
if (!handle) return;
|
|
743
801
|
const subtitle = document.getElementById("fg-follow-subtitle");
|
|
744
802
|
const actions = document.getElementById("fg-follow-actions");
|
|
745
803
|
if (subtitle) {
|
|
@@ -785,14 +843,14 @@ var FollowGateClient = class {
|
|
|
785
843
|
}
|
|
786
844
|
}
|
|
787
845
|
async handleFollowConfirm() {
|
|
788
|
-
|
|
789
|
-
|
|
846
|
+
const handle = this.getTargetHandle();
|
|
847
|
+
if (!handle) return;
|
|
790
848
|
await this.complete({
|
|
791
849
|
platform: "twitter",
|
|
792
850
|
action: "follow",
|
|
793
851
|
target: handle
|
|
794
852
|
});
|
|
795
|
-
if (this.config
|
|
853
|
+
if (this.config?.twitter?.tweetId) {
|
|
796
854
|
this.renderRepostStep();
|
|
797
855
|
} else {
|
|
798
856
|
this.renderConfirmStep();
|
|
@@ -943,11 +1001,12 @@ var FollowGateClient = class {
|
|
|
943
1001
|
this.handleFinish();
|
|
944
1002
|
});
|
|
945
1003
|
document.getElementById("fg-redo-follow")?.addEventListener("click", () => {
|
|
946
|
-
|
|
1004
|
+
const handle = this.getTargetHandle();
|
|
1005
|
+
if (handle) {
|
|
947
1006
|
this.openIntent({
|
|
948
1007
|
platform: "twitter",
|
|
949
1008
|
action: "follow",
|
|
950
|
-
target:
|
|
1009
|
+
target: handle
|
|
951
1010
|
});
|
|
952
1011
|
}
|
|
953
1012
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@followgate/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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",
|