1 module dls.protocol.messages.window; 2 3 import dls.protocol.interfaces : MessageActionItem; 4 5 void showMessageRequest(string id, MessageActionItem item) 6 { 7 import dls.tools.tools : Tools; 8 import dls.util.uri : Uri; 9 import std.concurrency : locate, receiveOnly, send; 10 import std.path : dirName; 11 import std.process : browse; 12 13 while (!(id in Util.messageRequestInfo)) 14 { 15 auto data = receiveOnly!(Util.ThreadMessageData)(); 16 Util.addMessageRequestType(data[0], data[1], data[2]); 17 } 18 19 final switch (Util.messageRequestInfo[id][0]) 20 { 21 case Util.ShowMessageRequestType.upgradeSelections: 22 if (item.title.length > 0) 23 { 24 auto uri = new Uri(Util.messageRequestInfo[id][1]); 25 Tools.symbolTool.upgradeSelections(uri); 26 } 27 28 break; 29 30 case Util.ShowMessageRequestType.upgradeDls: 31 send(locate(Util.messageRequestInfo[id][1]), item.title.length > 0); 32 break; 33 34 case Util.ShowMessageRequestType.showChangelog: 35 if (item.title.length > 0) 36 { 37 browse(Util.messageRequestInfo[id][1]); 38 } 39 40 break; 41 } 42 43 Util.messageRequestInfo.remove(id); 44 } 45 46 abstract class Util 47 { 48 import dls.protocol.interfaces : MessageType; 49 import dls.protocol.jsonrpc : send; 50 import std.array : array, replace; 51 import std.algorithm : map; 52 import std.conv : to; 53 import std.json : JSONValue, parseJSON; 54 import std.typecons : Tuple, tuple; 55 56 static enum ShowMessageType 57 { 58 dlsBuildError = "dlsBuildError", 59 dlsLinkError = "dlsLinkError" 60 } 61 62 static enum ShowMessageRequestType 63 { 64 upgradeSelections = "upgradeSelections", 65 upgradeDls = "upgradeDls", 66 showChangelog = "showChangelog" 67 } 68 69 shared alias ThreadMessageData = Tuple!(string, ShowMessageRequestType, string); 70 71 private enum translationsJson = import("translations.json"); 72 private static JSONValue translations; 73 private static string locale; 74 private static Tuple!(ShowMessageRequestType, string)[string] messageRequestInfo; 75 76 static this() 77 { 78 translations = parseJSON(translationsJson); 79 locale = "en"; // TODO: add more locales and auto-detect system locale 80 } 81 82 static void sendMessage(ShowMessageType which, string[] args = []) 83 { 84 import dls.protocol.interfaces : ShowMessageParams; 85 86 JSONValue tr = translations[which]; 87 auto title = tr["title"][locale].str; 88 89 foreach (i; 0 .. args.length) 90 { 91 title = title.replace('$' ~ i.to!string, args[i]); 92 } 93 94 send("window/showMessage", 95 new ShowMessageParams(tr["messageType"].integer.to!MessageType, title)); 96 } 97 98 static string sendMessageRequest(ShowMessageRequestType which, 99 string[] args = [], string[] hiddenItems = []) 100 { 101 import dls.protocol.interfaces : ShowMessageRequestParams; 102 import std.algorithm : canFind, filter; 103 import std.typecons : nullable; 104 105 JSONValue tr = translations[which]; 106 auto title = tr["title"][locale].str; 107 auto actions = tr["actions"].array 108 .filter!(a => !hiddenItems.canFind(a["id"].str)) 109 .map!(a => new MessageActionItem(a["title"][locale].str)); 110 111 foreach (i; 0 .. args.length) 112 { 113 title = title.replace('$' ~ (i + 1).to!string, args[i]); 114 } 115 116 return send("window/showMessageRequest", new ShowMessageRequestParams( 117 tr["messageType"].integer.to!MessageType, title, actions.array.nullable)); 118 } 119 120 static string[] getActions(ShowMessageRequestType which) 121 { 122 return translations[which]["actions"].array.map!(a => a["title"][locale].str).array; 123 } 124 125 static void addMessageRequestType(string id, ShowMessageRequestType type, string data = null) 126 { 127 messageRequestInfo[id] = tuple(type, data); 128 } 129 }