Browse Source

Merge branch 'release/11.0' of https://code.fineres.com/scm/~obo/design1 into release/11.0

release/11.0
obo 1 year ago
parent
commit
4ff5051193
  1. 8
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 208
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  3. 41
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  4. 25
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java
  5. 10
      designer-base/src/main/java/com/fr/design/jxbrowser/NxInterceptRequestCallback.java
  6. 17
      designer-base/src/main/java/com/fr/design/login/config/DesignerLoginConfigManager.java
  7. 9
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  8. 25
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsConfigManager.java
  9. 186
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  10. 406
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java
  11. 12
      designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java
  12. 7
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  13. 17
      designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java
  14. 5
      designer-base/src/main/resources/com/fr/design/vcs/move_failed.svg
  15. 5
      designer-base/src/main/resources/com/fr/design/vcs/move_success.svg
  16. 3
      designer-base/src/main/resources/com/fr/design/vcs/vcs_move_icon.svg

8
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -1021,6 +1021,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
designerLoginConfigManager.setUseOldVersionLogin(useOldVersionLogin); designerLoginConfigManager.setUseOldVersionLogin(useOldVersionLogin);
} }
public boolean isUseNewPluginFirst() {
return designerLoginConfigManager.isUseNewPluginFirst();
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
designerLoginConfigManager.setUseNewPluginFirst(useNewPluginFirst);
}
/** /**
* 内置服务器是否使用时启动 * 内置服务器是否使用时启动
* *

208
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -36,7 +36,6 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsConfigManager; import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.VcsMovePanel;
import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.unit.UnitConvertUtil; import com.fr.design.unit.UnitConvertUtil;
import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUICoreUtils;
@ -55,12 +54,9 @@ import com.fr.stable.os.OperatingSystem;
import com.fr.third.apache.logging.log4j.Level; import com.fr.third.apache.logging.log4j.Level;
import com.fr.transaction.Configurations; import com.fr.transaction.Configurations;
import com.fr.transaction.Worker; import com.fr.transaction.Worker;
import com.fr.transaction.WorkerAdaptor;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.VcsOperator; import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.git.config.GcConfig; import com.fr.workspace.server.vcs.git.config.GcConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
@ -81,7 +77,14 @@ import javax.swing.UIManager;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Window;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
@ -146,32 +149,6 @@ public class PreferencePane extends BasicPane {
private static final Level[] LOG = {Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG}; private static final Level[] LOG = {Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG};
private static final int ONE_DAY_INT = 1;
private static final int ONE_WEEK_INT = 7;
private static final int ONE_MONTH_INT = 30;
private static final int THREE_MONTH_INT = 90;
private static final int SIX_MONTH_INT = 180;
private static final int ONE_DAY_INDEX = 0;
private static final int ONE_WEEK_INDEX = 1;
private static final int ONE_MONTH_INDEX = 2;
private static final int THREE_MONTH_INDEX = 3;
private static final int SIX_MONTH_INDEX = 4;
private static final String ONE_DAY = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_DAY");
private static final String ONE_WEEK = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_WEEK");
private static final String ONE_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_MONTH");
private static final String THREE_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_THREE_MONTH");
private static final String SIX_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_SIX_MONTH");
private static final String[] INTERVAL = {
ONE_DAY,
ONE_WEEK,
ONE_MONTH,
THREE_MONTH,
SIX_MONTH
};
private static final int DEFAULT_INDEX = 3;
private boolean languageChanged; // 是否修改了设计器语言设置 private boolean languageChanged; // 是否修改了设计器语言设置
//设置是否支持undo //设置是否支持undo
private UICheckBox supportUndoCheckBox; private UICheckBox supportUndoCheckBox;
@ -209,20 +186,8 @@ public class PreferencePane extends BasicPane {
private UICheckBox cloudAnalyticsDelayCheckBox; private UICheckBox cloudAnalyticsDelayCheckBox;
private UICheckBox vcsEnableCheckBox; private UICheckBox vcsEnableCheckBox;
private UICheckBox useVcsAutoSaveScheduleCheckBox;
private UICheckBox useVcsAutoCleanScheduleCheckBox;
private UIComboBox autoCleanIntervalComboBox;
private UIComboBox autoCleanRetainIntervalComboBox;
private IntegerEditor autoSaveIntervalEditor;
private UICheckBox saveCommitCheckBox; private UICheckBox saveCommitCheckBox;
private UICheckBox useIntervalCheckBox; private UICheckBox useIntervalCheckBox;
private VcsMovePanel movePanel;
private JPanel saveIntervalPane;
private JPanel autoCleanPane;
private UICheckBox startupPageEnabledCheckBox; private UICheckBox startupPageEnabledCheckBox;
private IntegerEditor saveIntervalEditor; private IntegerEditor saveIntervalEditor;
private UICheckBox gcEnableCheckBox; private UICheckBox gcEnableCheckBox;
@ -262,26 +227,13 @@ public class PreferencePane extends BasicPane {
JPanel advancePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); JPanel advancePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane adviceScrollPane = patchScroll(advancePane); UIScrollPane adviceScrollPane = patchScroll(advancePane);
jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane); jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane);
//初始化vcs总面板
JPanel vcsParentPane = new JPanel();
CardLayout cardLayout = new CardLayout();
vcsParentPane.setLayout(cardLayout);
//vcs配置面板
JPanel vcsPane = new JPanel(new BorderLayout());
//添加滚动条
UIScrollPane vcsScrollPane = patchScroll(vcsPane);
//配置面板作为vcs总面板的一张卡片
vcsParentPane.add(vcsScrollPane, VcsMovePanel.SETTING);
jtabPane.addTab(i18nText("Fine-Design_Vcs_Title"), vcsParentPane);
contentPane.add(jtabPane, BorderLayout.NORTH); contentPane.add(jtabPane, BorderLayout.NORTH);
createFunctionPane(generalPane); createFunctionPane(generalPane);
createEditPane(generalPane); createEditPane(generalPane);
createColorSettingPane(generalPane); createColorSettingPane(generalPane);
createVcsSettingPane(generalPane);
// vcsPane
createVcsSettingPane(vcsPane, vcsParentPane, cardLayout);
// ConfPane // ConfPane
JPanel confLocationPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane(); JPanel confLocationPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane();
@ -393,31 +345,21 @@ public class PreferencePane extends BasicPane {
return generalPanelWithScroll; return generalPanelWithScroll;
} }
private void createVcsSettingPane(JPanel generalPane,JPanel parentPane, CardLayout cardLayout) { private void createVcsSettingPane(JPanel generalPane) {
//迁移面板 JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Title"));
movePanel = createMovePane(cardLayout, parentPane); generalPane.add(vcsPane);
generalPane.add(movePanel, BorderLayout.NORTH);
JPanel savePane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Save_Setting"));
JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Clean_Setting"));
JPanel containPane = new JPanel(new GridLayout(10,1,0,8));
containPane.add(savePane);
containPane.add(vcsPane);
generalPane.add(containPane, BorderLayout.CENTER);
remindVcsLabel = new UILabel(i18nText("Fine-Design_Vcs_Remind")); remindVcsLabel = new UILabel(i18nText("Fine-Design_Vcs_Remind"));
remindVcsLabel.setVisible(!VcsHelper.getInstance().needInit()); remindVcsLabel.setVisible(!VcsHelper.getInstance().needInit());
vcsEnableCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_SaveAuto")); vcsEnableCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_SaveAuto"));
saveIntervalPane = createSaveIntervalPane();
saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete")); saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete"));
saveIntervalEditor = new IntegerEditor(60); saveIntervalEditor = new IntegerEditor(60);
useIntervalCheckBox = new UICheckBox(); useIntervalCheckBox = new UICheckBox();
savePane.add(vcsEnableCheckBox);
savePane.add(saveIntervalPane);
//gc面板 //gc面板
JPanel gcControlPane = createGcControlPane(); JPanel gcControlPane = createGcControlPane();
JPanel enableVcsPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); JPanel enableVcsPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
enableVcsPanel.add(vcsEnableCheckBox);
enableVcsPanel.add(remindVcsLabel); enableVcsPanel.add(remindVcsLabel);
JPanel intervalPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); JPanel intervalPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
final UILabel everyLabel = new UILabel(i18nText("Fine-Design_Vcs_Every")); final UILabel everyLabel = new UILabel(i18nText("Fine-Design_Vcs_Every"));
@ -426,7 +368,6 @@ public class PreferencePane extends BasicPane {
intervalPanel.add(everyLabel); intervalPanel.add(everyLabel);
intervalPanel.add(saveIntervalEditor); intervalPanel.add(saveIntervalEditor);
intervalPanel.add(delayLabel); intervalPanel.add(delayLabel);
autoCleanPane = createAutoCleanPane();
vcsEnableCheckBox.addChangeListener(new ChangeListener() { vcsEnableCheckBox.addChangeListener(new ChangeListener() {
@Override @Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
@ -449,58 +390,9 @@ public class PreferencePane extends BasicPane {
vcsPane.add(enableVcsPanel); vcsPane.add(enableVcsPanel);
vcsPane.add(intervalPanel); vcsPane.add(intervalPanel);
vcsPane.add(saveCommitCheckBox); vcsPane.add(saveCommitCheckBox);
vcsPane.add(autoCleanPane); vcsPane.add(gcControlPane);
saveIntervalPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
if (VcsHelper.getInstance().isLegacyMode()) {
// 老版本时才显示gc选项
vcsPane.add(gcControlPane);
}
}
private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) {
return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){
@Override
public void doCallBack(boolean visible) {
saveIntervalPane.setVisible(visible);
autoCleanPane.setVisible(visible);
}
});
};
private JPanel createAutoCleanPane() {
JPanel autoCleanPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoCleanScheduleCheckBox = new UICheckBox();
autoCleanIntervalComboBox = new UIComboBox(INTERVAL);
autoCleanIntervalComboBox.setSelectedIndex(DEFAULT_INDEX);
autoCleanRetainIntervalComboBox = new UIComboBox(INTERVAL);
autoCleanRetainIntervalComboBox.setSelectedIndex(DEFAULT_INDEX);
autoCleanPane.add(useVcsAutoCleanScheduleCheckBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Every")));
autoCleanPane.add(autoCleanIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Content")));
autoCleanPane.add(autoCleanRetainIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Last")));
useVcsAutoCleanScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(false);
return autoCleanPane;
} }
private JPanel createSaveIntervalPane() {
JPanel saveIntervalPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoSaveScheduleCheckBox = new UICheckBox();
autoSaveIntervalEditor = new IntegerEditor(60);
saveIntervalPane.add(useVcsAutoSaveScheduleCheckBox);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Every")));
saveIntervalPane.add(autoSaveIntervalEditor);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Save_Delay")));
useVcsAutoSaveScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
saveIntervalPane.setVisible(false);
return saveIntervalPane;
}
/** /**
* 模创建板版本gc 配置操作面板 * 模创建板版本gc 配置操作面板
* *
@ -904,10 +796,6 @@ public class PreferencePane extends BasicPane {
gcEnableCheckBox.setSelected(GcConfig.getInstance().isGcEnable()); gcEnableCheckBox.setSelected(GcConfig.getInstance().isGcEnable());
gcButton.setEnabled(gcEnableCheckBox.isSelected()); gcButton.setEnabled(gcEnableCheckBox.isSelected());
useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave());
useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean());
autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval());
gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor()); gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor());
paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor()); paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor());
@ -923,8 +811,7 @@ public class PreferencePane extends BasicPane {
this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort())); this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort()));
if (useOptimizedUPMCheckbox != null) { if (useOptimizedUPMCheckbox != null) {
useOptimizedUPMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseOptimizedUPM() useOptimizedUPMCheckbox.setSelected(checkOptimizedUPMUse());
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter());
} }
if (useNewVersionLoginCheckbox != null) { if (useNewVersionLoginCheckbox != null) {
@ -968,6 +855,15 @@ public class PreferencePane extends BasicPane {
this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled()); this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled());
} }
private boolean checkOptimizedUPMUse() {
//如果是没手动配置过则默认开启
//isUseNewPluginFirst如果为true说明没手动配置过,直接开启
//走到这里说明checkBox不为空,机型肯定符合
return DesignerEnvManager.getEnvManager().isUseNewPluginFirst()
|| ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter();
}
private int chooseCase(int sign) { private int chooseCase(int sign) {
switch (sign) { switch (sign) {
case 0: case 0:
@ -987,21 +883,6 @@ public class PreferencePane extends BasicPane {
} }
} }
private int getDay(int dateIndex) {
switch (dateIndex) {
case ONE_DAY_INDEX:
return ONE_DAY_INT;
case ONE_WEEK_INDEX:
return ONE_WEEK_INT;
case ONE_MONTH_INDEX:
return ONE_MONTH_INT;
case SIX_MONTH_INDEX:
return SIX_MONTH_INT;
default:
return THREE_MONTH_INT;
}
}
/** /**
* The method of update. * The method of update.
*/ */
@ -1040,24 +921,16 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected()); designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected());
designerEnvManager.setEmbedServerLazyStartup(this.embedServerLazyStartupCheckBox.isSelected()); designerEnvManager.setEmbedServerLazyStartup(this.embedServerLazyStartupCheckBox.isSelected());
designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected()); designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected());
designerEnvManager.setUseOptimizedUPM4Adapter(this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected()); boolean optimizedUPMFlag = this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected();
designerEnvManager.setUseOptimizedUPM4Adapter(optimizedUPMFlag);
//只有取消掉使用新插件管理器这个选项才需要把useNewPluginFirst置false(意味着用户手动配置了,如果勾选着的话,这个useNewPluginFirst为true就行了)
designerEnvManager.setUseNewPluginFirst(optimizedUPMFlag);
designerEnvManager.setCloudAnalyticsDelay(this.cloudAnalyticsDelayCheckBox.isSelected()); designerEnvManager.setCloudAnalyticsDelay(this.cloudAnalyticsDelayCheckBox.isSelected());
VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager(); VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager();
vcsConfigManager.setSaveInterval(this.saveIntervalEditor.getValue()); vcsConfigManager.setSaveInterval(this.saveIntervalEditor.getValue());
vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected()); vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected());
vcsConfigManager.setSaveCommit(this.saveCommitCheckBox.isSelected()); vcsConfigManager.setSaveCommit(this.saveCommitCheckBox.isSelected());
vcsConfigManager.setUseInterval(this.useIntervalCheckBox.isSelected()); vcsConfigManager.setUseInterval(this.useIntervalCheckBox.isSelected());
vcsConfigManager.setUseAutoSave(this.useVcsAutoSaveScheduleCheckBox.isSelected());
vcsConfigManager.setAutoSaveInterval(this.autoSaveIntervalEditor.getValue());
Configurations.update(new WorkerAdaptor(VcsConfig.class) {
@Override
public void run() {
VcsConfig.getInstance().setUseV2AutoClean(useVcsAutoCleanScheduleCheckBox.isSelected());
VcsConfig.getInstance().setV2CleanInterval(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
VcsConfig.getInstance().setV2RetainInterval(getDay(autoCleanRetainIntervalComboBox.getSelectedIndex()));
}
});
dealWithSchedule();
designerEnvManager.setStartupPageEnabled(this.startupPageEnabledCheckBox.isSelected()); designerEnvManager.setStartupPageEnabled(this.startupPageEnabledCheckBox.isSelected());
Configurations.update(new Worker() { Configurations.update(new Worker() {
@Override @Override
@ -1132,31 +1005,6 @@ public class PreferencePane extends BasicPane {
} }
private void dealWithSchedule() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
boolean v2FunctionSupport = VcsHelper.getInstance().checkV2FunctionSupport();
if (v2FunctionSupport) {
//如果支持V2
if (useVcsAutoSaveScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto save!");
VcsHelper.getInstance().startAutoSave(autoSaveIntervalEditor.getValue());
} else {
VcsHelper.getInstance().stopAutoSave();
}
if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
} else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob();
}
}
return null;
}
}.execute();
}
// 如果语言设置改变了,则显示重启对话框 // 如果语言设置改变了,则显示重启对话框
public void showRestartDialog() { public void showRestartDialog() {
if (!languageChanged) { if (!languageChanged) {

41
designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java

@ -112,27 +112,7 @@ public class PluginOperateUtils {
} }
/**
* 批量启用或禁用插件
*
* @param pluginIDs 要处理的插件信息
* @param jsCallback 回调函数
*/
public static void setPluginActive(JSArray pluginIDs, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int len = pluginIDs.length();
BatchModifyStatusCallback modifyStatusCallback = new BatchModifyStatusCallback(jsCallback, len);
for (int i = 0; i < len; i++) {
String pluginInfo = pluginIDs.get(i).asString().getValue();
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
dealWithPluginActive(pluginMarker, modifyStatusCallback);
}
}
});
}
private static void dealWithPluginActive(PluginMarker pluginMarker, BatchModifyStatusCallback modifyStatusCallback) { private static void dealWithPluginActive(PluginMarker pluginMarker, BatchModifyStatusCallback modifyStatusCallback) {
PluginContext plugin = PluginManager.getContext(pluginMarker); PluginContext plugin = PluginManager.getContext(pluginMarker);
@ -180,6 +160,27 @@ public class PluginOperateUtils {
}); });
} }
/**
* 批量启用或禁用插件
*
* @param pluginIDs 要处理的插件信息
* @param jsCallback 回调函数
*/
public static void setPluginActive(List<String> pluginIDs, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int len = pluginIDs.size();
BatchModifyStatusCallback modifyStatusCallback = new BatchModifyStatusCallback(jsCallback, len);
for (String pluginInfo : pluginIDs) {
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
dealWithPluginActive(pluginMarker, modifyStatusCallback);
}
}
});
}
public static void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSCallback jsCallback) { public static void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {

25
designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java

@ -8,6 +8,7 @@ import com.fr.design.ui.ModernUIConstants;
import com.fr.design.ui.ModernUIPane; import com.fr.design.ui.ModernUIPane;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair; import com.fr.stable.collections.combination.Pair;
import com.fr.stable.os.OperatingSystem;
import com.fr.web.struct.AssembleComponent; import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.Browser; import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
@ -47,6 +48,12 @@ import static com.fr.design.ui.ModernUIConstants.WINDOW;
*/ */
public class JxUIPane<T> extends ModernUIPane<T> { public class JxUIPane<T> extends ModernUIPane<T> {
/**
* 冒号
*/
public static final String COLON = ":";
private static final String COLON_ESCAPE = "\\:";
private Browser browser; private Browser browser;
private String namespace = "Pool"; private String namespace = "Pool";
private String variable = "data"; private String variable = "data";
@ -126,7 +133,7 @@ public class JxUIPane<T> extends ModernUIPane<T> {
*/ */
@Override @Override
public void redirect(String url) { public void redirect(String url) {
browser.navigation().loadUrl(url); browser.navigation().loadUrl(encodeWindowsPath(url));
} }
/** /**
@ -138,7 +145,7 @@ public class JxUIPane<T> extends ModernUIPane<T> {
@Override @Override
public void redirect(String url, Map<String, String> map) { public void redirect(String url, Map<String, String> map) {
setMap(map); setMap(map);
browser.navigation().loadUrl(url); browser.navigation().loadUrl(encodeWindowsPath(url));
} }
private void setMap(Map<String, String> map) { private void setMap(Map<String, String> map) {
@ -220,6 +227,18 @@ public class JxUIPane<T> extends ModernUIPane<T> {
return Optional.ofNullable(frame.executeJavaScript(name)); return Optional.ofNullable(frame.executeJavaScript(name));
} }
/**
* 由于自定义scheme目前走的是url因此路径会被自动转化比如windows路径下对冒号问题
* C:\\abc 变成 /C/abc这里对冒号进行编码转义
*/
private static String encodeWindowsPath(String path) {
if (OperatingSystem.isWindows() && path.startsWith(EMB_TAG + SCHEME_HEADER)) {
String s = path.split(EMB_TAG + SCHEME_HEADER)[1];
return EMB_TAG + SCHEME_HEADER + s.replace(COLON, COLON_ESCAPE);
}
return path;
}
/** /**
* JxUIPane 的建造者 * JxUIPane 的建造者
* *
@ -492,7 +511,7 @@ public class JxUIPane<T> extends ModernUIPane<T> {
pane.browser.navigation().on(listenerPair.getFirst(), listenerPair.getSecond()); pane.browser.navigation().on(listenerPair.getFirst(), listenerPair.getSecond());
} }
if (StringUtils.isNotEmpty(this.url)) { if (StringUtils.isNotEmpty(this.url)) {
pane.browser.navigation().loadUrl(this.url); pane.browser.navigation().loadUrl(encodeWindowsPath(this.url));
} else if (StringUtils.isNotEmpty(this.html)) { } else if (StringUtils.isNotEmpty(this.html)) {
pane.browser.mainFrame().ifPresent(f -> f.loadHtml(html)); pane.browser.mainFrame().ifPresent(f -> f.loadHtml(html));
} }

10
designer-base/src/main/java/com/fr/design/jxbrowser/NxInterceptRequestCallback.java

@ -20,6 +20,7 @@ import com.teamdev.jxbrowser.net.callback.InterceptUrlRequestCallback;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.InputStream; import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -36,6 +37,8 @@ import static com.fr.design.ui.ModernUIConstants.COMPONENT_TAG;
*/ */
public class NxInterceptRequestCallback implements InterceptUrlRequestCallback { public class NxInterceptRequestCallback implements InterceptUrlRequestCallback {
private static final String COLON_DECODE_ESCAPE = "/:";
private static final String SCHEME_SPLIT = ":/";
private Supplier<AssembleComponent> component; private Supplier<AssembleComponent> component;
private Supplier<Map<String, String>> renderParameterBuild; private Supplier<Map<String, String>> renderParameterBuild;
@ -61,7 +64,7 @@ public class NxInterceptRequestCallback implements InterceptUrlRequestCallback {
@Override @Override
public Response on(Params params) { public Response on(Params params) {
UrlRequest urlRequest = params.urlRequest(); UrlRequest urlRequest = params.urlRequest();
String path = urlRequest.url(); String path = urlRequest.url().replace(COLON_DECODE_ESCAPE, JxUIPane.COLON);
Optional<UrlRequestJob> urlRequestJobOptional; Optional<UrlRequestJob> urlRequestJobOptional;
if (path.startsWith(COMPONENT_TAG)) { if (path.startsWith(COMPONENT_TAG)) {
String text = htmlText(renderParameterBuild.get()); String text = htmlText(renderParameterBuild.get());
@ -107,7 +110,10 @@ public class NxInterceptRequestCallback implements InterceptUrlRequestCallback {
path = path.substring(index + 1); path = path.substring(index + 1);
} else { } else {
// jxbrowser 7之后,协议会自动补齐双斜杠// // jxbrowser 7之后,协议会自动补齐双斜杠//
path = path.split(":/")[1]; int i = path.indexOf(SCHEME_SPLIT);
path = path.substring(i + SCHEME_SPLIT.length());
// 通过自定义协议之后的url会自动encode一些中文字符,这里做一个decode,否则会导致路径访问失败
path = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
} }
return IOUtils.readResource(path); return IOUtils.readResource(path);
} }

17
designer-base/src/main/java/com/fr/design/login/config/DesignerLoginConfigManager.java

@ -75,6 +75,13 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
*/ */
private boolean useOldVersionLogin = false; private boolean useOldVersionLogin = false;
/**
* 是否手动配置过新插件管理
* <li>11.0.18版本开始全部认为没有手动配置过,符合机型的都默认开启新插件管理,如果需要关闭需要再次手动配置</li>
* <li>如果手动配置过则置为false</li>
*/
private boolean useNewPluginFirst = true;
private DesignerLoginConfigManager() { private DesignerLoginConfigManager() {
} }
@ -103,6 +110,7 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
this.setLoginRemindBeforeJumpBBS(reader.getAttrAsBoolean("loginRemindBeforeJumpBBS", true)); this.setLoginRemindBeforeJumpBBS(reader.getAttrAsBoolean("loginRemindBeforeJumpBBS", true));
this.setPluginRemindOnFirstLaunch(reader.getAttrAsBoolean("pluginRemindOnFirstLaunch", true)); this.setPluginRemindOnFirstLaunch(reader.getAttrAsBoolean("pluginRemindOnFirstLaunch", true));
this.setUseOldVersionLogin(reader.getAttrAsBoolean("useOldVersionLogin", false)); this.setUseOldVersionLogin(reader.getAttrAsBoolean("useOldVersionLogin", false));
this.setUseNewPluginFirst(reader.getAttrAsBoolean("useNewPluginFirst", true));
} }
} }
@ -123,6 +131,7 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
writer.attr("loginRemindBeforeJumpBBS", loginRemindBeforeJumpBBS); writer.attr("loginRemindBeforeJumpBBS", loginRemindBeforeJumpBBS);
writer.attr("pluginRemindOnFirstLaunch", pluginRemindOnFirstLaunch); writer.attr("pluginRemindOnFirstLaunch", pluginRemindOnFirstLaunch);
writer.attr("useOldVersionLogin", useOldVersionLogin); writer.attr("useOldVersionLogin", useOldVersionLogin);
writer.attr("useNewPluginFirst", useNewPluginFirst);
writer.end(); writer.end();
} }
@ -237,4 +246,12 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
public void setUseOldVersionLogin(boolean useOldVersionLogin) { public void setUseOldVersionLogin(boolean useOldVersionLogin) {
this.useOldVersionLogin = useOldVersionLogin; this.useOldVersionLogin = useOldVersionLogin;
} }
public boolean isUseNewPluginFirst() {
return useNewPluginFirst;
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
this.useNewPluginFirst = useNewPluginFirst;
}
} }

9
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java

@ -325,7 +325,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
if (VcsHelper.getInstance().needInit()) { if (VcsHelper.getInstance().needInit()) {
vcsAction = new VcsAction(); vcsAction = new VcsAction();
if (!isLegacyOnCluster()) { if (!WorkContext.getCurrent().isCluster()) {
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_Title")); vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_Title"));
} else { } else {
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_NotSupportRemote")); vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_NotSupportRemote"));
@ -509,7 +509,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private void fireVcsActionChange(boolean enable) { private void fireVcsActionChange(boolean enable) {
if (!DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable() if (!DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable()
|| VcsHelper.getInstance().isUnSelectedTemplate() || VcsHelper.getInstance().isUnSelectedTemplate()
|| isLegacyOnCluster()) { || WorkContext.getCurrent().isCluster()) {
setEnabled(false); setEnabled(false);
return; return;
} }
@ -810,11 +810,6 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
} }
} }
private boolean isLegacyOnCluster() {
// 老模式且为集群,用于代替之前的只判断集群逻辑
return WorkContext.getCurrent().isCluster() && VcsHelper.getInstance().isLegacyMode();
}
private String doCheck (String userInput, String suffix) { private String doCheck (String userInput, String suffix) {
String errorMsg = StringUtils.EMPTY; String errorMsg = StringUtils.EMPTY;
if (selectedOperation.duplicated(userInput, suffix, true)) { if (selectedOperation.duplicated(userInput, suffix, true)) {

25
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsConfigManager.java

@ -16,10 +16,6 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
private boolean useInterval = true; private boolean useInterval = true;
private int saveInterval = 60; private int saveInterval = 60;
private boolean useAutoSave = false;
private int autoSaveInterval = 15;
public static VcsConfigManager getInstance() { public static VcsConfigManager getInstance() {
return instance; return instance;
} }
@ -52,23 +48,6 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
return saveInterval; return saveInterval;
} }
public int getAutoSaveInterval() {
return autoSaveInterval;
}
public void setAutoSaveInterval(int autoSaveInterval) {
this.autoSaveInterval = autoSaveInterval;
}
public boolean isUseAutoSave() {
return useAutoSave;
}
public void setUseAutoSave(boolean useAutoSave) {
this.useAutoSave = useAutoSave;
}
public void setSaveInterval(int saveInterval) { public void setSaveInterval(int saveInterval) {
this.saveInterval = saveInterval; this.saveInterval = saveInterval;
} }
@ -80,8 +59,6 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
this.setSaveInterval(reader.getAttrAsInt("saveInterval", 60)); this.setSaveInterval(reader.getAttrAsInt("saveInterval", 60));
this.setUseInterval(reader.getAttrAsBoolean("useInterval", true)); this.setUseInterval(reader.getAttrAsBoolean("useInterval", true));
this.setVcsEnable(reader.getAttrAsBoolean("vcsEnable", true)); this.setVcsEnable(reader.getAttrAsBoolean("vcsEnable", true));
this.setAutoSaveInterval(reader.getAttrAsInt("autoSaveInterval", 15));
this.setUseAutoSave(reader.getAttrAsBoolean("useAutoSave", false));
} }
} }
@ -92,8 +69,6 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
writer.attr("saveInterval", this.getSaveInterval()); writer.attr("saveInterval", this.getSaveInterval());
writer.attr("useInterval", this.isUseInterval()); writer.attr("useInterval", this.isUseInterval());
writer.attr("vcsEnable", this.isVcsEnable()); writer.attr("vcsEnable", this.isVcsEnable());
writer.attr("autoSaveInterval", this.getAutoSaveInterval());
writer.attr("useAutoSave", this.isUseAutoSave());
writer.end(); writer.end();
} }
} }

