Browse Source

Merge pull request #4711 in DESIGN/design from feature/10.0 to feature/x

* commit 'b5c77640343f9620514516047daa193b4006770d':
  REPORT-53647  下载路由修改
  REPORT-51958 设计器通知中心调整
research/11.0
superman 3 years ago
parent
commit
af7771fb67
  1. 28
      designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java
  2. 3
      designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java
  3. 40
      designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java
  4. 19
      designer-base/src/main/java/com/fr/design/login/message/NotificationActionType.java
  5. 21
      designer-base/src/main/java/com/fr/design/notification/Notification.java
  6. 158
      designer-base/src/main/java/com/fr/design/notification/ui/NotificationCenterDialog.java
  7. 4
      designer-base/src/main/java/com/fr/design/notification/ui/NotificationCenterPane.java
  8. 148
      designer-base/src/main/java/com/fr/design/notification/ui/NotificationPane.java
  9. 6
      designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java
  10. 2
      designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java

28
designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java

@ -9,6 +9,7 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.notification.Notification;
import com.fr.design.notification.NotificationCenter;
import com.fr.module.ModuleContext;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
@ -43,17 +44,17 @@ public class NotificationDialog extends JDialog {
public NotificationDialog(Frame owner, String title, boolean isModal, int messageType, String message, NotificationDialogAction action) {
super(owner);
setTitle(title);
initComponents(messageType, message, isModal, action);
initComponents(StringUtils.EMPTY, messageType, message, isModal, action);
}
public NotificationDialog(Builder builder) {
super(builder.owner);
setTitle(builder.title);
initComponents(builder.messageType, builder.message, builder.modal, builder.action);
initComponents(builder.messageId, builder.messageType, builder.message, builder.modal, builder.action);
}
public void initComponents(int messageType, String message, boolean isModal, NotificationDialogAction action) {
NotificationCenter.getInstance().addNotification(new Notification(messageType, message, action));
public void initComponents(String messageId, int messageType, String message, boolean isModal, NotificationDialogAction action) {
NotificationCenter.getInstance().addNotification(new Notification(messageId, messageType, message, action));
notificationDialogAction = action;
setModal(isModal);
setFocusable(false);
@ -173,6 +174,7 @@ public class NotificationDialog extends JDialog {
public static final class Builder {
public int messageType = WARNING_MESSAGE;
public String messageId;
public String message;
public boolean modal = true;
public Frame owner = null;
@ -187,6 +189,11 @@ public class NotificationDialog extends JDialog {
return new NotificationDialog(this);
}
public Builder messageId(String messageId) {
this.messageId = messageId;
return this;
}
public Builder owner(Frame owner) {
this.owner = owner;
return this;
@ -217,4 +224,17 @@ public class NotificationDialog extends JDialog {
return this;
}
}
public static void defaultPopup(String messageId, String title, String body, NotificationDialogAction action) {
NotificationDialog.Builder()
.messageId(messageId)
.owner(DesignerContext.getDesignerFrame())
.title(title)
.modal(false)
.messageType(NotificationDialog.NEW_MESSAGE)
.message(body)
.notificationDialogAction(action)
.build()
.setVisible(true);
}
}

3
designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java

@ -1,5 +1,8 @@
package com.fr.design.dialog;
public interface NotificationDialogAction {
String name();
void doClick();
}

40
designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java

@ -59,7 +59,7 @@ public class DesignerMessageHelper {
@Override
public void run() {
try {
pullLatestMessageAndShow();
pullLatestMessage();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -70,7 +70,7 @@ public class DesignerMessageHelper {
});
}
private void pullLatestMessageAndShow() throws Exception {
private void pullLatestMessage() throws Exception {
String url = CloudCenter.getInstance().acquireUrlByKind("designer.message.push", "https://market.fanruan.com/api/v1/message/designer");
Map<String, String> params = new HashMap<>();
params.put("designerId", DesignerEnvManager.getEnvManager().getUUID());
@ -78,7 +78,11 @@ public class DesignerMessageHelper {
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
String status = response.optString(STATUS);
if (SUCCESS.equals(status)) {
JSONObject data = response.optJSONObject(DATA);
parseLatestMessage(response.optJSONObject(DATA));
}
}
private void parseLatestMessage(JSONObject data) {
String messageId = data.optString(MESSAGE_ID);
String title = data.optString(TITLE);
String body = data.optString(BODY);
@ -87,33 +91,21 @@ public class DesignerMessageHelper {
if (StringUtils.isNotEmpty(messageId) && StringUtils.isNotEmpty(title) && StringUtils.isNotEmpty(body) && jumpType > 0 && StringUtils.isNotEmpty(jumpTo)) {
NotificationJumpType notificationJumpType = NotificationJumpType.valueOf(jumpType);
if (notificationJumpType == NotificationJumpType.WEB_URL) {
NotificationDialog.Builder()
.owner(DesignerContext.getDesignerFrame())
.title(title)
.modal(false)
.messageType(NotificationDialog.NEW_MESSAGE)
.message(body)
.notificationDialogAction(new NotificationDialogAction() {
NotificationDialog.defaultPopup(messageId, title, body, new NotificationDialogAction() {
@Override
public String name() {
return jumpTo;
}
@Override
public void doClick() {
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(jumpTo);
BrowseUtils.browser(ssoUrl);
}
})
.build()
.setVisible(true);
});
} else if (notificationJumpType == NotificationJumpType.DESIGNER_MODULE) {
DesignerModuleClickType designerModuleClickType = DesignerModuleClickType.valueOf(jumpTo);
NotificationDialog.Builder()
.owner(DesignerContext.getDesignerFrame())
.title(title)
.modal(false)
.messageType(NotificationDialog.NEW_MESSAGE)
.message(body)
.notificationDialogAction(designerModuleClickType.getAction())
.build()
.setVisible(true);
}
NotificationActionType notificationActionType = NotificationActionType.valueOf(jumpTo);
NotificationDialog.defaultPopup(messageId, title, body, notificationActionType.getAction());
}
}
}

19
designer-base/src/main/java/com/fr/design/login/message/DesignerModuleClickType.java → designer-base/src/main/java/com/fr/design/login/message/NotificationActionType.java

@ -21,8 +21,13 @@ import com.fr.stable.os.OperatingSystem;
* @version 10.0
* Created by Lanlan on 2021/6/11
*/
public enum DesignerModuleClickType {
public enum NotificationActionType {
PLUGIN("PLUGIN", new NotificationDialogAction() {
@Override
public String name() {
return "PLUGIN";
}
@Override
public void doClick() {
try {
@ -41,6 +46,11 @@ public enum DesignerModuleClickType {
}
}),
REUSE("REUSE", new NotificationDialogAction() {
@Override
public String name() {
return "REUSE";
}
@Override
public void doClick() {
try {
@ -54,6 +64,11 @@ public enum DesignerModuleClickType {
}
}),
UNKNOWN(StringUtils.EMPTY, new NotificationDialogAction() {
@Override
public String name() {
return "UNKNOWN";
}
@Override
public void doClick() {
}
@ -62,7 +77,7 @@ public enum DesignerModuleClickType {
private String jumpTo;
private NotificationDialogAction action;
DesignerModuleClickType(String jumpTo, NotificationDialogAction action) {
NotificationActionType(String jumpTo, NotificationDialogAction action) {
this.jumpTo = jumpTo;
this.action = action;
}

21
designer-base/src/main/java/com/fr/design/notification/Notification.java

@ -1,24 +1,33 @@
package com.fr.design.notification;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.stable.StringUtils;
public class Notification {
private String messageId;
private int type;
private String message;
private NotificationDialogAction notificationDialogAction;
public static final int ERROR_MESSAGE = 0;
public static final int NEW_MESSAGE = 1;
public static final int WARNING_MESSAGE = 2;
public Notification(int type,String message,NotificationDialogAction notificationDialogAction){
public Notification(String messageId, int type, String message, NotificationDialogAction notificationDialogAction) {
this.messageId = messageId;
this.type = type;
this.message = message;
this.notificationDialogAction = notificationDialogAction;
}
public Notification(String message){
public Notification(String message) {
this.type = WARNING_MESSAGE;
this.message = message;
this.notificationDialogAction = new NotificationDialogAction() {
@Override
public String name() {
return StringUtils.EMPTY;
}
@Override
public void doClick() {
//do nothing
@ -30,11 +39,15 @@ public class Notification {
return notificationDialogAction;
}
public int getType(){
public int getType() {
return type;
}
public String getMessage(){
public String getMessage() {
return message;
}
public String getMessageId() {
return messageId;
}
}

158
designer-base/src/main/java/com/fr/design/notification/ui/NotificationCenterDialog.java

@ -1,30 +1,24 @@
package com.fr.design.notification.ui;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.notification.Notification;
import com.fr.design.notification.NotificationCenter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class NotificationCenterDialog extends JDialog {
private ArrayList<NotificationPane> notificationNeedShow;
@ -32,7 +26,9 @@ public class NotificationCenterDialog extends JDialog {
private UILabel deleteLabel;
private static final int NOTIFICATIONCOUNT = 5;
public NotificationCenterDialog(Frame parent) {
private static NotificationCenterDialog instance;
private NotificationCenterDialog(Frame parent) {
super(parent);
setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Notification"));
setResizable(false);
@ -46,7 +42,14 @@ public class NotificationCenterDialog extends JDialog {
initComponents();
}
public void initComponents() {
public static NotificationCenterDialog getInstance() {
if (instance == null) {
instance = new NotificationCenterDialog(DesignerContext.getDesignerFrame());
}
return instance;
}
private void initComponents() {
centerPanel = FRGUIPaneFactory.createNColumnGridInnerContainer_S_Pane(1);
addNotification();
deleteLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Clear_Notifications") + "(" + NotificationCenter.getInstance().getNotificationsCount() + ")");
@ -74,11 +77,27 @@ public class NotificationCenterDialog extends JDialog {
centerWindow();
}
private void hideDialog() {
public ArrayList<NotificationPane> getNotificationNeedShow() {
return notificationNeedShow;
}
public JPanel getCenterPanel() {
return centerPanel;
}
public UILabel getDeleteLabel() {
return deleteLabel;
}
public void showDialog() {
this.setVisible(true);
}
public void hideDialog() {
this.dispose();
}
private void addNotification() {
public void addNotification() {
notificationNeedShow.clear();
int size = NotificationCenter.getInstance().getNotificationsCount();
@ -86,7 +105,7 @@ public class NotificationCenterDialog extends JDialog {
int j = size - i;
if (j >= 0) {
Notification notification = NotificationCenter.getInstance().getNotification(j);
NotificationPane notificationPane = new NotificationPane(notification.getType(), notification.getMessage(), i, notification.getNotificationDialogAction());
NotificationPane notificationPane = new NotificationPane(this, notification.getMessageId(), notification.getType(), notification.getMessage(), i, notification.getNotificationDialogAction());
notificationNeedShow.add(notificationPane);
}
}
@ -111,119 +130,4 @@ public class NotificationCenterDialog extends JDialog {
//这里设置位置:水平居中,竖直偏上
win.setLocation(screenSize.width - winSize.width - 90, 50);
}
/**
* 一条消息面板
*/
class NotificationPane extends JPanel {
private int index;
private UILabel messageLabel;
private UILabel messageIcon;
private NotificationDialogAction notificationDialogAction;
public NotificationPane(int type, String message, int index, NotificationDialogAction notificationDialogAction) {
this.index = index;
this.notificationDialogAction = notificationDialogAction;
this.setLayout(FRGUIPaneFactory.createBorderLayout());
setTypeIcon(getIconForType(type));
setNotification(message);
setDeleteIcon();
}
public void setTypeIcon(Icon icon) {
messageIcon = new UILabel(icon);
messageIcon.addMouseListener(messageAndIconListener);
JPanel messageIconPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
messageIconPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
messageIconPanel.add(messageIcon);
add(messageIconPanel, BorderLayout.WEST);
}
public void setDeleteIcon() {
UILabel deleteIcon = new UILabel(UIManager.getIcon("OptionPane.deleteIcon"));
JPanel deleteIconPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
deleteIconPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 7));
deleteIconPane.add(deleteIcon);
deleteIconPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
NotificationCenter.getInstance().removeNotification(NotificationCenter.getInstance().getNotificationsCount() - index);
centerPanel.removeAll();
addNotification();
deleteLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Clear_Notifications") + "(" + NotificationCenter.getInstance().getNotificationsCount() + ")");
pack();
if (notificationNeedShow.size() == 0) {
hideDialog();
}
NotificationCenterPane.getNotificationCenterPane().refreshButton();
}
@Override
public void mouseEntered(MouseEvent e) {
deleteIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public void mouseExited(MouseEvent e) {
deleteIcon.setCursor(Cursor.getDefaultCursor());
}
});
add(deleteIconPane, BorderLayout.EAST);
}
public int getIndex() {
return index;
}
public void setNotification(String message) {
messageLabel = new UILabel("<html>" + message + "</html>");
messageLabel.addMouseListener(messageAndIconListener);
JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
labelPanel.add(messageLabel);
this.add(labelPanel, BorderLayout.CENTER);
}
protected Icon getIconForType(int messageType) {
String propertyName;
switch (messageType) {
case 0:
propertyName = "OptionPane.circularErrorIcon";
break;
case 1:
propertyName = "OptionPane.newMessageIcon";
break;
case 2:
propertyName = "OptionPane.circularWarningIcon";
break;
default:
return null;
}
return UIManager.getIcon(propertyName);
}
private MouseListener messageAndIconListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
hideDialog();
notificationDialogAction.doClick();
}
@Override
public void mouseEntered(MouseEvent e) {
messageLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
messageIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
messageLabel.setForeground(new Color(250, 170, 57));
}
@Override
public void mouseExited(MouseEvent e) {
messageLabel.setCursor(Cursor.getDefaultCursor());
messageIcon.setCursor(Cursor.getDefaultCursor());
messageLabel.setForeground(Color.BLACK);
}
};
}
}

4
designer-base/src/main/java/com/fr/design/notification/ui/NotificationCenterPane.java

@ -4,7 +4,6 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.notification.NotificationCenter;
import com.fr.general.IOUtils;
import java.awt.BorderLayout;
@ -28,8 +27,7 @@ public class NotificationCenterPane extends BasicPane {
notificationCenterButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
NotificationCenterDialog notificationCenterDialog = new NotificationCenterDialog(DesignerContext.getDesignerFrame());
notificationCenterDialog.setVisible(true);
NotificationCenterDialog.getInstance().showDialog();
}
});
this.setBackground(UIConstants.TEMPLATE_TAB_PANE_BACKGROUND);

148
designer-base/src/main/java/com/fr/design/notification/ui/NotificationPane.java

@ -0,0 +1,148 @@
package com.fr.design.notification.ui;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.notification.NotificationCenter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.UIManager;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/21
*/
public class NotificationPane extends JPanel {
private NotificationCenterDialog parent;
private String messageId;
private int index;
private UILabel messageLabel;
private UILabel messageIcon;
private NotificationDialogAction notificationDialogAction;
public NotificationPane(NotificationCenterDialog parent, String messageId, int type, String message, int index, NotificationDialogAction notificationDialogAction) {
this.parent = parent;
this.index = index;
this.messageId = messageId;
this.notificationDialogAction = notificationDialogAction;
this.setLayout(FRGUIPaneFactory.createBorderLayout());
setTypeIcon(getIconForType(type));
setNotification(message);
setDeleteIcon();
}
public void setTypeIcon(Icon icon) {
messageIcon = new UILabel(icon);
messageIcon.addMouseListener(messageAndIconListener);
JPanel messageIconPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
messageIconPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
messageIconPanel.add(messageIcon);
add(messageIconPanel, BorderLayout.WEST);
}
public void setDeleteIcon() {
UILabel deleteIcon = new UILabel(UIManager.getIcon("OptionPane.deleteIcon"));
JPanel deleteIconPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
deleteIconPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 7));
deleteIconPane.add(deleteIcon);
deleteIconPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
NotificationCenter.getInstance().removeNotification(NotificationCenter.getInstance().getNotificationsCount() - index);
parent.getCenterPanel().removeAll();
parent.addNotification();
parent.getDeleteLabel().setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Clear_Notifications") + "(" + NotificationCenter.getInstance().getNotificationsCount() + ")");
parent.pack();
if (parent.getNotificationNeedShow().size() == 0) {
parent.hideDialog();
}
NotificationCenterPane.getNotificationCenterPane().refreshButton();
}
@Override
public void mouseEntered(MouseEvent e) {
deleteIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public void mouseExited(MouseEvent e) {
deleteIcon.setCursor(Cursor.getDefaultCursor());
}
});
add(deleteIconPane, BorderLayout.EAST);
}
public int getIndex() {
return index;
}
public String getMessageId() {
return messageId;
}
public NotificationDialogAction getNotificationDialogAction() {
return notificationDialogAction;
}
public void setNotification(String message) {
messageLabel = new UILabel("<html>" + message + "</html>");
messageLabel.addMouseListener(messageAndIconListener);
JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
labelPanel.add(messageLabel);
this.add(labelPanel, BorderLayout.CENTER);
}
protected Icon getIconForType(int messageType) {
String propertyName;
switch (messageType) {
case 0:
propertyName = "OptionPane.circularErrorIcon";
break;
case 1:
propertyName = "OptionPane.newMessageIcon";
break;
case 2:
propertyName = "OptionPane.circularWarningIcon";
break;
default:
return null;
}
return UIManager.getIcon(propertyName);
}
private void performTargetAction() {
parent.hideDialog();
notificationDialogAction.doClick();
}
private MouseListener messageAndIconListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
performTargetAction();
}
@Override
public void mouseEntered(MouseEvent e) {
messageLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
messageIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
messageLabel.setForeground(new Color(250, 170, 57));
}
@Override
public void mouseExited(MouseEvent e) {
messageLabel.setCursor(Cursor.getDefaultCursor());
messageIcon.setCursor(Cursor.getDefaultCursor());
messageLabel.setForeground(Color.BLACK);
}
};
}

6
designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java

@ -10,7 +10,6 @@ import com.fr.design.env.RemoteWorkspace;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.env.CheckServiceDialog;
import com.fr.env.VersionCheckMessageDialog;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.invoke.Reflect;
@ -74,6 +73,11 @@ public class VersionCheckUtils {
if (!VersionCheckUtils.versionCheck(envName)) {
NotificationDialog notificationDialog = new NotificationDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Prompt"),
false, NotificationDialog.WARNING_MESSAGE, Toolkit.i18nText("Fine-Design_Basic_Sync_Check_Brief_Info"), new NotificationDialogAction() {
@Override
public String name() {
return "VERSION_CHECK";
}
@Override
public void doClick() {
CheckServiceDialog checkServiceDialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), GeneralUtils.readFullBuildNO(), getRemoteBranch(envName),getNoExistServiceDescription(envName));

2
designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java

@ -35,7 +35,7 @@ import java.security.spec.X509EncodedKeySpec;
* created by Harrison on 2020/05/27
**/
public class DownloadUtils {
private static final String REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "file/";
private static final String REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "file/download";
private static final String PACKAGE_REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "package/download/";
private static final String CERTIFICATE_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtsz62CPSWXZE/IYZRiAuTSZkw\n" +
"1WOwer8+JFktK0uKLAUuQoBr+UjAMFtRA8W7JgKMDwZy/2liEAiXEOSPU/hrdV8D\n" +

Loading…
Cancel
Save