@followgate/js 0.12.0 → 0.13.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 CHANGED
@@ -28,6 +28,7 @@ interface FollowGateConfig {
28
28
  onComplete?: () => void;
29
29
  theme?: 'dark' | 'light';
30
30
  accentColor?: string;
31
+ forceShow?: boolean;
31
32
  }
32
33
  /**
33
34
  * SDK Error class with helpful messages
@@ -102,7 +103,7 @@ declare class FollowGateClient {
102
103
  private fetchServerConfig;
103
104
  /**
104
105
  * Show the FollowGate modal
105
- * If user is already unlocked, calls onComplete immediately
106
+ * If user is already unlocked, calls onComplete immediately (unless forceShow is true)
106
107
  */
107
108
  show(): Promise<void>;
108
109
  /**
@@ -147,9 +148,14 @@ declare class FollowGateClient {
147
148
  */
148
149
  hasUsername(): boolean;
149
150
  /**
150
- * Clear stored session
151
+ * Clear stored session (user, actions, and unlock status)
151
152
  */
152
153
  reset(): void;
154
+ /**
155
+ * Clear only the unlock status (keeps user and actions)
156
+ * Useful for allowing users to go through the flow again
157
+ */
158
+ clearUnlockStatus(): void;
153
159
  getFollowUrl(platform: Platform, target: string): string;
154
160
  getRepostUrl(platform: Platform, target: string): string;
155
161
  getLikeUrl(platform: Platform, target: string): string;
package/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ interface FollowGateConfig {
28
28
  onComplete?: () => void;
29
29
  theme?: 'dark' | 'light';
30
30
  accentColor?: string;
31
+ forceShow?: boolean;
31
32
  }
32
33
  /**
33
34
  * SDK Error class with helpful messages
@@ -102,7 +103,7 @@ declare class FollowGateClient {
102
103
  private fetchServerConfig;
103
104
  /**
104
105
  * Show the FollowGate modal
105
- * If user is already unlocked, calls onComplete immediately
106
+ * If user is already unlocked, calls onComplete immediately (unless forceShow is true)
106
107
  */
107
108
  show(): Promise<void>;
108
109
  /**
@@ -147,9 +148,14 @@ declare class FollowGateClient {
147
148
  */
148
149
  hasUsername(): boolean;
149
150
  /**
150
- * Clear stored session
151
+ * Clear stored session (user, actions, and unlock status)
151
152
  */
152
153
  reset(): void;
154
+ /**
155
+ * Clear only the unlock status (keeps user and actions)
156
+ * Useful for allowing users to go through the flow again
157
+ */
158
+ clearUnlockStatus(): void;
153
159
  getFollowUrl(platform: Platform, target: string): string;
154
160
  getRepostUrl(platform: Platform, target: string): string;
155
161
  getLikeUrl(platform: Platform, target: string): string;
package/dist/index.js CHANGED
@@ -598,18 +598,27 @@ 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 (unless forceShow is true)
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.debug) {
609
- console.log("[FollowGate] Already unlocked, skipping modal");
608
+ if (this.config.forceShow) {
609
+ this.clearUnlockStatus();
610
+ if (this.config.debug) {
611
+ console.log("[FollowGate] forceShow enabled - cleared unlock status, showing modal");
612
+ }
613
+ } else {
614
+ console.warn(
615
+ "[FollowGate] Modal skipped - user already unlocked.",
616
+ "Use forceShow: true in init() to always show modal, or call FollowGate.reset() to clear.",
617
+ this.config.userId ? `(userId: ${this.config.userId})` : "(no userId set)"
618
+ );
619
+ this.config.onComplete?.();
620
+ return;
610
621
  }
611
- this.config.onComplete?.();
612
- return;
613
622
  }
614
623
  await this.fetchServerConfig();
