2 Commit-ok b1fb39c486 ... 8e4c368200

Szerző SHA1 Üzenet Dátum
  MHSanaei 8e4c368200 feat(update): allow opting into the dev channel from a stable build 9 órája
  MHSanaei 522b1b64b0 fix(logger): prevent nil-deref panic in migrate/setting CLI paths 15 órája

+ 2 - 9
frontend/src/pages/index/IndexPage.tsx

@@ -66,7 +66,6 @@ export default function IndexPage() {
   useEffect(() => { setMessageInstance(messageApi); }, [messageApi]);
 
   const [accessLogEnable, setAccessLogEnable] = useState(false);
-  const [isDevBuild, setIsDevBuild] = useState(false);
   const [devChannelEnable, setDevChannelEnable] = useState(false);
   const [panelUpdateInfo, setPanelUpdateInfo] = useState<PanelUpdateInfo>({
     currentVersion: '',
@@ -90,12 +89,11 @@ export default function IndexPage() {
   const [loadingTip, setLoadingTip] = useState(t('loading'));
 
   useEffect(() => {
-    HttpUtil.post<{ accessLogEnable?: boolean; isDevBuild?: boolean; devChannelEnable?: boolean }>(
+    HttpUtil.post<{ accessLogEnable?: boolean; devChannelEnable?: boolean }>(
       '/panel/api/setting/defaultSettings',
     ).then((msg) => {
       if (msg?.success && msg.obj) {
         setAccessLogEnable(!!msg.obj.accessLogEnable);
-        setIsDevBuild(!!msg.obj.isDevBuild);
         setDevChannelEnable(!!msg.obj.devChannelEnable);
       }
     });
@@ -128,11 +126,7 @@ export default function IndexPage() {
   }, [refresh]);
 
   function openPanelVersion() {
-    if (panelUpdateInfo.updateAvailable || isDevBuild) {
-      setPanelUpdateOpen(true);
-    } else {
-      window.open('https://github.com/MHSanaei/3x-ui/releases', '_blank', 'noopener,noreferrer');
-    }
+    setPanelUpdateOpen(true);
   }
 
   async function handleChannelChange(dev: boolean) {
@@ -463,7 +457,6 @@ export default function IndexPage() {
           <PanelUpdateModal
             open={panelUpdateOpen}
             info={panelUpdateInfo}
-            isDevBuild={isDevBuild}
             devChannelEnable={devChannelEnable}
             onChannelChange={handleChannelChange}
             onClose={() => setPanelUpdateOpen(false)}

+ 9 - 13
frontend/src/pages/index/PanelUpdateModal.tsx

@@ -25,7 +25,6 @@ interface BusyEvent {
 interface PanelUpdateModalProps {
   open: boolean;
   info: PanelUpdateInfo;
-  isDevBuild?: boolean;
   devChannelEnable?: boolean;
   onChannelChange?: (dev: boolean) => void | Promise<void>;
   onClose: () => void;
@@ -35,7 +34,6 @@ interface PanelUpdateModalProps {
 export default function PanelUpdateModal({
   open,
   info,
-  isDevBuild,
   devChannelEnable,
   onChannelChange,
   onClose,
@@ -113,18 +111,16 @@ export default function PanelUpdateModal({
           />
         )}
 
-        {isDevBuild && (
-          <div className="version-list">
-            <div className="version-list-item">
-              <span>{t('pages.index.devChannel')}</span>
-              <Switch
-                checked={!!devChannelEnable}
-                loading={channelBusy}
-                onChange={handleChannel}
-              />
-            </div>
+        <div className="version-list">
+          <div className="version-list-item">
+            <span>{t('pages.index.devChannel')}</span>
+            <Switch
+              checked={!!devChannelEnable}
+              loading={channelBusy}
+              onChange={handleChannel}
+            />
           </div>
-        )}
+        </div>
 
         {devChannelEnable && (
           <Alert

+ 3 - 1
internal/logger/logger.go

@@ -29,7 +29,9 @@ const (
 )
 
 var (
-	logger     *logging.Logger
+	// Initialized to a usable default so logging never nil-derefs before InitLogger
+	// runs — the "migrate" and "setting" CLI subcommands log without calling it.
+	logger     = logging.MustGetLogger("x-ui")
 	fileRotate *lumberjack.Logger // nil when file backend disabled
 
 	// logBuffer maintains recent log entries in memory for web UI retrieval;

+ 4 - 5
internal/web/service/panel/panel.go

@@ -90,12 +90,11 @@ func (s *PanelService) GetUpdateInfo() (*PanelUpdateInfo, error) {
 }
 
 // devChannelActive reports whether self-update should track the rolling dev
-// release. It requires both the opt-in setting and a dev build, so a stable
-// binary with the toggle left on never cross-grades to the dev channel.
+// release. It is driven solely by the opt-in setting so the panel can
+// cross-grade a stable build onto the dev channel once the user enables it;
+// nothing updates without an explicit user action, so an unattended stable
+// binary with the toggle off stays on the stable channel.
 func devChannelActive() bool {
-	if !config.IsDevBuild() {
-		return false
-	}
 	enabled, err := (&service.SettingService{}).GetDevChannelEnable()
 	return err == nil && enabled
 }

+ 1 - 0
main.go

@@ -484,6 +484,7 @@ func GetApiToken(getApiToken bool) {
 func migrateDb() {
 	inboundService := service.InboundService{}
 
+	logger.InitLogger(logging.INFO)
 	err := database.InitDB(config.GetDBPath())
 	if err != nil {
 		log.Fatal(err)