186
designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java

@ -2,7 +2,6 @@ package com.fr.design.mainframe.vcs.common;
import com.fr.concurrent.NamedThreadFactory; import com.fr.concurrent.NamedThreadFactory;
import com.fr.config.ConfigEvent;
import com.fr.design.DesignerEnvManager; import com.fr.design.DesignerEnvManager;
import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane; import com.fr.design.file.TemplateTreePane;
@ -13,9 +12,6 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.JTemplateActionListener; import com.fr.design.mainframe.JTemplateActionListener;
import com.fr.design.mainframe.vcs.VcsConfigManager; import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.ui.FileVersionTable; import com.fr.design.mainframe.vcs.ui.FileVersionTable;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.ListenerAdaptor;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext; import com.fr.plugin.context.PluginContext;
@ -29,14 +25,11 @@ import com.fr.workspace.server.vcs.filesystem.VcsFileSystem;
import com.fr.workspace.server.vcs.git.config.GcConfig; import com.fr.workspace.server.vcs.git.config.GcConfig;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import java.awt.Color; import java.awt.Color;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/** /**
* Created by XiaXiang on 2019/4/17. * Created by XiaXiang on 2019/4/17.
@ -62,65 +55,10 @@ public class VcsHelper implements JTemplateActionListener {
private final static String SERVICE_NAME_MOVE = "moveVcs"; private final static String SERVICE_NAME_MOVE = "moveVcs";
private static final VcsHelper INSTANCE = new VcsHelper(); private static final VcsHelper INSTANCE = new VcsHelper();
private static ScheduledExecutorService saveSchedule;
private volatile boolean legacyMode;
public static VcsHelper getInstance() { public static VcsHelper getInstance() {
return INSTANCE; return INSTANCE;
} }
private VcsHelper() {
VcsOperator op = WorkContext.getCurrent().get(VcsOperator.class);
// 开了设计器启动页面时一开始取不到VcsOperator,通过下面的切换环境事件再取,这边判断下
if (op != null) {
legacyMode = op.isLegacyMode();
}
EventDispatcher.listen(ConfigEvent.READY, new ListenerAdaptor() {
@Override
protected void on(Event event) {
try {
legacyMode = WorkContext.getCurrent().get(VcsOperator.class).isLegacyMode();
FineLoggerFactory.getLogger().info("[VcsHelper] legacyMode:{}", legacyMode);
} catch (Exception e) {
//保险起见走老逻辑
legacyMode = true;
FineLoggerFactory.getLogger().error("[VcsHelper] get legacy failed", e.getMessage());
}
}
});
}
/**
* 开始自动保存任务
*
* @param interval 时间间隔
*/
public void startAutoSave(int interval) {
stopAutoSave();
saveSchedule = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("VcsAutoSaveSchedule"));
saveSchedule.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
FineLoggerFactory.getLogger().info("[VcsV2] start to run auto save schedule");
JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable() && JTemplate.isValid(template)) {
fireAutoSaveVcs(template);
}
}
}, interval, interval, TimeUnit.MINUTES);
}
/**
* 停止任务
*/
public void stopAutoSave() {
if (saveSchedule != null && !saveSchedule.isShutdown()) {
saveSchedule.shutdown();
}
}
private int containsFolderCounts() { private int containsFolderCounts() {
TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree(); TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree();
if (fileTree.getSelectionPaths() == null) { if (fileTree.getSelectionPaths() == null) {
@ -195,21 +133,24 @@ public class VcsHelper implements JTemplateActionListener {
fireVcs.execute(new Runnable() { fireVcs.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
String fileName = getEditingFilename(); String fileName = getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class); VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0); VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
boolean replace = needDeleteVersion(entity);
int latestFileVersion = 0; int latestFileVersion = 0;
if (entity != null) { if (entity != null) {
latestFileVersion = entity.getVersion(); latestFileVersion = entity.getVersion();
} }
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) { if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace); operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath(); String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
List<VcsEntity> updatedList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY)); FileVersionTable.getInstance().updateModel(1, WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY)));
SwingUtilities.invokeLater(() -> FileVersionTable.getInstance().updateModel(1, updatedList));
} else { } else {
operator.saveVersion(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace); operator.saveVersion(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1);
}
VcsEntity oldEntity = WorkContext.getCurrent().get(VcsOperator.class).getFileVersionByIndexAndUsername(fileName, getCurrentUsername(), 1);
if (needDeleteVersion(oldEntity)) {
operator.deleteVersion(oldEntity.getFilename(), oldEntity.getVersion());
} }
if (GcConfig.getInstance().isGcEnable()) { if (GcConfig.getInstance().isGcEnable()) {
operator.gc(); operator.gc();
@ -217,9 +158,7 @@ public class VcsHelper implements JTemplateActionListener {
} }
}); });
if (!fireVcs.isShutdown()) { fireVcs.shutdown();
fireVcs.shutdown();
}
} }
/** /**
@ -249,85 +188,12 @@ public class VcsHelper implements JTemplateActionListener {
moveVcs.shutdown(); moveVcs.shutdown();
} }
/**
* 判断是否为老模式
* @return 是否为老模式
*/
public boolean isLegacyMode() {
return legacyMode;
}
/**
* 更新当前的legacyMode状态
* <li>目前用在迁移结束后更新模式为新模式</li>
*
*/
public void updateLegacyMode() {
this.legacyMode = !legacyMode;
}
@Override @Override
public void templateOpened(JTemplate<?, ?> jt) { public void templateOpened(JTemplate<?, ?> jt) {
try {
if (checkAutoSaveSupport()) {
startAutoSave(VcsConfigManager.getInstance().getAutoSaveInterval());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
} }
/**
* 响应版本管理自动保存
*
* <li>直接用template的file来保存的话相当于拿源文件来保存模板这样用户做的改动会丢失</li>
* <li>因此需要自己实现一下自动保存的逻辑将当前模板的数据导出,再拿这个Byte[]去做我们需要的保存处理</li>
* <li>保存后需要触发清理逻辑</li>
*
* @param jt 模板
*/
public void fireAutoSaveVcs(final JTemplate jt) {
String fileName = getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
boolean replace = needDeleteVersion(entity);
int latestFileVersion = 0;
if (entity != null) {
latestFileVersion = entity.getVersion();
}
if (JTemplate.isValid(jt)) {
doSave(jt, fileName, latestFileVersion, replace, operator);
}
}
private void doSave(JTemplate jt, String fileName, int latestFileVersion, boolean replace, VcsOperator operator) {
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
List<VcsEntity> updatedList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY));
SwingUtilities.invokeLater(() -> FileVersionTable.getInstance().updateModel(1, updatedList));
} else {
autoSave(jt, getCurrentUsername(), fileName, latestFileVersion + 1, replace, operator);
}
if (GcConfig.getInstance().isGcEnable()) {
operator.gc();
}
}
private void autoSave(JTemplate jt, String currentUsername, String fileName, int nowVersion, boolean replace, VcsOperator operator) {
try {
if (JTemplate.isValid(jt)) {
operator.autoSave(currentUsername, fileName, StringUtils.EMPTY, nowVersion, jt.exportData(), replace);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/** /**
* 模板保存时 处理. * 模板保存时 处理.
* *
@ -344,40 +210,6 @@ public class VcsHelper implements JTemplateActionListener {
@Override @Override
public void templateClosed(JTemplate<?, ?> jt) { public void templateClosed(JTemplate<?, ?> jt) {
try {
if (checkAutoSaveSupport()) {
stopAutoSave();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 判断是否支持V2功能
*
* @return 支持返回true
*/
public boolean checkV2FunctionSupport() {
return !VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
}
/**
* 判断是否支持迁移功能
*
* @return 支持返回true
*/
public boolean checkMoveFunctionSupport() {
return VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
}
/**
* 是否支持自动保存
*
* @return 支持返回true
*/
public boolean checkAutoSaveSupport() {
return VcsConfigManager.getInstance().isUseAutoSave() && !VcsHelper.getInstance().isLegacyMode();
} }
} }

