11import { renderAll } from './view/view.js' ;
22import { getAllProblems , syncProblems } from "./service/problemService.js" ;
33import { getLevelColor , getCurrentRetrievability } from './util/utils.js' ;
4- import { handleFeedbackSubmission } from './script/submission.js' ;
4+ import { handleFeedbackSubmission , handleAddBlankProblem } from './script/submission.js' ;
55import './popup.css' ;
66import { isCloudSyncEnabled , loadConfigs , setCloudSyncEnabled , setProblemSorter , setDefaultCardLimit , setReminderEnabled } from "./service/configService" ;
77import { store , daily_store } from './store' ;
@@ -640,21 +640,36 @@ async function loadProblemList() {
640640}
641641
642642
643- // 显示/隐藏弹窗
644- function toggleAddProblemDialog ( show = true ) {
643+ // 显示/隐藏添加题目弹窗
644+ function toggleAddProblemDialog ( show ) {
645645 const dialog = document . getElementById ( 'addProblemDialog' ) ;
646- if ( ! dialog ) {
647- console . error ( '找不到添加题目弹窗' ) ;
648- return ;
649- }
650-
651- dialog . style . display = show ? 'block' : 'none' ;
646+ if ( ! dialog ) return ;
652647
653- if ( ! show ) {
654- // 重置表单
655- const urlInput = document . getElementById ( 'problemUrl' ) ;
656- if ( urlInput ) {
657- urlInput . value = '' ;
648+ if ( show ) {
649+ dialog . style . display = 'block' ;
650+ } else {
651+ dialog . style . display = 'none' ;
652+
653+ // 清除所有输入字段
654+ const problemUrl = document . getElementById ( 'problemUrl' ) ;
655+ const problemName = document . getElementById ( 'problemName' ) ;
656+ const customUrl = document . getElementById ( 'customUrl' ) ;
657+
658+ if ( problemUrl ) problemUrl . value = '' ;
659+ if ( problemName ) problemName . value = '' ;
660+ if ( customUrl ) customUrl . value = '' ;
661+
662+ // 重置选项卡到默认状态
663+ const urlTabButton = document . getElementById ( 'urlTabButton' ) ;
664+ const manualTabButton = document . getElementById ( 'manualTabButton' ) ;
665+ const urlTab = document . getElementById ( 'urlTab' ) ;
666+ const manualTab = document . getElementById ( 'manualTab' ) ;
667+
668+ if ( urlTabButton && manualTabButton && urlTab && manualTab ) {
669+ urlTabButton . classList . add ( 'active' ) ;
670+ manualTabButton . classList . remove ( 'active' ) ;
671+ urlTab . classList . add ( 'active' ) ;
672+ manualTab . classList . remove ( 'active' ) ;
658673 }
659674 }
660675}
@@ -666,11 +681,98 @@ function initializeAddProblem() {
666681 const addButton = document . querySelector ( '.gear-button.add-problem' ) ;
667682 if ( ! addButton ) return ;
668683
684+ // 添加选项卡切换样式
685+ const style = document . createElement ( 'style' ) ;
686+ style . textContent = `
687+ .tab-container {
688+ margin-bottom: 15px;
689+ }
690+
691+ .tab-buttons {
692+ display: flex;
693+ border-bottom: 1px solid #3a4a5c;
694+ margin-bottom: 15px;
695+ }
696+
697+ .tab-button {
698+ background: none;
699+ border: none;
700+ padding: 8px 15px;
701+ color: #a0aec0;
702+ cursor: pointer;
703+ transition: all 0.3s;
704+ border-bottom: 2px solid transparent;
705+ }
706+
707+ .tab-button.active {
708+ color: #4a9d9c;
709+ border-bottom: 2px solid #4a9d9c;
710+ }
711+
712+ .tab-content {
713+ display: none;
714+ }
715+
716+ .tab-content.active {
717+ display: block;
718+ }
719+
720+ /* 修复弹窗背景色 - 使用更强的选择器 */
721+ #addProblemDialog .modal-content {
722+ background-color: #1d2e3d !important;
723+ color: #ffffff !important;
724+ }
725+
726+ #addProblemDialog .tab-content,
727+ #addProblemDialog .form-group {
728+ background-color: #1d2e3d !important;
729+ color: #ffffff !important;
730+ }
731+
732+ #addProblemDialog input.form-control,
733+ #addProblemDialog select.form-control {
734+ background-color: #2d3e4d !important;
735+ color: #ffffff !important;
736+ border: 1px solid #3a4a5c !important;
737+ }
738+
739+ #addProblemDialog input.form-control::placeholder {
740+ color: #8096a8 !important;
741+ }
742+
743+ #addProblemDialog label {
744+ color: #a0aec0 !important;
745+ }
746+ ` ;
747+ document . head . appendChild ( style ) ;
748+
669749 // 点击添加按钮显示弹窗
670750 addButton . addEventListener ( 'click' , ( ) => {
671751 toggleAddProblemDialog ( true ) ;
672752 } ) ;
673753
754+ // 选项卡切换功能
755+ const urlTabButton = document . getElementById ( 'urlTabButton' ) ;
756+ const manualTabButton = document . getElementById ( 'manualTabButton' ) ;
757+ const urlTab = document . getElementById ( 'urlTab' ) ;
758+ const manualTab = document . getElementById ( 'manualTab' ) ;
759+
760+ if ( urlTabButton && manualTabButton ) {
761+ urlTabButton . addEventListener ( 'click' , ( ) => {
762+ urlTabButton . classList . add ( 'active' ) ;
763+ manualTabButton . classList . remove ( 'active' ) ;
764+ urlTab . classList . add ( 'active' ) ;
765+ manualTab . classList . remove ( 'active' ) ;
766+ } ) ;
767+
768+ manualTabButton . addEventListener ( 'click' , ( ) => {
769+ manualTabButton . classList . add ( 'active' ) ;
770+ urlTabButton . classList . remove ( 'active' ) ;
771+ manualTab . classList . add ( 'active' ) ;
772+ urlTab . classList . remove ( 'active' ) ;
773+ } ) ;
774+ }
775+
674776 // 取消按钮
675777 const cancelButton = document . getElementById ( 'cancelAdd' ) ;
676778 if ( cancelButton ) {
@@ -683,27 +785,54 @@ function initializeAddProblem() {
683785 const confirmButton = document . getElementById ( 'confirmAdd' ) ;
684786 if ( confirmButton ) {
685787 confirmButton . addEventListener ( 'click' , async ( ) => {
686- const urlInput = document . getElementById ( 'problemUrl' ) ;
687-
688- const url = urlInput . value . trim ( ) ;
689-
690788 try {
691- await handleAddProblem ( url ) ;
789+ let result ;
790+
791+ // 判断当前激活的是哪个选项卡
792+ if ( urlTab . classList . contains ( 'active' ) ) {
793+ // 从URL添加
794+ const url = document . getElementById ( 'problemUrl' ) . value . trim ( ) ;
795+ if ( ! url ) {
796+ throw new Error ( 'Please enter a valid problem URL.' ) ;
797+ }
798+ result = await handleAddProblem ( url ) ;
799+ } else {
800+ // 创建空白卡片
801+ const name = document . getElementById ( 'problemName' ) . value . trim ( ) ;
802+ const level = document . getElementById ( 'problemLevel' ) . value ;
803+ const customUrl = document . getElementById ( 'customUrl' ) . value . trim ( ) ;
804+
805+ if ( ! name ) {
806+ throw new Error ( 'Please enter the problem name.' ) ;
807+ }
808+
809+ if ( ! level ) {
810+ throw new Error ( 'Please select a difficulty level.' ) ;
811+ }
812+
813+ // 如果提供了URL,检查其格式是否有效
814+ if ( customUrl && ! customUrl . match ( / ^ h t t p s ? : \/ \/ .+ / ) ) {
815+ throw new Error ( 'Please enter a valid URL starting with http:// or https://' ) ;
816+ }
817+
818+ result = await handleAddBlankProblem ( name , level , customUrl ) ;
819+ }
820+
692821 toggleAddProblemDialog ( false ) ;
693822 await loadDailyReviewData ( ) ;
694823 updateCardDisplay ( ) ;
695824
696825 // 显示成功提示
697826 Swal . fire ( {
698827 icon : 'success' ,
699- title : '添加成功 ' ,
700- text : '题目已成功添加到复习列表 ' ,
828+ title : 'SUCCESS ' ,
829+ text : 'Problem added to review list. ' ,
701830 showConfirmButton : false ,
702831 timer : 1500 ,
703832 background : '#1d2e3d' ,
704833 color : '#ffffff' ,
705834 toast : true ,
706- position : 'top -end' ,
835+ position : 'center -end' ,
707836 customClass : {
708837 popup : 'colored-toast'
709838 }
@@ -712,7 +841,7 @@ function initializeAddProblem() {
712841 // 显示错误提示
713842 Swal . fire ( {
714843 icon : 'error' ,
715- title : '添加失败 ' ,
844+ title : 'ADD FAIL ' ,
716845 text : error . message ,
717846 background : '#1d2e3d' ,
718847 color : '#ffffff' ,
0 commit comments