@sunggang/ui-lib 0.4.52 → 0.4.54

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.
@@ -511,6 +511,33 @@ var LiffProvider = function(param) {
511
511
  console.error("儲存 liffUserInfo 失敗:", err);
512
512
  }
513
513
  };
514
+ // 移除 LIFF profile 的 localStorage
515
+ var removeLiffUserInfoFromStorage = function() {
516
+ try {
517
+ window.localStorage.removeItem(liffUserInfoStorageKey);
518
+ } catch (err) {
519
+ // ignore
520
+ }
521
+ };
522
+ // 移除 LIFF initialized flag
523
+ var removeLiffInitializedFromStorage = function() {
524
+ try {
525
+ window.localStorage.removeItem("".concat(localStorageKey, "-liffInitialized"));
526
+ } catch (err) {
527
+ // ignore
528
+ }
529
+ };
530
+ // 清除 LIFF 相關快取與狀態(暴露給外部 as needed)
531
+ var clearLiffData = function() {
532
+ try {
533
+ removeLiffUserInfoFromStorage();
534
+ removeLiffInitializedFromStorage();
535
+ } catch (e) {
536
+ // ignore
537
+ }
538
+ setLiffProfile(null);
539
+ setLiffObject(null);
540
+ };
514
541
  var fetchMemberInfo = function() {
515
542
  var _ref = _async_to_generator(function(token) {
516
543
  var response, err;
@@ -619,6 +646,12 @@ var LiffProvider = function(param) {
619
646
  // token 無效時清除 userInfo
620
647
  setUserInfo(null);
621
648
  window.localStorage.removeItem(userInfoStorageKey);
649
+ // 使用統一清理方法清除 LIFF 快取與初始化標記
650
+ try {
651
+ clearLiffData();
652
+ } catch (e) {
653
+ // ignore
654
+ }
622
655
  return [
623
656
  3,
624
657
  7
@@ -698,8 +731,14 @@ var LiffProvider = function(param) {
698
731
  6
699
732
  ];
700
733
  case 5:
734
+ // 登入沒有回傳 token,視為登入失敗 — 清除 LIFF 快取
701
735
  setUserInfo(response);
702
736
  saveUserInfoToStorage(response);
737
+ try {
738
+ clearLiffData();
739
+ } catch (e) {
740
+ // ignore
741
+ }
703
742
  if (handleLoginError) handleLoginError();
704
743
  _state.label = 6;
705
744
  case 6:
@@ -726,157 +765,235 @@ var LiffProvider = function(param) {
726
765
  };
727
766
  }();
728
767
  // 初始化 LIFF
768
+ var initPromiseRef = React.useRef(null);
729
769
  var initializeLiff = function() {
730
770
  var _ref = _async_to_generator(function(isValid) {
731
- var customFetch, liff, originalFetch, profile, profileErr, lineToken, redirectUri, tempFriendship, friendship, friendFlag, error, err;
732
771
  return _ts_generator(this, function(_state) {
733
- switch(_state.label){
734
- case 0:
735
- _state.trys.push([
736
- 0,
737
- 13,
738
- ,
739
- 14
740
- ]);
741
- customFetch = // 自訂 fetch 函數,避免每次請求都改變 URL
742
- // eslint-disable-next-line no-inner-declarations
743
- function customFetch(url, options) {
744
- if (url.toString().startsWith("https://liffsdk.line-scdn.net/xlt/") && url.toString().endsWith(".json")) {
745
- url = "".concat(url, "?ts=").concat(Math.random());
746
- }
747
- return originalFetch(url, options);
748
- };
749
- return [
750
- 4,
751
- Promise.resolve().then(function () { return require('./index.cjs3.js'); })
752
- ];
753
- case 1:
754
- liff = _state.sent().liff;
755
- originalFetch = window.fetch;
756
- window.fetch = customFetch;
757
- if (openInApp && !(liff === null || liff === void 0 ? void 0 : liff.isInClient()) && (liff === null || liff === void 0 ? void 0 : liff.getOS()) !== "web") window.location.href = "line://app/".concat(liffId);
758
- return [
759
- 4,
760
- liff.init({
761
- liffId: liffId,
762
- withLoginOnExternalBrowser: false
763
- })
764
- ];
765
- case 2:
766
- _state.sent();
767
- console.log("LIFF init succeeded.");
768
- setLiffObject(liff);
769
- _state.label = 3;
770
- case 3:
771
- _state.trys.push([
772
- 3,
773
- 5,
774
- ,
775
- 6
776
- ]);
777
- return [
778
- 4,
779
- liff.getProfile()
780
- ];
781
- case 4:
782
- profile = _state.sent();
783
- setLiffProfile(profile);
784
- saveLiffUserInfoToStorage(profile);
785
- return [
786
- 3,
787
- 6
788
- ];
789
- case 5:
790
- profileErr = _state.sent();
791
- console.warn("取得 LIFF profile 失敗(非致命):", profileErr);
792
- return [
793
- 3,
794
- 6
795
- ];
796
- case 6:
797
- lineToken = liff === null || liff === void 0 ? void 0 : liff.getAccessToken();
798
- // 未登入先進行登入
799
- if (!liff.isLoggedIn()) {
800
- redirectUri = customerRedirectUrl || "".concat(window.location.href);
801
- if (liffLogin) {
802
- liff.login({
803
- redirectUri: redirectUri
804
- });
772
+ // 如果已有執行中的 initialize promise,直接等待它
773
+ if (initPromiseRef.current) return [
774
+ 2,
775
+ initPromiseRef.current
776
+ ];
777
+ initPromiseRef.current = _async_to_generator(function() {
778
+ var customFetch, initializedFlagKey, alreadyInitialized, liffModule, e, liff, originalFetch, storedProfileExists, profile, profileErr, lineToken, redirectUri, tempFriendship, friendship, friendFlag, error, err;
779
+ return _ts_generator(this, function(_state) {
780
+ switch(_state.label){
781
+ case 0:
782
+ _state.trys.push([
783
+ 0,
784
+ 19,
785
+ 20,
786
+ 21
787
+ ]);
788
+ customFetch = // eslint-disable-next-line no-inner-declarations
789
+ function customFetch(url, options) {
790
+ if (url.toString().startsWith("https://liffsdk.line-scdn.net/xlt/") && url.toString().endsWith(".json")) {
791
+ url = "".concat(url, "?ts=").concat(Math.random());
792
+ }
793
+ return originalFetch(url, options);
794
+ };
795
+ initializedFlagKey = "".concat(localStorageKey, "-liffInitialized");
796
+ // 若之前已紀錄為 initialized,嘗試直接載入 SDK 並重用
797
+ alreadyInitialized = !!window.localStorage.getItem(initializedFlagKey);
798
+ liffModule = null;
799
+ _state.label = 1;
800
+ case 1:
801
+ _state.trys.push([
802
+ 1,
803
+ 3,
804
+ ,
805
+ 4
806
+ ]);
807
+ return [
808
+ 4,
809
+ Promise.resolve().then(function () { return require('./index.cjs3.js'); })
810
+ ];
811
+ case 2:
812
+ liffModule = _state.sent();
813
+ return [
814
+ 3,
815
+ 4
816
+ ];
817
+ case 3:
818
+ e = _state.sent();
819
+ console.warn("載入 @line/liff 失敗:", e);
820
+ throw e;
821
+ case 4:
822
+ liff = liffModule.liff;
823
+ originalFetch = window.fetch;
824
+ window.fetch = customFetch;
825
+ // 如果記錄存在,嘗試重用 SDK 物件(不一定需要再呼叫 init)
826
+ if (alreadyInitialized) {
827
+ try {
828
+ setLiffObject(liff);
829
+ console.log("Reused LIFF SDK from persisted flag.");
830
+ } catch (e) {
831
+ console.warn("重用 LIFF SDK 失敗,將重新 init", e);
832
+ }
833
+ }
834
+ if (!!alreadyInitialized) return [
835
+ 3,
836
+ 6
837
+ ];
838
+ if (openInApp && !(liff === null || liff === void 0 ? void 0 : liff.isInClient()) && (liff === null || liff === void 0 ? void 0 : liff.getOS()) !== "web") window.location.href = "line://app/".concat(liffId);
839
+ return [
840
+ 4,
841
+ liff.init({
842
+ liffId: liffId,
843
+ withLoginOnExternalBrowser: false
844
+ })
845
+ ];
846
+ case 5:
847
+ _state.sent();
848
+ // 設定 persisted flag,避免重新整理時重複 init
849
+ try {
850
+ window.localStorage.setItem(initializedFlagKey, "1");
851
+ } catch (e) {
852
+ // ignore
853
+ }
854
+ console.log("LIFF init succeeded.");
855
+ setLiffObject(liff);
856
+ _state.label = 6;
857
+ case 6:
858
+ // 如果 localStorage 或 state 已有 profile,就跳過重複呼叫
859
+ storedProfileExists = false;
860
+ try {
861
+ storedProfileExists = !!window.localStorage.getItem(liffUserInfoStorageKey);
862
+ } catch (e) {
863
+ storedProfileExists = false;
864
+ }
865
+ if (!(!storedProfileExists && !liffProfile)) return [
866
+ 3,
867
+ 11
868
+ ];
869
+ _state.label = 7;
870
+ case 7:
871
+ _state.trys.push([
872
+ 7,
873
+ 9,
874
+ ,
875
+ 10
876
+ ]);
877
+ return [
878
+ 4,
879
+ liff.getProfile()
880
+ ];
881
+ case 8:
882
+ profile = _state.sent();
883
+ setLiffProfile(profile);
884
+ saveLiffUserInfoToStorage(profile);
885
+ return [
886
+ 3,
887
+ 10
888
+ ];
889
+ case 9:
890
+ profileErr = _state.sent();
891
+ console.warn("取得 LIFF profile 失敗(非致命):", profileErr);
892
+ return [
893
+ 3,
894
+ 10
895
+ ];
896
+ case 10:
897
+ return [
898
+ 3,
899
+ 12
900
+ ];
901
+ case 11:
902
+ console.log("跳過 liff.getProfile():已由 localStorage 或 state 取得 profile");
903
+ _state.label = 12;
904
+ case 12:
905
+ lineToken = liff === null || liff === void 0 ? void 0 : liff.getAccessToken();
906
+ // 未登入先進行登入
907
+ if (!liff.isLoggedIn()) {
908
+ redirectUri = customerRedirectUrl || "".concat(window.location.href);
909
+ if (liffLogin) {
910
+ liff.login({
911
+ redirectUri: redirectUri
912
+ });
913
+ return [
914
+ 2
915
+ ];
916
+ }
917
+ if (loginByUser || ignoreRoute) return [
918
+ 2
919
+ ];
920
+ liff.login({
921
+ redirectUri: redirectUri
922
+ });
923
+ }
924
+ tempFriendship = null;
925
+ if (!lineToken) return [
926
+ 3,
927
+ 18
928
+ ];
929
+ _state.label = 13;
930
+ case 13:
931
+ _state.trys.push([
932
+ 13,
933
+ 15,
934
+ ,
935
+ 16
936
+ ]);
937
+ return [
938
+ 4,
939
+ liff.getFriendship()
940
+ ];
941
+ case 14:
942
+ friendship = _state.sent();
943
+ friendFlag = friendship === null || friendship === void 0 ? void 0 : friendship.friendFlag;
944
+ setFriendship(friendFlag);
945
+ tempFriendship = friendFlag;
946
+ console.log("isFriendship", friendFlag);
947
+ return [
948
+ 3,
949
+ 16
950
+ ];
951
+ case 15:
952
+ error = _state.sent();
953
+ console.error("Error in liff.getFriendship():", error);
954
+ return [
955
+ 3,
956
+ 16
957
+ ];
958
+ case 16:
959
+ console.log("isValid", isValid);
960
+ if (tempFriendship && isValid) return [
961
+ 2
962
+ ];
963
+ return [
964
+ 4,
965
+ loginInit(lineToken)
966
+ ];
967
+ case 17:
968
+ _state.sent();
969
+ _state.label = 18;
970
+ case 18:
971
+ return [
972
+ 3,
973
+ 21
974
+ ];
975
+ case 19:
976
+ err = _state.sent();
977
+ setLiffError((err === null || err === void 0 ? void 0 : err.toString) ? err.toString() : String(err));
978
+ console.log("LIFF init failed.", err);
979
+ throw err;
980
+ case 20:
981
+ // 清除 reference,允許下次再次初始化(若需要)
982
+ initPromiseRef.current = null;
983
+ return [
984
+ 7
985
+ ];
986
+ case 21:
805
987
  return [
806
988
  2
807
989
  ];
808
- }
809
- if (loginByUser || ignoreRoute) return [
810
- 2
811
- ];
812
- liff.login({
813
- redirectUri: redirectUri
814
- });
815
990
  }
816
- tempFriendship = null;
817
- if (!lineToken) return [
818
- 3,
819
- 12
820
- ];
821
- _state.label = 7;
822
- case 7:
823
- _state.trys.push([
824
- 7,
825
- 9,
826
- ,
827
- 10
828
- ]);
829
- return [
830
- 4,
831
- liff.getFriendship()
832
- ];
833
- case 8:
834
- friendship = _state.sent();
835
- friendFlag = friendship === null || friendship === void 0 ? void 0 : friendship.friendFlag;
836
- setFriendship(friendFlag);
837
- tempFriendship = friendFlag;
838
- console.log("isFriendship", friendFlag);
839
- return [
840
- 3,
841
- 10
842
- ];
843
- case 9:
844
- error = _state.sent();
845
- console.error("Error in liff.getFriendship():", error);
846
- return [
847
- 3,
848
- 10
849
- ];
850
- case 10:
851
- console.log("isValid", isValid);
852
- if (tempFriendship && isValid) return [
853
- 2
854
- ];
855
- return [
856
- 4,
857
- loginInit(lineToken)
858
- ];
859
- case 11:
860
- _state.sent();
861
- _state.label = 12;
862
- case 12:
863
- return [
864
- 3,
865
- 14
866
- ];
867
- case 13:
868
- err = _state.sent();
869
- setLiffError(err.toString());
870
- console.log("LIFF init failed.", err);
871
- return [
872
- 3,
873
- 14
874
- ];
875
- case 14:
876
- return [
877
- 2
878
- ];
879
- }
991
+ });
992
+ })();
993
+ return [
994
+ 2,
995
+ initPromiseRef.current
996
+ ];
880
997
  });
881
998
  });
882
999
  return function initializeLiff(isValid) {
@@ -1029,6 +1146,12 @@ var LiffProvider = function(param) {
1029
1146
  setLoginType(null);
1030
1147
  setUserInfo(null);
1031
1148
  window.localStorage.removeItem(userInfoStorageKey);
1149
+ // 使用統一清理方法
1150
+ try {
1151
+ clearLiffData();
1152
+ } catch (e) {
1153
+ // ignore
1154
+ }
1032
1155
  console.warn("LIFF token 驗證失敗,需重新登入", err);
1033
1156
  return [
1034
1157
  2,
@@ -1137,14 +1260,12 @@ var LiffProvider = function(param) {
1137
1260
  userInfo: userInfo,
1138
1261
  accessToken: accessToken,
1139
1262
  liffError: liffError,
1140
- initializeLiff: function() {
1141
- return initializeLiff(false);
1142
- },
1143
1263
  isFriendship: isFriendship,
1144
1264
  ensureLiffTokenValid: ensureLiffTokenValid,
1145
1265
  accountLogin: accountLogin,
1146
1266
  loginType: loginType,
1147
- liffProfile: liffProfile
1267
+ liffProfile: liffProfile,
1268
+ clearLiffData: clearLiffData
1148
1269
  };
1149
1270
  }, [
1150
1271
  liffObject,
@@ -1156,7 +1277,8 @@ var LiffProvider = function(param) {
1156
1277
  ensureLiffTokenValid,
1157
1278
  accountLogin,
1158
1279
  loginType,
1159
- liffProfile
1280
+ liffProfile,
1281
+ clearLiffData
1160
1282
  ]);
1161
1283
  return /*#__PURE__*/ jsxRuntime.jsx(LiffContext.Provider, {
1162
1284
  value: contextValue,
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { createContext, useState, useCallback, useEffect, useMemo, useContext } from 'react';
2
+ import { createContext, useState, useRef, useCallback, useEffect, useMemo, useContext } from 'react';
3
3
 
4
4
  function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
5
5
  try {
@@ -507,6 +507,33 @@ var LiffProvider = function(param) {
507
507
  console.error("儲存 liffUserInfo 失敗:", err);
508
508
  }
509
509
  };
510
+ // 移除 LIFF profile 的 localStorage
511
+ var removeLiffUserInfoFromStorage = function() {
512
+ try {
513
+ window.localStorage.removeItem(liffUserInfoStorageKey);
514
+ } catch (err) {
515
+ // ignore
516
+ }
517
+ };
518
+ // 移除 LIFF initialized flag
519
+ var removeLiffInitializedFromStorage = function() {
520
+ try {
521
+ window.localStorage.removeItem("".concat(localStorageKey, "-liffInitialized"));
522
+ } catch (err) {
523
+ // ignore
524
+ }
525
+ };
526
+ // 清除 LIFF 相關快取與狀態(暴露給外部 as needed)
527
+ var clearLiffData = function() {
528
+ try {
529
+ removeLiffUserInfoFromStorage();
530
+ removeLiffInitializedFromStorage();
531
+ } catch (e) {
532
+ // ignore
533
+ }
534
+ setLiffProfile(null);
535
+ setLiffObject(null);
536
+ };
510
537
  var fetchMemberInfo = function() {
511
538
  var _ref = _async_to_generator(function(token) {
512
539
  var response, err;
@@ -615,6 +642,12 @@ var LiffProvider = function(param) {
615
642
  // token 無效時清除 userInfo
616
643
  setUserInfo(null);
617
644
  window.localStorage.removeItem(userInfoStorageKey);
645
+ // 使用統一清理方法清除 LIFF 快取與初始化標記
646
+ try {
647
+ clearLiffData();
648
+ } catch (e) {
649
+ // ignore
650
+ }
618
651
  return [
619
652
  3,
620
653
  7
@@ -694,8 +727,14 @@ var LiffProvider = function(param) {
694
727
  6
695
728
  ];
696
729
  case 5:
730
+ // 登入沒有回傳 token,視為登入失敗 — 清除 LIFF 快取
697
731
  setUserInfo(response);
698
732
  saveUserInfoToStorage(response);
733
+ try {
734
+ clearLiffData();
735
+ } catch (e) {
736
+ // ignore
737
+ }
699
738
  if (handleLoginError) handleLoginError();
700
739
  _state.label = 6;
701
740
  case 6:
@@ -722,157 +761,235 @@ var LiffProvider = function(param) {
722
761
  };
723
762
  }();
724
763
  // 初始化 LIFF
764
+ var initPromiseRef = useRef(null);
725
765
  var initializeLiff = function() {
726
766
  var _ref = _async_to_generator(function(isValid) {
727
- var customFetch, liff, originalFetch, profile, profileErr, lineToken, redirectUri, tempFriendship, friendship, friendFlag, error, err;
728
767
  return _ts_generator(this, function(_state) {
729
- switch(_state.label){
730
- case 0:
731
- _state.trys.push([
732
- 0,
733
- 13,
734
- ,
735
- 14
736
- ]);
737
- customFetch = // 自訂 fetch 函數,避免每次請求都改變 URL
738
- // eslint-disable-next-line no-inner-declarations
739
- function customFetch(url, options) {
740
- if (url.toString().startsWith("https://liffsdk.line-scdn.net/xlt/") && url.toString().endsWith(".json")) {
741
- url = "".concat(url, "?ts=").concat(Math.random());
742
- }
743
- return originalFetch(url, options);
744
- };
745
- return [
746
- 4,
747
- import('./index.esm3.js')
748
- ];
749
- case 1:
750
- liff = _state.sent().liff;
751
- originalFetch = window.fetch;
752
- window.fetch = customFetch;
753
- if (openInApp && !(liff === null || liff === void 0 ? void 0 : liff.isInClient()) && (liff === null || liff === void 0 ? void 0 : liff.getOS()) !== "web") window.location.href = "line://app/".concat(liffId);
754
- return [
755
- 4,
756
- liff.init({
757
- liffId: liffId,
758
- withLoginOnExternalBrowser: false
759
- })
760
- ];
761
- case 2:
762
- _state.sent();
763
- console.log("LIFF init succeeded.");
764
- setLiffObject(liff);
765
- _state.label = 3;
766
- case 3:
767
- _state.trys.push([
768
- 3,
769
- 5,
770
- ,
771
- 6
772
- ]);
773
- return [
774
- 4,
775
- liff.getProfile()
776
- ];
777
- case 4:
778
- profile = _state.sent();
779
- setLiffProfile(profile);
780
- saveLiffUserInfoToStorage(profile);
781
- return [
782
- 3,
783
- 6
784
- ];
785
- case 5:
786
- profileErr = _state.sent();
787
- console.warn("取得 LIFF profile 失敗(非致命):", profileErr);
788
- return [
789
- 3,
790
- 6
791
- ];
792
- case 6:
793
- lineToken = liff === null || liff === void 0 ? void 0 : liff.getAccessToken();
794
- // 未登入先進行登入
795
- if (!liff.isLoggedIn()) {
796
- redirectUri = customerRedirectUrl || "".concat(window.location.href);
797
- if (liffLogin) {
798
- liff.login({
799
- redirectUri: redirectUri
800
- });
768
+ // 如果已有執行中的 initialize promise,直接等待它
769
+ if (initPromiseRef.current) return [
770
+ 2,
771
+ initPromiseRef.current
772
+ ];
773
+ initPromiseRef.current = _async_to_generator(function() {
774
+ var customFetch, initializedFlagKey, alreadyInitialized, liffModule, e, liff, originalFetch, storedProfileExists, profile, profileErr, lineToken, redirectUri, tempFriendship, friendship, friendFlag, error, err;
775
+ return _ts_generator(this, function(_state) {
776
+ switch(_state.label){
777
+ case 0:
778
+ _state.trys.push([
779
+ 0,
780
+ 19,
781
+ 20,
782
+ 21
783
+ ]);
784
+ customFetch = // eslint-disable-next-line no-inner-declarations
785
+ function customFetch(url, options) {
786
+ if (url.toString().startsWith("https://liffsdk.line-scdn.net/xlt/") && url.toString().endsWith(".json")) {
787
+ url = "".concat(url, "?ts=").concat(Math.random());
788
+ }
789
+ return originalFetch(url, options);
790
+ };
791
+ initializedFlagKey = "".concat(localStorageKey, "-liffInitialized");
792
+ // 若之前已紀錄為 initialized,嘗試直接載入 SDK 並重用
793
+ alreadyInitialized = !!window.localStorage.getItem(initializedFlagKey);
794
+ liffModule = null;
795
+ _state.label = 1;
796
+ case 1:
797
+ _state.trys.push([
798
+ 1,
799
+ 3,
800
+ ,
801
+ 4
802
+ ]);
803
+ return [
804
+ 4,
805
+ import('./index.esm3.js')
806
+ ];
807
+ case 2:
808
+ liffModule = _state.sent();
809
+ return [
810
+ 3,
811
+ 4
812
+ ];
813
+ case 3:
814
+ e = _state.sent();
815
+ console.warn("載入 @line/liff 失敗:", e);
816
+ throw e;
817
+ case 4:
818
+ liff = liffModule.liff;
819
+ originalFetch = window.fetch;
820
+ window.fetch = customFetch;
821
+ // 如果記錄存在,嘗試重用 SDK 物件(不一定需要再呼叫 init)
822
+ if (alreadyInitialized) {
823
+ try {
824
+ setLiffObject(liff);
825
+ console.log("Reused LIFF SDK from persisted flag.");
826
+ } catch (e) {
827
+ console.warn("重用 LIFF SDK 失敗,將重新 init", e);
828
+ }
829
+ }
830
+ if (!!alreadyInitialized) return [
831
+ 3,
832
+ 6
833
+ ];
834
+ if (openInApp && !(liff === null || liff === void 0 ? void 0 : liff.isInClient()) && (liff === null || liff === void 0 ? void 0 : liff.getOS()) !== "web") window.location.href = "line://app/".concat(liffId);
835
+ return [
836
+ 4,
837
+ liff.init({
838
+ liffId: liffId,
839
+ withLoginOnExternalBrowser: false
840
+ })
841
+ ];
842
+ case 5:
843
+ _state.sent();
844
+ // 設定 persisted flag,避免重新整理時重複 init
845
+ try {
846
+ window.localStorage.setItem(initializedFlagKey, "1");
847
+ } catch (e) {
848
+ // ignore
849
+ }
850
+ console.log("LIFF init succeeded.");
851
+ setLiffObject(liff);
852
+ _state.label = 6;
853
+ case 6:
854
+ // 如果 localStorage 或 state 已有 profile,就跳過重複呼叫
855
+ storedProfileExists = false;
856
+ try {
857
+ storedProfileExists = !!window.localStorage.getItem(liffUserInfoStorageKey);
858
+ } catch (e) {
859
+ storedProfileExists = false;
860
+ }
861
+ if (!(!storedProfileExists && !liffProfile)) return [
862
+ 3,
863
+ 11
864
+ ];
865
+ _state.label = 7;
866
+ case 7:
867
+ _state.trys.push([
868
+ 7,
869
+ 9,
870
+ ,
871
+ 10
872
+ ]);
873
+ return [
874
+ 4,
875
+ liff.getProfile()
876
+ ];
877
+ case 8:
878
+ profile = _state.sent();
879
+ setLiffProfile(profile);
880
+ saveLiffUserInfoToStorage(profile);
881
+ return [
882
+ 3,
883
+ 10
884
+ ];
885
+ case 9:
886
+ profileErr = _state.sent();
887
+ console.warn("取得 LIFF profile 失敗(非致命):", profileErr);
888
+ return [
889
+ 3,
890
+ 10
891
+ ];
892
+ case 10:
893
+ return [
894
+ 3,
895
+ 12
896
+ ];
897
+ case 11:
898
+ console.log("跳過 liff.getProfile():已由 localStorage 或 state 取得 profile");
899
+ _state.label = 12;
900
+ case 12:
901
+ lineToken = liff === null || liff === void 0 ? void 0 : liff.getAccessToken();
902
+ // 未登入先進行登入
903
+ if (!liff.isLoggedIn()) {
904
+ redirectUri = customerRedirectUrl || "".concat(window.location.href);
905
+ if (liffLogin) {
906
+ liff.login({
907
+ redirectUri: redirectUri
908
+ });
909
+ return [
910
+ 2
911
+ ];
912
+ }
913
+ if (loginByUser || ignoreRoute) return [
914
+ 2
915
+ ];
916
+ liff.login({
917
+ redirectUri: redirectUri
918
+ });
919
+ }
920
+ tempFriendship = null;
921
+ if (!lineToken) return [
922
+ 3,
923
+ 18
924
+ ];
925
+ _state.label = 13;
926
+ case 13:
927
+ _state.trys.push([
928
+ 13,
929
+ 15,
930
+ ,
931
+ 16
932
+ ]);
933
+ return [
934
+ 4,
935
+ liff.getFriendship()
936
+ ];
937
+ case 14:
938
+ friendship = _state.sent();
939
+ friendFlag = friendship === null || friendship === void 0 ? void 0 : friendship.friendFlag;
940
+ setFriendship(friendFlag);
941
+ tempFriendship = friendFlag;
942
+ console.log("isFriendship", friendFlag);
943
+ return [
944
+ 3,
945
+ 16
946
+ ];
947
+ case 15:
948
+ error = _state.sent();
949
+ console.error("Error in liff.getFriendship():", error);
950
+ return [
951
+ 3,
952
+ 16
953
+ ];
954
+ case 16:
955
+ console.log("isValid", isValid);
956
+ if (tempFriendship && isValid) return [
957
+ 2
958
+ ];
959
+ return [
960
+ 4,
961
+ loginInit(lineToken)
962
+ ];
963
+ case 17:
964
+ _state.sent();
965
+ _state.label = 18;
966
+ case 18:
967
+ return [
968
+ 3,
969
+ 21
970
+ ];
971
+ case 19:
972
+ err = _state.sent();
973
+ setLiffError((err === null || err === void 0 ? void 0 : err.toString) ? err.toString() : String(err));
974
+ console.log("LIFF init failed.", err);
975
+ throw err;
976
+ case 20:
977
+ // 清除 reference,允許下次再次初始化(若需要)
978
+ initPromiseRef.current = null;
979
+ return [
980
+ 7
981
+ ];
982
+ case 21:
801
983
  return [
802
984
  2
803
985
  ];
804
- }
805
- if (loginByUser || ignoreRoute) return [
806
- 2
807
- ];
808
- liff.login({
809
- redirectUri: redirectUri
810
- });
811
986
  }
812
- tempFriendship = null;
813
- if (!lineToken) return [
814
- 3,
815
- 12
816
- ];
817
- _state.label = 7;
818
- case 7:
819
- _state.trys.push([
820
- 7,
821
- 9,
822
- ,
823
- 10
824
- ]);
825
- return [
826
- 4,
827
- liff.getFriendship()
828
- ];
829
- case 8:
830
- friendship = _state.sent();
831
- friendFlag = friendship === null || friendship === void 0 ? void 0 : friendship.friendFlag;
832
- setFriendship(friendFlag);
833
- tempFriendship = friendFlag;
834
- console.log("isFriendship", friendFlag);
835
- return [
836
- 3,
837
- 10
838
- ];
839
- case 9:
840
- error = _state.sent();
841
- console.error("Error in liff.getFriendship():", error);
842
- return [
843
- 3,
844
- 10
845
- ];
846
- case 10:
847
- console.log("isValid", isValid);
848
- if (tempFriendship && isValid) return [
849
- 2
850
- ];
851
- return [
852
- 4,
853
- loginInit(lineToken)
854
- ];
855
- case 11:
856
- _state.sent();
857
- _state.label = 12;
858
- case 12:
859
- return [
860
- 3,
861
- 14
862
- ];
863
- case 13:
864
- err = _state.sent();
865
- setLiffError(err.toString());
866
- console.log("LIFF init failed.", err);
867
- return [
868
- 3,
869
- 14
870
- ];
871
- case 14:
872
- return [
873
- 2
874
- ];
875
- }
987
+ });
988
+ })();
989
+ return [
990
+ 2,
991
+ initPromiseRef.current
992
+ ];
876
993
  });
877
994
  });
878
995
  return function initializeLiff(isValid) {
@@ -1025,6 +1142,12 @@ var LiffProvider = function(param) {
1025
1142
  setLoginType(null);
1026
1143
  setUserInfo(null);
1027
1144
  window.localStorage.removeItem(userInfoStorageKey);
1145
+ // 使用統一清理方法
1146
+ try {
1147
+ clearLiffData();
1148
+ } catch (e) {
1149
+ // ignore
1150
+ }
1028
1151
  console.warn("LIFF token 驗證失敗,需重新登入", err);
1029
1152
  return [
1030
1153
  2,
@@ -1133,14 +1256,12 @@ var LiffProvider = function(param) {
1133
1256
  userInfo: userInfo,
1134
1257
  accessToken: accessToken,
1135
1258
  liffError: liffError,
1136
- initializeLiff: function() {
1137
- return initializeLiff(false);
1138
- },
1139
1259
  isFriendship: isFriendship,
1140
1260
  ensureLiffTokenValid: ensureLiffTokenValid,
1141
1261
  accountLogin: accountLogin,
1142
1262
  loginType: loginType,
1143
- liffProfile: liffProfile
1263
+ liffProfile: liffProfile,
1264
+ clearLiffData: clearLiffData
1144
1265
  };
1145
1266
  }, [
1146
1267
  liffObject,
@@ -1152,7 +1273,8 @@ var LiffProvider = function(param) {
1152
1273
  ensureLiffTokenValid,
1153
1274
  accountLogin,
1154
1275
  loginType,
1155
- liffProfile
1276
+ liffProfile,
1277
+ clearLiffData
1156
1278
  ]);
1157
1279
  return /*#__PURE__*/ jsx(LiffContext.Provider, {
1158
1280
  value: contextValue,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sunggang/ui-lib",
3
- "version": "0.4.52",
3
+ "version": "0.4.54",
4
4
  "sideEffects": [
5
5
  "*.css",
6
6
  "./src/style.css",
@@ -6,9 +6,9 @@ type LiffContextType = {
6
6
  liffProfile?: any;
7
7
  accessToken: string;
8
8
  liffError: string | null;
9
- initializeLiff: () => Promise<void>;
10
9
  isFriendship: boolean | null;
11
10
  ensureLiffTokenValid: () => Promise<boolean>;
11
+ clearLiffData: () => void;
12
12
  loginType: string | null;
13
13
  accountLogin: (username: string, password: string) => Promise<void>;
14
14
  };