406
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java

@ -1,406 +0,0 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.vcs.v2.move.VcsMoveService;
import com.fr.workspace.server.vcs.v2.move.VcsMoveStrategy;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 迁移面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/13
*/
public class VcsMovePanel extends BasicPane {
private static final FRFont FONT = DesignUtils
.getDefaultGUIFont()
.applySize(14)
.applyStyle(FRFont.BOLD);
private static final Color BACK_GROUND_COLOR = new Color(202,232,255);
//提示字体的颜色,直接模仿其他面板的写法
private static final Color TIP_COLOR = new Color(51, 51, 52, (int)Math.round(0.5 * 255));
private static final Color LABEL_COLOR = new Color(34,149,233);
private static final int MIN_VALUE = 1;
private static final int MAX_VALUE = 999;
private static final int STEP = 1;
private static final int DEFAULT_VALUE = 5;
public static final String SETTING = "SETTING";
public static final String PROCESS = "PROCESS";
public static final String SUCCESS = "SUCCESS";
public static final String FAILED = "FAILED";
public static boolean moving = false;
private UILabel vcsUpdateExistLabel;
private UILabel vcsUpdateFireLabel;
private BasicPane choosePane;
private CardLayout parentCard;
private JPanel parentPane;
private static final JProgressBar PROGRESS_BAR = new JProgressBar();
private JPanel progressPanel;
private UILabel tipLabel;
private UIButton successButton;
private UILabel iconLabel;
private UILabel successLabel;
private UILabel successTipLabel;
private UIButton failedButton;
private UILabel failedIconLabel;
private UILabel failedLabel;
private UILabel failedTipLabel;
//保留全部
private UIRadioButton moveAllButton;
//默认选项,保留部分
private UIRadioButton moveDefaultButton;
//全部放弃
private UIRadioButton moveNothingButton;
private UISpinner spinner;
private MoveCallBack callBack;
private JPanel updatePane;
private boolean visible = false;
public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack) {
this.parentCard = cardLayout;
this.parentPane = parentPane;
this.callBack = callBack;
this.setLayout(new BorderLayout());
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.setBackground(BACK_GROUND_COLOR);
//初始化迁移的面板
initVcsLabel(updatePane);
//initVcsChoosePane
initVcsChoosePane();
//初始化listener
initListener();
this.add(updatePane);
checkVisible();
//如果已经在迁移
if (VcsMoveService.getInstance().isMoving()) {
initProcessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), PROCESS);
}
}
private void checkVisible() {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return VcsHelper.getInstance().checkMoveFunctionSupport();
}
@Override
protected void done() {
try {
boolean useMove = get();
VcsMovePanel.this.setVisible(useMove);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
private void initProcessPane() {
JPanel processPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
PROGRESS_BAR.setStringPainted(true);
PROGRESS_BAR.setUI(new ModernUIProgressBarUI());
PROGRESS_BAR.setBorderPainted(false);
PROGRESS_BAR.setOpaque(false);
PROGRESS_BAR.setBorder(null);
PROGRESS_BAR.setSize(BasicDialog.MEDIUM);
body.add(PROGRESS_BAR);
body.add(new UILabel(StringUtils.BLANK));
tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_While_Moving"));
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
body.add(tipLabel);
processPane.add(body);
processPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
parentPane.add(processPane, PROCESS);
}
private void initVcsChoosePane() {
choosePane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Vcs_Deal_With_Entry");
}
};
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
layout.setAlignLeft(true);
choosePane.setLayout(layout);
//初始化上方的文字板块
initTopDesc();
//初始化中间区域的单选框
initRadioButton();
//初始化下方的Tip描述
initTipDesc();
}
private void initTopDesc() {
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_How_To_Deal_With_Entry"));
choosePane.add(label);
}
private void initTipDesc() {
UILabel descLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Desc"));
descLabel.setForeground(TIP_COLOR);
choosePane.add(descLabel);
}
private void initRadioButton() {
//保留全部
moveAllButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_All"));
//默认选项,保留部分
moveDefaultButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Default"));
//全部放弃
moveNothingButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Nothing"));
// 将按钮"保留部分"设置为选中状态
moveDefaultButton.setSelected(true);
// 创建一个按钮组,添加三个按钮
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(moveAllButton);
buttonGroup.add(moveDefaultButton);
buttonGroup.add(moveNothingButton);
JPanel moveDefaultPanel = new JPanel();
JPanel moveAllPane = new JPanel();
JPanel moveNothingPane = new JPanel();
moveAllPane.add(moveAllButton);
moveDefaultPanel.add(moveDefaultButton);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Left")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
moveDefaultPanel.add(spinner);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Right")));
moveNothingPane.add(moveNothingButton);
choosePane.add(moveAllPane);
choosePane.add(moveDefaultPanel);
choosePane.add(moveNothingPane);
}
private void initVcsLabel(JPanel parent) {
vcsUpdateExistLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/vcs_move_icon.svg"));
vcsUpdateExistLabel.setText(Toolkit.i18nText("Fine-Design_Vcs_Can_Update"));
vcsUpdateFireLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Update"));
vcsUpdateFireLabel.setForeground(LABEL_COLOR);
vcsUpdateFireLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
parent.add(vcsUpdateExistLabel);
parent.add(vcsUpdateFireLabel);
}
private void initListener() {
vcsUpdateFireLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
BasicDialog dlg = choosePane.showMediumWindow(SwingUtilities.getWindowAncestor(VcsMovePanel.this), new DialogActionAdapter() {
@Override
public void doOk() {
//进度条面板
initProcessPane();
VcsMovePanel.this.getParentCard().next(getParentPane());
VcsMoveStrategy strategy;
if (moveDefaultButton.isSelected()) {
strategy = VcsMoveStrategy.createNumStrategy((int) spinner.getValue());
} else if (moveNothingButton.isSelected()) {
strategy = VcsMoveStrategy.ALL_GIVE_UP;
} else {
strategy = VcsMoveStrategy.ALL_RETAIN;
}
new MoveWorker(strategy).execute();
}
});
dlg.setVisible(true);
}
});
}
private void initSuccessPane() {
JPanel successPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
successButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Success_Go"));
initSuccessButtonListener();
iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_success.svg"));
successLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Success"));
successLabel.setFont(FONT);
successTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Success_Tip"));
initStatusPane(successTipLabel, iconLabel, successLabel, successButton, body, SUCCESS, successPane);
}
private void initSuccessButtonListener() {
successButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAfterMove();
}
});
}
private void initFailedButtonListener() {
failedButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAfterMove();
}
});
}
private void doAfterMove() {
visible = !VcsHelper.getInstance().isLegacyMode();
updatePane.setVisible(!visible);
callBack.doCallBack(visible);
parentCard.show(parentPane, SETTING);
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
public CardLayout getParentCard() {
return parentCard;
}
public JPanel getParentPane() {
return parentPane;
}
private void initFailedPane() {
JPanel failedPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
failedButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Go"));
initFailedButtonListener();
failedIconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_failed.svg"));
failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed"));
failedLabel.setFont(FONT);
failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip"));
initStatusPane(failedTipLabel, failedIconLabel, failedLabel, failedButton, body, FAILED, failedPane);
}
private void initStatusPane(UILabel tipLabel, UILabel iconLabel, UILabel label, UIButton button, JPanel body, String tag,JPanel statusPane) {
tipLabel.setForeground(TIP_COLOR);
body.add(iconLabel);
body.add(new UILabel(StringUtils.BLANK));
body.add(label);
body.add(new UILabel(StringUtils.BLANK));
body.add(tipLabel);
body.add(new UILabel(StringUtils.BLANK));
body.add(button);
statusPane.add(body);
statusPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
parentPane.add(statusPane, tag);
iconLabel.setAlignmentX(CENTER_ALIGNMENT);
label.setAlignmentX(CENTER_ALIGNMENT);
button.setAlignmentX(CENTER_ALIGNMENT);
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
}
private class MoveWorker extends SwingWorker<Void, Integer> {
private VcsMoveStrategy strategy;
public MoveWorker(VcsMoveStrategy strategy) {
this.strategy = strategy;
}
@Override
protected Void doInBackground() throws Exception {
try {
//开始迁移
VcsMoveService.getInstance().startMove(new VcsMoveService.BaseMoveServiceWhileMoving() {
@Override
public void publishProgress() {
int num = VcsMoveService.getInstance().getCurrentMove();
publish(num);
}
@Override
public void prepare4Move() {
PROGRESS_BAR.setMaximum(VcsMoveService.getInstance().getTotal());
}
}, strategy);
} catch (Exception e) {
this.cancel(true);
VcsMoveService.getInstance().stopMoving();
initFailedPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), FAILED);
FineLoggerFactory.getLogger().error("[VcsV2] Vcs move failed!");
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
PROGRESS_BAR.setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
VcsMoveService.getInstance().stopMoving();
initSuccessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), SUCCESS);
VcsHelper.getInstance().updateLegacyMode();
}
}
/**
* 迁移回调事件
*
*/
public static class MoveCallBack {
/**
* 处理回调
*/
public void doCallBack(boolean visible){}
}
}

