os.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. 'use strict';
  2. const _ = require('lodash');
  3. const path = require('path');
  4. const { Controller } = require('ee-core');
  5. const {
  6. app: electronApp, dialog, shell, Notification,
  7. powerMonitor, screen, nativeTheme
  8. } = require('electron');
  9. const Conf = require('ee-core/config');
  10. const Ps = require('ee-core/ps');
  11. /**
  12. * 操作系统 - 功能demo
  13. * @class
  14. */
  15. class OsController extends Controller {
  16. constructor(ctx) {
  17. super(ctx);
  18. }
  19. /**
  20. * 所有方法接收两个参数
  21. * @param args 前端传的参数
  22. * @param event - ipc通信时才有值。详情见:控制器文档
  23. */
  24. /**
  25. * 消息提示对话框
  26. */
  27. messageShow() {
  28. dialog.showMessageBoxSync({
  29. type: 'info', // "none", "info", "error", "question" 或者 "warning"
  30. title: '自定义标题-message',
  31. message: '自定义消息内容',
  32. detail: '其它的额外信息'
  33. })
  34. return '打开了消息框';
  35. }
  36. /**
  37. * 消息提示与确认对话框
  38. */
  39. messageShowConfirm() {
  40. const res = dialog.showMessageBoxSync({
  41. type: 'info',
  42. title: '自定义标题-message',
  43. message: '自定义消息内容',
  44. detail: '其它的额外信息',
  45. cancelId: 1, // 用于取消对话框的按钮的索引
  46. defaultId: 0, // 设置默认选中的按钮
  47. buttons: ['确认', '取消'], // 按钮及索引
  48. })
  49. let data = (res === 0) ? '点击确认按钮' : '点击取消按钮';
  50. return data;
  51. }
  52. /**
  53. * 选择目录
  54. */
  55. selectFolder() {
  56. const filePaths = dialog.showOpenDialogSync({
  57. properties: ['openDirectory', 'createDirectory']
  58. });
  59. if (_.isEmpty(filePaths)) {
  60. return null
  61. }
  62. return filePaths[0];
  63. }
  64. /**
  65. * 打开目录
  66. */
  67. openDirectory(args) {
  68. if (!args.id) {
  69. return false;
  70. }
  71. let dir = '';
  72. if (path.isAbsolute(args.id)) {
  73. dir = args.id;
  74. } else {
  75. dir = electronApp.getPath(args.id);
  76. }
  77. shell.openPath(dir);
  78. return true;
  79. }
  80. /**
  81. * 加载视图内容
  82. */
  83. loadViewContent(args) {
  84. const { type, content } = args;
  85. let contentUrl = content;
  86. if (type == 'html') {
  87. contentUrl = path.join('file://', electronApp.getAppPath(), content);
  88. }
  89. this.service.os.createBrowserView(contentUrl);
  90. return true
  91. }
  92. /**
  93. * 移除视图内容
  94. */
  95. removeViewContent() {
  96. this.service.os.removeBrowserView();
  97. return true
  98. }
  99. /**
  100. * 打开新窗口
  101. */
  102. createWindow(args) {
  103. const { type, content, windowName, windowTitle } = args;
  104. let contentUrl = null;
  105. if (type == 'html') {
  106. contentUrl = path.join('file://', electronApp.getAppPath(), content)
  107. } else if (type == 'web') {
  108. contentUrl = content;
  109. } else if (type == 'vue') {
  110. let addr = 'http://localhost:8080'
  111. if (Ps.isProd()) {
  112. const mainServer = Conf.getValue('mainServer');
  113. addr = mainServer.protocol + mainServer.host + ':' + mainServer.port;
  114. }
  115. contentUrl = addr + content;
  116. } else {
  117. // some
  118. }
  119. console.log('contentUrl: ', contentUrl);
  120. const addonWindow = this.app.addon.window;
  121. let opt = {
  122. title: windowTitle
  123. }
  124. const win = addonWindow.create(windowName, opt);
  125. const winContentsId = win.webContents.id;
  126. // load page
  127. win.loadURL(contentUrl);
  128. return winContentsId;
  129. }
  130. /**
  131. * 获取窗口contents id
  132. */
  133. getWCid(args) {
  134. const addonWindow = this.app.addon.window;
  135. // 主窗口的name默认是main,其它窗口name开发者自己定义
  136. const name = args;
  137. const id = addonWindow.getWCid(name);
  138. return id;
  139. }
  140. /**
  141. * 加载扩展程序
  142. */
  143. // async loadExtension (args) {
  144. // const crxFile = args[0];
  145. // if (_.isEmpty(crxFile)) {
  146. // return false;
  147. // }
  148. // const extensionId = path.basename(crxFile, '.crx');
  149. // const chromeExtensionDir = chromeExtension.getDirectory();
  150. // const extensionDir = path.join(chromeExtensionDir, extensionId);
  151. // Log.info("[api] [example] [loadExtension] extension id:", extensionId);
  152. // unzip(crxFile, extensionDir).then(() => {
  153. // Log.info("[api] [example] [loadExtension] unzip success!");
  154. // chromeExtension.load(extensionId);
  155. // });
  156. // return true;
  157. // }
  158. /**
  159. * 创建系统通知
  160. */
  161. sendNotification(args, event) {
  162. const { title, subtitle, body, silent} = args;
  163. if (!Notification.isSupported()) {
  164. return '当前系统不支持通知';
  165. }
  166. let options = {};
  167. if (!_.isEmpty(title)) {
  168. options.title = title;
  169. }
  170. if (!_.isEmpty(subtitle)) {
  171. options.subtitle = subtitle;
  172. }
  173. if (!_.isEmpty(body)) {
  174. options.body = body;
  175. }
  176. if (!_.isEmpty(silent)) {
  177. options.silent = silent;
  178. }
  179. this.service.os.createNotification(options, event);
  180. return true
  181. }
  182. /**
  183. * 电源监控
  184. */
  185. initPowerMonitor(args, event) {
  186. const channel = 'controller.os.initPowerMonitor';
  187. powerMonitor.on('on-ac', (e) => {
  188. let data = {
  189. type: 'on-ac',
  190. msg: '接入了电源'
  191. }
  192. event.reply(`${channel}`, data)
  193. });
  194. powerMonitor.on('on-battery', (e) => {
  195. let data = {
  196. type: 'on-battery',
  197. msg: '使用电池中'
  198. }
  199. event.reply(`${channel}`, data)
  200. });
  201. powerMonitor.on('lock-screen', (e) => {
  202. let data = {
  203. type: 'lock-screen',
  204. msg: '锁屏了'
  205. }
  206. event.reply(`${channel}`, data)
  207. });
  208. powerMonitor.on('unlock-screen', (e) => {
  209. let data = {
  210. type: 'unlock-screen',
  211. msg: '解锁了'
  212. }
  213. event.reply(`${channel}`, data)
  214. });
  215. return true
  216. }
  217. /**
  218. * 获取屏幕信息
  219. */
  220. getScreen(args) {
  221. let data = [];
  222. let res = {};
  223. if (args == 0) {
  224. let res = screen.getCursorScreenPoint();
  225. data = [
  226. {
  227. title: '横坐标',
  228. desc: res.x
  229. },
  230. {
  231. title: '纵坐标',
  232. desc: res.y
  233. },
  234. ]
  235. return data;
  236. }
  237. if (args == 1) {
  238. res = screen.getPrimaryDisplay();
  239. }
  240. if (args == 2) {
  241. let resArr = screen.getAllDisplays();
  242. // 数组,只取一个吧
  243. res = resArr[0];
  244. }
  245. // Log.info('[electron] [ipc] [example] [getScreen] res:', res);
  246. data = [
  247. {
  248. title: '分辨率',
  249. desc: res.bounds.width + ' x ' + res.bounds.height
  250. },
  251. {
  252. title: '单色显示器',
  253. desc: res.monochrome ? '是' : '否'
  254. },
  255. {
  256. title: '色深',
  257. desc: res. colorDepth
  258. },
  259. {
  260. title: '色域',
  261. desc: res.colorSpace
  262. },
  263. {
  264. title: 'scaleFactor',
  265. desc: res.scaleFactor
  266. },
  267. {
  268. title: '加速器',
  269. desc: res.accelerometerSupport
  270. },
  271. {
  272. title: '触控',
  273. desc: res.touchSupport == 'unknown' ? '不支持' : '支持'
  274. },
  275. ]
  276. return data;
  277. }
  278. /**
  279. * 获取系统主题
  280. */
  281. getTheme() {
  282. let theme = 'system';
  283. if (nativeTheme.shouldUseHighContrastColors) {
  284. theme = 'light';
  285. } else if (nativeTheme.shouldUseInvertedColorScheme) {
  286. theme = 'dark';
  287. }
  288. return theme;
  289. }
  290. /**
  291. * 设置系统主题
  292. */
  293. setTheme(args) {
  294. // TODO 好像没有什么明显效果
  295. nativeTheme.themeSource = args;
  296. return args;
  297. }
  298. }
  299. OsController.toString = () => '[class OsController]';
  300. module.exports = OsController;