@followgate/js 0.13.0 → 0.14.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 +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.js +99 -31
- package/dist/index.mjs +99 -31
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -12,6 +12,7 @@ type SocialAction = 'follow' | 'repost' | 'like';
|
|
|
12
12
|
interface TwitterConfig {
|
|
13
13
|
handle?: string;
|
|
14
14
|
overrideHandle?: string;
|
|
15
|
+
overridePostUrl?: string;
|
|
15
16
|
tweetId?: string;
|
|
16
17
|
username?: string;
|
|
17
18
|
}
|
|
@@ -28,7 +29,6 @@ interface FollowGateConfig {
|
|
|
28
29
|
onComplete?: () => void;
|
|
29
30
|
theme?: 'dark' | 'light';
|
|
30
31
|
accentColor?: string;
|
|
31
|
-
forceShow?: boolean;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* SDK Error class with helpful messages
|
|
@@ -103,7 +103,7 @@ declare class FollowGateClient {
|
|
|
103
103
|
private fetchServerConfig;
|
|
104
104
|
/**
|
|
105
105
|
* Show the FollowGate modal
|
|
106
|
-
* If user is already unlocked, calls onComplete immediately
|
|
106
|
+
* If user is already unlocked, calls onComplete immediately
|
|
107
107
|
*/
|
|
108
108
|
show(): Promise<void>;
|
|
109
109
|
/**
|
|
@@ -121,6 +121,24 @@ declare class FollowGateClient {
|
|
|
121
121
|
* 3. config.twitter.handle (legacy fallback, deprecated)
|
|
122
122
|
*/
|
|
123
123
|
private getTargetHandle;
|
|
124
|
+
/**
|
|
125
|
+
* Get target post URL/ID with priority:
|
|
126
|
+
* 1. config.twitter.overridePostUrl (explicit override)
|
|
127
|
+
* 2. serverConfig.targetPostUrl (from Dashboard)
|
|
128
|
+
* 3. config.twitter.tweetId (legacy fallback, deprecated)
|
|
129
|
+
*/
|
|
130
|
+
private getTargetPostUrl;
|
|
131
|
+
/**
|
|
132
|
+
* Extract post ID from URL or return as-is if already an ID
|
|
133
|
+
* Supports: Tweet ID, Twitter/X URLs
|
|
134
|
+
*/
|
|
135
|
+
private extractPostId;
|
|
136
|
+
/**
|
|
137
|
+
* Check if repost step should be shown based on:
|
|
138
|
+
* 1. serverConfig.actions includes 'repost'
|
|
139
|
+
* 2. A valid postUrl is available
|
|
140
|
+
*/
|
|
141
|
+
private shouldShowRepostStep;
|
|
124
142
|
private renderUsernameStep;
|
|
125
143
|
private handleUsernameSubmit;
|
|
126
144
|
private renderFollowStep;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ type SocialAction = 'follow' | 'repost' | 'like';
|
|
|
12
12
|
interface TwitterConfig {
|
|
13
13
|
handle?: string;
|
|
14
14
|
overrideHandle?: string;
|
|
15
|
+
overridePostUrl?: string;
|
|
15
16
|
tweetId?: string;
|
|
16
17
|
username?: string;
|
|
17
18
|
}
|
|
@@ -28,7 +29,6 @@ interface FollowGateConfig {
|
|
|
28
29
|
onComplete?: () => void;
|
|
29
30
|
theme?: 'dark' | 'light';
|
|
30
31
|
accentColor?: string;
|
|
31
|
-
forceShow?: boolean;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* SDK Error class with helpful messages
|
|
@@ -103,7 +103,7 @@ declare class FollowGateClient {
|
|
|
103
103
|
private fetchServerConfig;
|
|
104
104
|
/**
|
|
105
105
|
* Show the FollowGate modal
|
|
106
|
-
* If user is already unlocked, calls onComplete immediately
|
|
106
|
+
* If user is already unlocked, calls onComplete immediately
|
|
107
107
|
*/
|
|
108
108
|
show(): Promise<void>;
|
|
109
109
|
/**
|
|
@@ -121,6 +121,24 @@ declare class FollowGateClient {
|
|
|
121
121
|
* 3. config.twitter.handle (legacy fallback, deprecated)
|
|
122
122
|
*/
|
|
123
123
|
private getTargetHandle;
|
|
124
|
+
/**
|
|
125
|
+
* Get target post URL/ID with priority:
|
|
126
|
+
* 1. config.twitter.overridePostUrl (explicit override)
|
|
127
|
+
* 2. serverConfig.targetPostUrl (from Dashboard)
|
|
128
|
+
* 3. config.twitter.tweetId (legacy fallback, deprecated)
|
|
129
|
+
*/
|
|
130
|
+
private getTargetPostUrl;
|
|
131
|
+
/**
|
|
132
|
+
* Extract post ID from URL or return as-is if already an ID
|
|
133
|
+
* Supports: Tweet ID, Twitter/X URLs
|
|
134
|
+
*/
|
|
135
|
+
private extractPostId;
|
|
136
|
+
/**
|
|
137
|
+
* Check if repost step should be shown based on:
|
|
138
|
+
* 1. serverConfig.actions includes 'repost'
|
|
139
|
+
* 2. A valid postUrl is available
|
|
140
|
+
*/
|
|
141
|
+
private shouldShowRepostStep;
|
|
124
142
|
private renderUsernameStep;
|
|
125
143
|
private handleUsernameSubmit;
|
|
126
144
|
private renderFollowStep;
|
package/dist/index.js
CHANGED
|
@@ -598,27 +598,22 @@ var FollowGateClient = class {
|
|
|
598
598
|
}
|
|
599
599
|
/**
|
|
600
600
|
* Show the FollowGate modal
|
|
601
|
-
* If user is already unlocked, calls onComplete immediately
|
|
601
|
+
* If user is already unlocked, calls onComplete immediately
|
|
602
602
|
*/
|
|
603
603
|
async show() {
|
|
604
604
|
if (!this.config) {
|
|
605
605
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
606
606
|
}
|
|
607
607
|
if (this.isUnlocked()) {
|
|
608
|
-
if (this.config.
|
|
609
|
-
|
|
610
|
-
if (this.config.debug) {
|
|
611
|
-
console.log("[FollowGate] forceShow enabled - cleared unlock status, showing modal");
|
|
612
|
-
}
|
|
613
|
-
} else {
|
|
614
|
-
console.warn(
|
|
608
|
+
if (this.config.debug) {
|
|
609
|
+
console.log(
|
|
615
610
|
"[FollowGate] Modal skipped - user already unlocked.",
|
|
616
|
-
"
|
|
611
|
+
"Call FollowGate.reset() to clear unlock status.",
|
|
617
612
|
this.config.userId ? `(userId: ${this.config.userId})` : "(no userId set)"
|
|
618
613
|
);
|
|
619
|
-
this.config.onComplete?.();
|
|
620
|
-
return;
|
|
621
614
|
}
|
|
615
|
+
this.config.onComplete?.();
|
|
616
|
+
return;
|
|
622
617
|
}
|
|
623
618
|
await this.fetchServerConfig();
|
|
624
619
|
if (this.config.twitter?.username && !this.hasUsername()) {
|
|
@@ -718,11 +713,68 @@ var FollowGateClient = class {
|
|
|
718
713
|
}
|
|
719
714
|
return null;
|
|
720
715
|
}
|
|
716
|
+
/**
|
|
717
|
+
* Get target post URL/ID with priority:
|
|
718
|
+
* 1. config.twitter.overridePostUrl (explicit override)
|
|
719
|
+
* 2. serverConfig.targetPostUrl (from Dashboard)
|
|
720
|
+
* 3. config.twitter.tweetId (legacy fallback, deprecated)
|
|
721
|
+
*/
|
|
722
|
+
getTargetPostUrl() {
|
|
723
|
+
if (this.config?.twitter?.overridePostUrl) {
|
|
724
|
+
return this.extractPostId(this.config.twitter.overridePostUrl);
|
|
725
|
+
}
|
|
726
|
+
if (this.serverConfig?.targetPostUrl) {
|
|
727
|
+
return this.extractPostId(this.serverConfig.targetPostUrl);
|
|
728
|
+
}
|
|
729
|
+
if (this.config?.twitter?.tweetId) {
|
|
730
|
+
return this.config.twitter.tweetId;
|
|
731
|
+
}
|
|
732
|
+
return null;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Extract post ID from URL or return as-is if already an ID
|
|
736
|
+
* Supports: Tweet ID, Twitter/X URLs
|
|
737
|
+
*/
|
|
738
|
+
extractPostId(input) {
|
|
739
|
+
if (!input) return null;
|
|
740
|
+
const trimmed = input.trim();
|
|
741
|
+
if (/^\d+$/.test(trimmed)) {
|
|
742
|
+
return trimmed;
|
|
743
|
+
}
|
|
744
|
+
const twitterMatch = trimmed.match(
|
|
745
|
+
/(?:twitter|x)\.com\/\w+\/status\/(\d+)/
|
|
746
|
+
);
|
|
747
|
+
if (twitterMatch) {
|
|
748
|
+
return twitterMatch[1];
|
|
749
|
+
}
|
|
750
|
+
return trimmed;
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Check if repost step should be shown based on:
|
|
754
|
+
* 1. serverConfig.actions includes 'repost'
|
|
755
|
+
* 2. A valid postUrl is available
|
|
756
|
+
*/
|
|
757
|
+
shouldShowRepostStep() {
|
|
758
|
+
const postUrl = this.getTargetPostUrl();
|
|
759
|
+
const actionsIncludeRepost = this.serverConfig?.actions?.includes("repost");
|
|
760
|
+
if (actionsIncludeRepost && !postUrl) {
|
|
761
|
+
console.warn(
|
|
762
|
+
"[FollowGate] REPOST action configured but no targetPostUrl available.",
|
|
763
|
+
"Set targetPostUrl in Dashboard or use overridePostUrl in config.",
|
|
764
|
+
"Skipping repost step."
|
|
765
|
+
);
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
if (this.config?.twitter?.tweetId) {
|
|
769
|
+
return true;
|
|
770
|
+
}
|
|
771
|
+
return !!actionsIncludeRepost && !!postUrl;
|
|
772
|
+
}
|
|
721
773
|
renderUsernameStep() {
|
|
722
774
|
const content = this.getContentElement();
|
|
723
775
|
if (!content) return;
|
|
724
776
|
const handle = this.getTargetHandle();
|
|
725
|
-
const hasRepost =
|
|
777
|
+
const hasRepost = this.shouldShowRepostStep();
|
|
726
778
|
const allowSkip = this.serverConfig?.allowSkip ?? false;
|
|
727
779
|
const welcomeTitle = this.serverConfig?.welcomeTitle || "Unlock Free Access";
|
|
728
780
|
const welcomeMessage = this.serverConfig?.welcomeMessage || "Enter your X username to get started";
|
|
@@ -784,7 +836,7 @@ var FollowGateClient = class {
|
|
|
784
836
|
);
|
|
785
837
|
return;
|
|
786
838
|
}
|
|
787
|
-
const hasRepost =
|
|
839
|
+
const hasRepost = this.shouldShowRepostStep();
|
|
788
840
|
const defaultTitle = hasRepost ? "Step 1: Follow" : "Follow to Continue";
|
|
789
841
|
const defaultMessage = `Follow @${handle} on X`;
|
|
790
842
|
const title = this.serverConfig?.welcomeTitle || defaultTitle;
|
|
@@ -819,8 +871,7 @@ var FollowGateClient = class {
|
|
|
819
871
|
});
|
|
820
872
|
}
|
|
821
873
|
handleSkipFollow() {
|
|
822
|
-
if (
|
|
823
|
-
if (this.config.twitter.tweetId) {
|
|
874
|
+
if (this.shouldShowRepostStep()) {
|
|
824
875
|
this.renderRepostStep();
|
|
825
876
|
} else {
|
|
826
877
|
this.renderConfirmStep();
|
|
@@ -891,7 +942,7 @@ var FollowGateClient = class {
|
|
|
891
942
|
action: "follow",
|
|
892
943
|
target: handle
|
|
893
944
|
});
|
|
894
|
-
if (this.
|
|
945
|
+
if (this.shouldShowRepostStep()) {
|
|
895
946
|
this.renderRepostStep();
|
|
896
947
|
} else {
|
|
897
948
|
this.renderConfirmStep();
|
|
@@ -899,7 +950,8 @@ var FollowGateClient = class {
|
|
|
899
950
|
}
|
|
900
951
|
renderRepostStep() {
|
|
901
952
|
const content = this.getContentElement();
|
|
902
|
-
|
|
953
|
+
const postId = this.getTargetPostUrl();
|
|
954
|
+
if (!content || !postId) return;
|
|
903
955
|
content.innerHTML = `
|
|
904
956
|
${this.renderStepIndicator(2)}
|
|
905
957
|
<div class="fg-icon-box fg-success">
|
|
@@ -930,12 +982,12 @@ var FollowGateClient = class {
|
|
|
930
982
|
});
|
|
931
983
|
}
|
|
932
984
|
handleRepostClick() {
|
|
933
|
-
|
|
934
|
-
|
|
985
|
+
const postId = this.getTargetPostUrl();
|
|
986
|
+
if (!postId) return;
|
|
935
987
|
this.openIntent({
|
|
936
988
|
platform: "twitter",
|
|
937
989
|
action: "repost",
|
|
938
|
-
target:
|
|
990
|
+
target: postId
|
|
939
991
|
});
|
|
940
992
|
this.showRepostConfirmation();
|
|
941
993
|
}
|
|
@@ -985,11 +1037,12 @@ var FollowGateClient = class {
|
|
|
985
1037
|
}
|
|
986
1038
|
}
|
|
987
1039
|
async handleRepostConfirm() {
|
|
988
|
-
|
|
1040
|
+
const postId = this.getTargetPostUrl();
|
|
1041
|
+
if (!postId) return;
|
|
989
1042
|
await this.complete({
|
|
990
1043
|
platform: "twitter",
|
|
991
1044
|
action: "repost",
|
|
992
|
-
target:
|
|
1045
|
+
target: postId
|
|
993
1046
|
});
|
|
994
1047
|
this.renderConfirmStep();
|
|
995
1048
|
}
|
|
@@ -997,15 +1050,27 @@ var FollowGateClient = class {
|
|
|
997
1050
|
const content = this.getContentElement();
|
|
998
1051
|
if (!content) return;
|
|
999
1052
|
const username = this.currentUser?.username;
|
|
1053
|
+
const targetHandle = this.getTargetHandle();
|
|
1054
|
+
const postId = this.getTargetPostUrl();
|
|
1000
1055
|
const successTitle = this.serverConfig?.successTitle || "Almost done!";
|
|
1001
1056
|
const successMessage = this.serverConfig?.successMessage || null;
|
|
1057
|
+
const hasFollow = targetHandle !== null;
|
|
1058
|
+
const hasRepost = postId !== null;
|
|
1059
|
+
let verifyText = "Verifying";
|
|
1060
|
+
if (hasFollow && hasRepost) {
|
|
1061
|
+
verifyText = "Verifying follow & repost";
|
|
1062
|
+
} else if (hasFollow) {
|
|
1063
|
+
verifyText = "Verifying follow";
|
|
1064
|
+
} else if (hasRepost) {
|
|
1065
|
+
verifyText = "Verifying repost";
|
|
1066
|
+
}
|
|
1002
1067
|
content.innerHTML = `
|
|
1003
1068
|
<h2 class="fg-title">${this.escapeHtml(successTitle)}</h2>
|
|
1004
1069
|
${successMessage ? `<p class="fg-subtitle" style="margin-bottom: 16px;">${this.escapeHtml(successMessage)}</p>` : ""}
|
|
1005
1070
|
<div class="fg-verify-box">
|
|
1006
1071
|
<div class="fg-verify-box-left">
|
|
1007
1072
|
<div class="fg-verify-spinner"></div>
|
|
1008
|
-
<span class="fg-verify-text"
|
|
1073
|
+
<span class="fg-verify-text">${verifyText}</span>
|
|
1009
1074
|
</div>
|
|
1010
1075
|
${username ? `
|
|
1011
1076
|
<div class="fg-user-badge" style="margin: 0; padding: 4px 10px; gap: 6px;">
|
|
@@ -1023,13 +1088,15 @@ var FollowGateClient = class {
|
|
|
1023
1088
|
${ICONS.check}
|
|
1024
1089
|
Got it
|
|
1025
1090
|
</button>
|
|
1026
|
-
${
|
|
1091
|
+
${hasFollow || hasRepost ? `
|
|
1027
1092
|
<div class="fg-btn-row">
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1093
|
+
${hasFollow ? `
|
|
1094
|
+
<button class="fg-btn fg-btn-secondary" id="fg-redo-follow">
|
|
1095
|
+
${ICONS.x}
|
|
1096
|
+
Open follow
|
|
1097
|
+
</button>
|
|
1098
|
+
` : ""}
|
|
1099
|
+
${hasRepost ? `
|
|
1033
1100
|
<button class="fg-btn fg-btn-secondary" id="fg-redo-repost">
|
|
1034
1101
|
${ICONS.repost}
|
|
1035
1102
|
Open repost
|
|
@@ -1052,11 +1119,12 @@ var FollowGateClient = class {
|
|
|
1052
1119
|
}
|
|
1053
1120
|
});
|
|
1054
1121
|
document.getElementById("fg-redo-repost")?.addEventListener("click", () => {
|
|
1055
|
-
|
|
1122
|
+
const repostId = this.getTargetPostUrl();
|
|
1123
|
+
if (repostId) {
|
|
1056
1124
|
this.openIntent({
|
|
1057
1125
|
platform: "twitter",
|
|
1058
1126
|
action: "repost",
|
|
1059
|
-
target:
|
|
1127
|
+
target: repostId
|
|
1060
1128
|
});
|
|
1061
1129
|
}
|
|
1062
1130
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -572,27 +572,22 @@ var FollowGateClient = class {
|
|
|
572
572
|
}
|
|
573
573
|
/**
|
|
574
574
|
* Show the FollowGate modal
|
|
575
|
-
* If user is already unlocked, calls onComplete immediately
|
|
575
|
+
* If user is already unlocked, calls onComplete immediately
|
|
576
576
|
*/
|
|
577
577
|
async show() {
|
|
578
578
|
if (!this.config) {
|
|
579
579
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
580
580
|
}
|
|
581
581
|
if (this.isUnlocked()) {
|
|
582
|
-
if (this.config.
|
|
583
|
-
|
|
584
|
-
if (this.config.debug) {
|
|
585
|
-
console.log("[FollowGate] forceShow enabled - cleared unlock status, showing modal");
|
|
586
|
-
}
|
|
587
|
-
} else {
|
|
588
|
-
console.warn(
|
|
582
|
+
if (this.config.debug) {
|
|
583
|
+
console.log(
|
|
589
584
|
"[FollowGate] Modal skipped - user already unlocked.",
|
|
590
|
-
"
|
|
585
|
+
"Call FollowGate.reset() to clear unlock status.",
|
|
591
586
|
this.config.userId ? `(userId: ${this.config.userId})` : "(no userId set)"
|
|
592
587
|
);
|
|
593
|
-
this.config.onComplete?.();
|
|
594
|
-
return;
|
|
595
588
|
}
|
|
589
|
+
this.config.onComplete?.();
|
|
590
|
+
return;
|
|
596
591
|
}
|
|
597
592
|
await this.fetchServerConfig();
|
|
598
593
|
if (this.config.twitter?.username && !this.hasUsername()) {
|
|
@@ -692,11 +687,68 @@ var FollowGateClient = class {
|
|
|
692
687
|
}
|
|
693
688
|
return null;
|
|
694
689
|
}
|
|
690
|
+
/**
|
|
691
|
+
* Get target post URL/ID with priority:
|
|
692
|
+
* 1. config.twitter.overridePostUrl (explicit override)
|
|
693
|
+
* 2. serverConfig.targetPostUrl (from Dashboard)
|
|
694
|
+
* 3. config.twitter.tweetId (legacy fallback, deprecated)
|
|
695
|
+
*/
|
|
696
|
+
getTargetPostUrl() {
|
|
697
|
+
if (this.config?.twitter?.overridePostUrl) {
|
|
698
|
+
return this.extractPostId(this.config.twitter.overridePostUrl);
|
|
699
|
+
}
|
|
700
|
+
if (this.serverConfig?.targetPostUrl) {
|
|
701
|
+
return this.extractPostId(this.serverConfig.targetPostUrl);
|
|
702
|
+
}
|
|
703
|
+
if (this.config?.twitter?.tweetId) {
|
|
704
|
+
return this.config.twitter.tweetId;
|
|
705
|
+
}
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Extract post ID from URL or return as-is if already an ID
|
|
710
|
+
* Supports: Tweet ID, Twitter/X URLs
|
|
711
|
+
*/
|
|
712
|
+
extractPostId(input) {
|
|
713
|
+
if (!input) return null;
|
|
714
|
+
const trimmed = input.trim();
|
|
715
|
+
if (/^\d+$/.test(trimmed)) {
|
|
716
|
+
return trimmed;
|
|
717
|
+
}
|
|
718
|
+
const twitterMatch = trimmed.match(
|
|
719
|
+
/(?:twitter|x)\.com\/\w+\/status\/(\d+)/
|
|
720
|
+
);
|
|
721
|
+
if (twitterMatch) {
|
|
722
|
+
return twitterMatch[1];
|
|
723
|
+
}
|
|
724
|
+
return trimmed;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Check if repost step should be shown based on:
|
|
728
|
+
* 1. serverConfig.actions includes 'repost'
|
|
729
|
+
* 2. A valid postUrl is available
|
|
730
|
+
*/
|
|
731
|
+
shouldShowRepostStep() {
|
|
732
|
+
const postUrl = this.getTargetPostUrl();
|
|
733
|
+
const actionsIncludeRepost = this.serverConfig?.actions?.includes("repost");
|
|
734
|
+
if (actionsIncludeRepost && !postUrl) {
|
|
735
|
+
console.warn(
|
|
736
|
+
"[FollowGate] REPOST action configured but no targetPostUrl available.",
|
|
737
|
+
"Set targetPostUrl in Dashboard or use overridePostUrl in config.",
|
|
738
|
+
"Skipping repost step."
|
|
739
|
+
);
|
|
740
|
+
return false;
|
|
741
|
+
}
|
|
742
|
+
if (this.config?.twitter?.tweetId) {
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
return !!actionsIncludeRepost && !!postUrl;
|
|
746
|
+
}
|
|
695
747
|
renderUsernameStep() {
|
|
696
748
|
const content = this.getContentElement();
|
|
697
749
|
if (!content) return;
|
|
698
750
|
const handle = this.getTargetHandle();
|
|
699
|
-
const hasRepost =
|
|
751
|
+
const hasRepost = this.shouldShowRepostStep();
|
|
700
752
|
const allowSkip = this.serverConfig?.allowSkip ?? false;
|
|
701
753
|
const welcomeTitle = this.serverConfig?.welcomeTitle || "Unlock Free Access";
|
|
702
754
|
const welcomeMessage = this.serverConfig?.welcomeMessage || "Enter your X username to get started";
|
|
@@ -758,7 +810,7 @@ var FollowGateClient = class {
|
|
|
758
810
|
);
|
|
759
811
|
return;
|
|
760
812
|
}
|
|
761
|
-
const hasRepost =
|
|
813
|
+
const hasRepost = this.shouldShowRepostStep();
|
|
762
814
|
const defaultTitle = hasRepost ? "Step 1: Follow" : "Follow to Continue";
|
|
763
815
|
const defaultMessage = `Follow @${handle} on X`;
|
|
764
816
|
const title = this.serverConfig?.welcomeTitle || defaultTitle;
|
|
@@ -793,8 +845,7 @@ var FollowGateClient = class {
|
|
|
793
845
|
});
|
|
794
846
|
}
|
|
795
847
|
handleSkipFollow() {
|
|
796
|
-
if (
|
|
797
|
-
if (this.config.twitter.tweetId) {
|
|
848
|
+
if (this.shouldShowRepostStep()) {
|
|
798
849
|
this.renderRepostStep();
|
|
799
850
|
} else {
|
|
800
851
|
this.renderConfirmStep();
|
|
@@ -865,7 +916,7 @@ var FollowGateClient = class {
|
|
|
865
916
|
action: "follow",
|
|
866
917
|
target: handle
|
|
867
918
|
});
|
|
868
|
-
if (this.
|
|
919
|
+
if (this.shouldShowRepostStep()) {
|
|
869
920
|
this.renderRepostStep();
|
|
870
921
|
} else {
|
|
871
922
|
this.renderConfirmStep();
|
|
@@ -873,7 +924,8 @@ var FollowGateClient = class {
|
|
|
873
924
|
}
|
|
874
925
|
renderRepostStep() {
|
|
875
926
|
const content = this.getContentElement();
|
|
876
|
-
|
|
927
|
+
const postId = this.getTargetPostUrl();
|
|
928
|
+
if (!content || !postId) return;
|
|
877
929
|
content.innerHTML = `
|
|
878
930
|
${this.renderStepIndicator(2)}
|
|
879
931
|
<div class="fg-icon-box fg-success">
|
|
@@ -904,12 +956,12 @@ var FollowGateClient = class {
|
|
|
904
956
|
});
|
|
905
957
|
}
|
|
906
958
|
handleRepostClick() {
|
|
907
|
-
|
|
908
|
-
|
|
959
|
+
const postId = this.getTargetPostUrl();
|
|
960
|
+
if (!postId) return;
|
|
909
961
|
this.openIntent({
|
|
910
962
|
platform: "twitter",
|
|
911
963
|
action: "repost",
|
|
912
|
-
target:
|
|
964
|
+
target: postId
|
|
913
965
|
});
|
|
914
966
|
this.showRepostConfirmation();
|
|
915
967
|
}
|
|
@@ -959,11 +1011,12 @@ var FollowGateClient = class {
|
|
|
959
1011
|
}
|
|
960
1012
|
}
|
|
961
1013
|
async handleRepostConfirm() {
|
|
962
|
-
|
|
1014
|
+
const postId = this.getTargetPostUrl();
|
|
1015
|
+
if (!postId) return;
|
|
963
1016
|
await this.complete({
|
|
964
1017
|
platform: "twitter",
|
|
965
1018
|
action: "repost",
|
|
966
|
-
target:
|
|
1019
|
+
target: postId
|
|
967
1020
|
});
|
|
968
1021
|
this.renderConfirmStep();
|
|
969
1022
|
}
|
|
@@ -971,15 +1024,27 @@ var FollowGateClient = class {
|
|
|
971
1024
|
const content = this.getContentElement();
|
|
972
1025
|
if (!content) return;
|
|
973
1026
|
const username = this.currentUser?.username;
|
|
1027
|
+
const targetHandle = this.getTargetHandle();
|
|
1028
|
+
const postId = this.getTargetPostUrl();
|
|
974
1029
|
const successTitle = this.serverConfig?.successTitle || "Almost done!";
|
|
975
1030
|
const successMessage = this.serverConfig?.successMessage || null;
|
|
1031
|
+
const hasFollow = targetHandle !== null;
|
|
1032
|
+
const hasRepost = postId !== null;
|
|
1033
|
+
let verifyText = "Verifying";
|
|
1034
|
+
if (hasFollow && hasRepost) {
|
|
1035
|
+
verifyText = "Verifying follow & repost";
|
|
1036
|
+
} else if (hasFollow) {
|
|
1037
|
+
verifyText = "Verifying follow";
|
|
1038
|
+
} else if (hasRepost) {
|
|
1039
|
+
verifyText = "Verifying repost";
|
|
1040
|
+
}
|
|
976
1041
|
content.innerHTML = `
|
|
977
1042
|
<h2 class="fg-title">${this.escapeHtml(successTitle)}</h2>
|
|
978
1043
|
${successMessage ? `<p class="fg-subtitle" style="margin-bottom: 16px;">${this.escapeHtml(successMessage)}</p>` : ""}
|
|
979
1044
|
<div class="fg-verify-box">
|
|
980
1045
|
<div class="fg-verify-box-left">
|
|
981
1046
|
<div class="fg-verify-spinner"></div>
|
|
982
|
-
<span class="fg-verify-text"
|
|
1047
|
+
<span class="fg-verify-text">${verifyText}</span>
|
|
983
1048
|
</div>
|
|
984
1049
|
${username ? `
|
|
985
1050
|
<div class="fg-user-badge" style="margin: 0; padding: 4px 10px; gap: 6px;">
|
|
@@ -997,13 +1062,15 @@ var FollowGateClient = class {
|
|
|
997
1062
|
${ICONS.check}
|
|
998
1063
|
Got it
|
|
999
1064
|
</button>
|
|
1000
|
-
${
|
|
1065
|
+
${hasFollow || hasRepost ? `
|
|
1001
1066
|
<div class="fg-btn-row">
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1067
|
+
${hasFollow ? `
|
|
1068
|
+
<button class="fg-btn fg-btn-secondary" id="fg-redo-follow">
|
|
1069
|
+
${ICONS.x}
|
|
1070
|
+
Open follow
|
|
1071
|
+
</button>
|
|
1072
|
+
` : ""}
|
|
1073
|
+
${hasRepost ? `
|
|
1007
1074
|
<button class="fg-btn fg-btn-secondary" id="fg-redo-repost">
|
|
1008
1075
|
${ICONS.repost}
|
|
1009
1076
|
Open repost
|
|
@@ -1026,11 +1093,12 @@ var FollowGateClient = class {
|
|
|
1026
1093
|
}
|
|
1027
1094
|
});
|
|
1028
1095
|
document.getElementById("fg-redo-repost")?.addEventListener("click", () => {
|
|
1029
|
-
|
|
1096
|
+
const repostId = this.getTargetPostUrl();
|
|
1097
|
+
if (repostId) {
|
|
1030
1098
|
this.openIntent({
|
|
1031
1099
|
platform: "twitter",
|
|
1032
1100
|
action: "repost",
|
|
1033
|
-
target:
|
|
1101
|
+
target: repostId
|
|
1034
1102
|
});
|
|
1035
1103
|
}
|
|
1036
1104
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@followgate/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.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",
|