615
624
  if (this.config.twitter?.username && !this.hasUsername()) {
@@ -770,10 +779,16 @@ var FollowGateClient = class {
770
779
  if (!content) return;
771
780
  const handle = this.getTargetHandle();
772
781
  if (!handle) {
773
- console.error("[FollowGate] No target handle configured. Set it in Dashboard or use overrideHandle.");
782
+ console.error(
783
+ "[FollowGate] No target handle configured. Set it in Dashboard or use overrideHandle."
784
+ );
774
785
  return;
775
786
  }
776
787
  const hasRepost = !!this.config?.twitter?.tweetId;
788
+ const defaultTitle = hasRepost ? "Step 1: Follow" : "Follow to Continue";
789
+ const defaultMessage = `Follow @${handle} on X`;
790
+ const title = this.serverConfig?.welcomeTitle || defaultTitle;
791
+ const message = this.serverConfig?.welcomeMessage || defaultMessage;
777
792
  content.innerHTML = `
778
793
  ${hasRepost ? this.renderStepIndicator(1) : ""}
779
794
  <div class="fg-icon-box">
@@ -785,8 +800,8 @@ var FollowGateClient = class {
785
800
  <span class="fg-user-badge-text">@${this.currentUser.username}</span>
786
801
  </div>
787
802
  ` : ""}
788
- <h2 class="fg-title">${hasRepost ? "Step 1: Follow" : "Follow to Continue"}</h2>
789
- <p class="fg-subtitle" id="fg-follow-subtitle">Follow @${handle} on X</p>
803
+ <h2 class="fg-title">${this.escapeHtml(title)}</h2>
804
+ <p class="fg-subtitle" id="fg-follow-subtitle">${this.escapeHtml(message)}</p>
790
805
  <div id="fg-follow-actions">
791
806
  <button class="fg-btn fg-btn-dark" id="fg-follow-btn">
792
807
  ${ICONS.x}
@@ -1105,7 +1120,7 @@ var FollowGateClient = class {
1105
1120
  return this.currentUser !== null;
1106
1121
  }
1107
1122
  /**
1108
- * Clear stored session
1123
+ * Clear stored session (user, actions, and unlock status)
1109
1124
  */
1110
1125
  reset() {
1111
1126
  this.currentUser = null;
@@ -1119,6 +1134,18 @@ var FollowGateClient = class {
1119
1134
  console.log("[FollowGate] Session reset");
1120
1135
  }
1121
1136
  }
1137
+ /**
1138
+ * Clear only the unlock status (keeps user and actions)
1139
+ * Useful for allowing users to go through the flow again
1140
+ */
1141
+ clearUnlockStatus() {
1142
+ if (typeof localStorage !== "undefined") {
1143
+ localStorage.removeItem(this.getStorageKey("followgate_unlocked"));
1144
+ }
1145
+ if (this.config?.debug) {
1146
+ console.log("[FollowGate] Unlock status cleared");
1147
+ }
1148
+ }
1122
1149
  // ============================================
1123
1150
  // Intent URL Methods
1124
1151
  // ============================================
package/dist/index.mjs CHANGED
@@ -572,18 +572,27 @@ 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 (unless forceShow is true)
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.debug) {
583
- console.log("[FollowGate] Already unlocked, skipping modal");
582
+ if (this.config.forceShow) {
583
+ this.clearUnlockStatus();
584
+ if (this.config.debug) {
585
+ console.log("[FollowGate] forceShow enabled - cleared unlock status, showing modal");
586
+ }
587
+ } else {
588
+ console.warn(
589
+ "[FollowGate] Modal skipped - user already unlocked.",
590
+ "Use forceShow: true in init() to always show modal, or call FollowGate.reset() to clear.",
591
+ this.config.userId ? `(userId: ${this.config.userId})` : "(no userId set)"
592
+ );
593
+ this.config.onComplete?.();
594
+ return;
584
595
  }
585
- this.config.onComplete?.();
586
- return;
587
596
  }
588
597
  await this.fetchServerConfig();
589
598
  if (this.config.twitter?.username && !this.hasUsername()) {
@@ -744,10 +753,16 @@ var FollowGateClient = class {
744
753
  if (!content) return;
745
754
  const handle = this.getTargetHandle();
746
755
  if (!handle) {
747
- console.error("[FollowGate] No target handle configured. Set it in Dashboard or use overrideHandle.");
756
+ console.error(
757
+ "[FollowGate] No target handle configured. Set it in Dashboard or use overrideHandle."
758
+ );
748
759
  return;
749
760
  }
750
761
  const hasRepost = !!this.config?.twitter?.tweetId;
762
+ const defaultTitle = hasRepost ? "Step 1: Follow" : "Follow to Continue";
763
+ const defaultMessage = `Follow @${handle} on X`;
764
+ const title = this.serverConfig?.welcomeTitle || defaultTitle;
765
+ const message = this.serverConfig?.welcomeMessage || defaultMessage;
751
766
  content.innerHTML = `
752
767
  ${hasRepost ? this.renderStepIndicator(1) : ""}
753
768
  <div class="fg-icon-box">
@@ -759,8 +774,8 @@ var FollowGateClient = class {
759
774
  <span class="fg-user-badge-text">@${this.currentUser.username}</span>
760
775
  </div>
761
776
  ` : ""}
762
- <h2 class="fg-title">${hasRepost ? "Step 1: Follow" : "Follow to Continue"}</h2>
763
- <p class="fg-subtitle" id="fg-follow-subtitle">Follow @${handle} on X</p>
777
+ <h2 class="fg-title">${this.escapeHtml(title)}</h2>
778
+ <p class="fg-subtitle" id="fg-follow-subtitle">${this.escapeHtml(message)}</p>
764
779
  <div id="fg-follow-actions">
765
780
  <button class="fg-btn fg-btn-dark" id="fg-follow-btn">
766
781
  ${ICONS.x}
@@ -1079,7 +1094,7 @@ var FollowGateClient = class {
1079
1094
  return this.currentUser !== null;
1080
1095
  }
1081
1096
  /**
1082
- * Clear stored session
1097
+ * Clear stored session (user, actions, and unlock status)
1083
1098
  */
1084
1099
  reset() {
1085
1100
  this.currentUser = null;
@@ -1093,6 +1108,18 @@ var FollowGateClient = class {
1093
1108
  console.log("[FollowGate] Session reset");
1094
1109
  }
1095
1110
  }
1111
+ /**
1112
+ * Clear only the unlock status (keeps user and actions)
1113
+ * Useful for allowing users to go through the flow again
1114
+ */
1115
+ clearUnlockStatus() {
1116
+ if (typeof localStorage !== "undefined") {
1117
+ localStorage.removeItem(this.getStorageKey("followgate_unlocked"));
1118
+ }
1119
+ if (this.config?.debug) {
1120
+ console.log("[FollowGate] Unlock status cleared");
1121
+ }
1122
+ }
1096
1123
  // ============================================
1097
1124
  // Intent URL Methods
1098
1125
  // ============================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@followgate/js",
3
- "version": "0.12.0",
3
+ "version": "0.13.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",