Spaces:
Sleeping
Sleeping
Update App.tsx
Browse files
App.tsx
CHANGED
|
@@ -142,6 +142,11 @@ const App: React.FC = () => {
|
|
| 142 |
const [channels, setChannels] = useState<ApiChannel[]>([]);
|
| 143 |
const [models, setModels] = useState<AiModel[]>([]);
|
| 144 |
const [isConfigManagerOpen, setIsConfigManagerOpen] = useState<boolean>(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
const [isRoleSelectorOpen, setIsRoleSelectorOpen] = useState<boolean>(false);
|
| 146 |
|
| 147 |
const [isDiscussionActive, setIsDiscussionActive] = useState<boolean>(false);
|
|
@@ -179,31 +184,46 @@ const App: React.FC = () => {
|
|
| 179 |
};
|
| 180 |
|
| 181 |
const loadConfiguration = () => {
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
|
| 186 |
-
|
| 187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
|
| 189 |
-
const
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
}
|
| 195 |
-
|
| 196 |
-
const channel = allChannels.find(ch => ch.id === model.channelId);
|
| 197 |
-
if (!channel) {
|
| 198 |
-
console.warn(`Model ${model.name} references non-existent channel ${model.channelId}`);
|
| 199 |
-
return null;
|
| 200 |
-
}
|
| 201 |
-
|
| 202 |
-
return { ...role, model, channel };
|
| 203 |
-
}).filter(Boolean) as ActiveRole[];
|
| 204 |
|
| 205 |
-
|
| 206 |
-
};
|
|
|
|
|
|
|
|
|
|
| 207 |
|
| 208 |
useEffect(() => {
|
| 209 |
loadConfiguration();
|
|
@@ -775,6 +795,29 @@ const App: React.FC = () => {
|
|
| 775 |
|
| 776 |
return (
|
| 777 |
<div className="flex flex-col h-screen max-w-7xl mx-auto bg-gray-900 shadow-2xl rounded-lg overflow-hidden">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 778 |
<header className="p-4 bg-gray-900 border-b border-gray-700 flex items-center justify-between shrink-0 space-x-2 md:space-x-4 flex-wrap">
|
| 779 |
<div className="flex items-center shrink-0">
|
| 780 |
<BotMessageSquare size={28} className="mr-2 md:mr-3 text-sky-400" />
|
|
|
|
| 142 |
const [channels, setChannels] = useState<ApiChannel[]>([]);
|
| 143 |
const [models, setModels] = useState<AiModel[]>([]);
|
| 144 |
const [isConfigManagerOpen, setIsConfigManagerOpen] = useState<boolean>(false);
|
| 145 |
+
const [updateNotification, setUpdateNotification] = useState<{
|
| 146 |
+
newChannels: number;
|
| 147 |
+
newModels: number;
|
| 148 |
+
newRoles: number;
|
| 149 |
+
} | null>(null);
|
| 150 |
const [isRoleSelectorOpen, setIsRoleSelectorOpen] = useState<boolean>(false);
|
| 151 |
|
| 152 |
const [isDiscussionActive, setIsDiscussionActive] = useState<boolean>(false);
|
|
|
|
| 184 |
};
|
| 185 |
|
| 186 |
const loadConfiguration = () => {
|
| 187 |
+
// 检查是否有配置更新
|
| 188 |
+
const updateInfo = ConfigManager.getLastUpdateInfo();
|
| 189 |
+
if (updateInfo) {
|
| 190 |
+
setUpdateNotification({
|
| 191 |
+
newChannels: updateInfo.newChannels,
|
| 192 |
+
newModels: updateInfo.newModels,
|
| 193 |
+
newRoles: updateInfo.newRoles
|
| 194 |
+
});
|
| 195 |
|
| 196 |
+
// 5秒后自动关闭通知
|
| 197 |
+
setTimeout(() => {
|
| 198 |
+
setUpdateNotification(null);
|
| 199 |
+
}, 5000);
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
const allChannels = ConfigManager.getChannels();
|
| 203 |
+
const allModels = ConfigManager.getModels();
|
| 204 |
+
const allRoles = ConfigManager.getActiveRoles();
|
| 205 |
+
|
| 206 |
+
setChannels(allChannels);
|
| 207 |
+
setModels(allModels);
|
| 208 |
+
|
| 209 |
+
const rolesWithModelsAndChannels: ActiveRole[] = allRoles.map(role => {
|
| 210 |
+
const model = allModels.find(m => m.id === role.modelId);
|
| 211 |
+
if (!model) {
|
| 212 |
+
console.warn(`Role ${role.name} references non-existent model ${role.modelId}`);
|
| 213 |
+
return null;
|
| 214 |
+
}
|
| 215 |
|
| 216 |
+
const channel = allChannels.find(ch => ch.id === model.channelId);
|
| 217 |
+
if (!channel) {
|
| 218 |
+
console.warn(`Model ${model.name} references non-existent channel ${model.channelId}`);
|
| 219 |
+
return null;
|
| 220 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
|
| 222 |
+
return { ...role, model, channel };
|
| 223 |
+
}).filter(Boolean) as ActiveRole[];
|
| 224 |
+
|
| 225 |
+
setActiveRoles(rolesWithModelsAndChannels);
|
| 226 |
+
};
|
| 227 |
|
| 228 |
useEffect(() => {
|
| 229 |
loadConfiguration();
|
|
|
|
| 795 |
|
| 796 |
return (
|
| 797 |
<div className="flex flex-col h-screen max-w-7xl mx-auto bg-gray-900 shadow-2xl rounded-lg overflow-hidden">
|
| 798 |
+
{updateNotification && (
|
| 799 |
+
<div className="fixed top-4 left-1/2 transform -translate-x-1/2 bg-green-700 text-white px-6 py-3 rounded-lg shadow-lg z-50">
|
| 800 |
+
<div className="flex items-center space-x-3">
|
| 801 |
+
<div className="flex-shrink-0">
|
| 802 |
+
<Check size={24} className="text-white" />
|
| 803 |
+
</div>
|
| 804 |
+
<div>
|
| 805 |
+
<p className="font-semibold">配置已更新!</p>
|
| 806 |
+
<p className="text-sm">
|
| 807 |
+
{updateNotification.newChannels > 0 && `新增 ${updateNotification.newChannels} 个渠道 `}
|
| 808 |
+
{updateNotification.newModels > 0 && `新增 ${updateNotification.newModels} 个模型 `}
|
| 809 |
+
{updateNotification.newRoles > 0 && `新增 ${updateNotification.newRoles} 个角色`}
|
| 810 |
+
</p>
|
| 811 |
+
</div>
|
| 812 |
+
<button
|
| 813 |
+
onClick={() => setUpdateNotification(null)}
|
| 814 |
+
className="flex-shrink-0 ml-4 hover:bg-green-600 rounded p-1"
|
| 815 |
+
>
|
| 816 |
+
<X size={20} />
|
| 817 |
+
</button>
|
| 818 |
+
</div>
|
| 819 |
+
</div>
|
| 820 |
+
)}
|
| 821 |
<header className="p-4 bg-gray-900 border-b border-gray-700 flex items-center justify-between shrink-0 space-x-2 md:space-x-4 flex-wrap">
|
| 822 |
<div className="flex items-center shrink-0">
|
| 823 |
<BotMessageSquare size={28} className="mr-2 md:mr-3 text-sky-400" />
|