12
designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java

@ -24,12 +24,18 @@ public class PMDialogAction implements OSBasedAction {
DesignUtils.visitEnvServerByParameters( PLUGIN_MANAGER_ROUTE,null,null); DesignUtils.visitEnvServerByParameters( PLUGIN_MANAGER_ROUTE,null,null);
return; return;
} }
if (ServerPreferenceConfig.getInstance().isUseOptimizedUPM() if (checkUPMSupport()) {
|| SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter()) {
UpmFinder.showUPMDialog(); UpmFinder.showUPMDialog();
} else { } else {
WebViewDlgHelper.createPluginDialog(); WebViewDlgHelper.createPluginDialog();
} }
} }
private boolean checkUPMSupport() {
return ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter()
//默认开启
|| DesignerEnvManager.getEnvManager().isUseNewPluginFirst();
}
} }

7
designer-base/src/main/java/com/fr/design/upm/UpmBridge.java

@ -306,7 +306,12 @@ public class UpmBridge {
@JSBridge @JSBridge
public void setAllPluginActive(JSArray pluginIDs, final JSFunction callback) { public void setAllPluginActive(JSArray pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginOperateUtils.setPluginActive(pluginIDs, jsCallback); List<String> list = new ArrayList<>();
int len = pluginIDs.length();
for (int i = 0; i < len; i++) {
list.add(pluginIDs.get(i).asString().getValue());
}
PluginOperateUtils.setPluginActive(list, jsCallback);
} }
/** /**

17
designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java

@ -28,7 +28,7 @@ import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.js.JsAccessible; import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsFunction; import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject; import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.js.internal.JsArrayImpl;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
@ -265,6 +265,21 @@ public class UpmBridgeV7 extends UpmBridge {
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback); PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
} }
/**
* 批量修改选中的插件的活跃状态
*
* @param pluginIDs 要处理的插件ID
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void setAllPluginActive(JsObject pluginIDs, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
List array = ((JsArrayImpl) pluginIDs).toList();
PluginOperateUtils.setPluginActive(array, jsCallback);
}
/** /**
* 从插件服务器上安装插件 * 从插件服务器上安装插件
* *

5
designer-base/src/main/resources/com/fr/design/vcs/move_failed.svg

@ -1,5 +0,0 @@
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M32 60.5C16.536 60.5 4 47.964 4 32.5C4 17.036 16.536 4.5 32 4.5C47.464 4.5 60 17.036 60 32.5C60 47.964 47.464 60.5 32 60.5Z" fill="#EB1D1F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M44 24.1928L23.692 44.4995L20 40.8075L40.308 20.4995L44 24.1928Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.308 44.5L20 24.1933L23.692 20.5L44 40.8067L40.308 44.5Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 549 B

5
designer-base/src/main/resources/com/fr/design/vcs/move_success.svg

@ -1,5 +0,0 @@
<svg width="58" height="59" viewBox="0 0 58 59" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 58.5C12.9837 58.5 0 45.5163 0 29.5C0 13.4837 12.9837 0.5 29 0.5C45.0163 0.5 58 13.4837 58 29.5C58 45.5163 45.0163 58.5 29 58.5Z" fill="#16C153"/>
<rect x="20.66" y="39.8213" width="32.1738" height="5.52381" transform="rotate(-45 20.66 39.8213)" fill="white"/>
<rect x="14.9535" y="26.7378" width="18.7954" height="5.52381" transform="rotate(45 14.9535 26.7378)" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 533 B

3
designer-base/src/main/resources/com/fr/design/vcs/vcs_move_icon.svg

@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 8C15 4.13435 11.8656 1 8 1C4.13435 1 1 4.13435 1 8C1 11.8656 4.13435 15 8 15C11.8656 15 15 11.8656 15 8ZM7.43333 5.70798C7.27778 5.55242 7.2 5.36353 7.2 5.14131C7.2 4.91909 7.27778 4.7302 7.43333 4.57464C7.58889 4.41909 7.77778 4.34131 8 4.34131C8.22222 4.34131 8.41111 4.41909 8.56667 4.57464C8.72222 4.7302 8.8 4.91909 8.8 5.14131C8.8 5.36353 8.72222 5.55242 8.56667 5.70798C8.41111 5.86353 8.22222 5.94131 8 5.94131C7.77778 5.94131 7.58889 5.86353 7.43333 5.70798ZM8 11.7787C7.6134 11.7787 7.3 11.4653 7.3 11.0787V7.47868C7.3 7.09208 7.6134 6.77868 8 6.77868C8.3866 6.77868 8.7 7.09208 8.7 7.47868V11.0787C8.7 11.4653 8.3866 11.7787 8 11.7787Z" fill="#419BF9"/>
</svg>

Before

Width:  |  Height:  |  Size: 821 B

Loading…
Cancel
Save