The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

845 lines
37KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #include "MainComponent.h"
  20. //==============================================================================
  21. MainContentComponent::MainContentComponent()
  22. {
  23. setupControls();
  24. distributeControls();
  25. #if JUCE_PUSH_NOTIFICATIONS
  26. addAndMakeVisible (headerLabel);
  27. addAndMakeVisible (mainTabs);
  28. addAndMakeVisible (sendButton);
  29. #else
  30. addAndMakeVisible (notAvailableYetLabel);
  31. #endif
  32. headerLabel.setJustificationType (Justification::centred);
  33. notAvailableYetLabel.setJustificationType (Justification::centred);
  34. #if JUCE_MAC
  35. StringArray tabNames { "Params1", "Params2", "Params3", "Params4" };
  36. #else
  37. StringArray tabNames { "Req. params", "Opt. params1", "Opt. params2", "Opt. params3" };
  38. #endif
  39. const auto colour = getLookAndFeel().findColour (ResizableWindow::backgroundColourId);
  40. localNotificationsTabs.addTab (tabNames[0], colour, &paramsOneView, false);
  41. localNotificationsTabs.addTab (tabNames[1], colour, &paramsTwoView, false);
  42. #if JUCE_ANDROID
  43. localNotificationsTabs.addTab (tabNames[2], colour, &paramsThreeView, false);
  44. localNotificationsTabs.addTab (tabNames[3], colour, &paramsFourView, false);
  45. #endif
  46. localNotificationsTabs.addTab ("Aux. actions", colour, &auxActionsView, false);
  47. mainTabs.addTab ("Local", colour, &localNotificationsTabs, false);
  48. mainTabs.addTab ("Remote", colour, &remoteView, false);
  49. const auto userArea = Desktop::getInstance().getDisplays().getMainDisplay().userArea;
  50. #if JUCE_ANDROID || JUCE_IOS
  51. setSize (userArea.getWidth(), userArea.getHeight());
  52. #else
  53. setSize (userArea.getWidth() / 2, userArea.getHeight() / 2);
  54. #endif
  55. sendButton.addListener (this);
  56. auxActionsView.getDeliveredNotificationsButton .addListener (this);
  57. auxActionsView.removeDeliveredNotifWithIdButton.addListener (this);
  58. auxActionsView.removeAllDeliveredNotifsButton .addListener (this);
  59. #if JUCE_IOS || JUCE_MAC
  60. auxActionsView.getPendingNotificationsButton .addListener (this);
  61. auxActionsView.removePendingNotifWithIdButton.addListener (this);
  62. auxActionsView.removeAllPendingNotifsButton .addListener (this);
  63. #endif
  64. remoteView.getDeviceTokenButton .addListener (this);
  65. remoteView.sendRemoteMessageButton .addListener (this);
  66. remoteView.subscribeToSportsButton .addListener (this);
  67. remoteView.unsubscribeFromSportsButton.addListener (this);
  68. paramControls.accentColourButton.addListener (this);
  69. paramControls.ledColourButton .addListener (this);
  70. jassert (PushNotifications::getInstance()->areNotificationsEnabled());
  71. PushNotifications::getInstance()->addListener (this);
  72. #if JUCE_IOS || JUCE_MAC
  73. paramControls.fireInComboBox.addListener (this);
  74. PushNotifications::getInstance()->requestPermissionsWithSettings (getNotificationSettings());
  75. #elif JUCE_ANDROID
  76. PushNotifications::ChannelGroup cg { "demoGroup", "demo group" };
  77. PushNotifications::getInstance()->setupChannels ({{ cg }}, getAndroidChannels());
  78. #endif
  79. }
  80. MainContentComponent::~MainContentComponent()
  81. {
  82. PushNotifications::getInstance()->removeListener (this);
  83. }
  84. void MainContentComponent::setupControls()
  85. {
  86. auto& pc = paramControls;
  87. StringArray categories { "okCategory", "okCancelCategory", "textCategory" };
  88. for (const auto& c : categories)
  89. pc.categoryComboBox.addItem (c, pc.categoryComboBox.getNumItems() + 1);
  90. pc.categoryComboBox.setSelectedItemIndex (0);
  91. for (int i = 1; i <= 3; ++i)
  92. pc.channelIdComboBox.addItem (String (i), i);
  93. pc.channelIdComboBox.setSelectedItemIndex (0);
  94. for (int i = 0; i < 5; ++i)
  95. pc.iconComboBox.addItem ("icon" + String (i + 1), i + 1);
  96. pc.iconComboBox.setSelectedItemIndex (0);
  97. #if JUCE_MAC
  98. pc.iconComboBox.addItem ("none", 100);
  99. #endif
  100. pc.fireInComboBox.addItem ("Now", 1);
  101. for (int i = 1; i < 11; ++i)
  102. pc.fireInComboBox.addItem (String (10 * i) + "seconds", i + 1);
  103. pc.fireInComboBox.setSelectedItemIndex (0);
  104. pc.largeIconComboBox.addItem ("none", 1);
  105. for (int i = 1; i < 5; ++i)
  106. pc.largeIconComboBox.addItem ("icon" + String (i), i + 1);
  107. pc.largeIconComboBox.setSelectedItemIndex (0);
  108. pc.badgeIconComboBox.addItem ("none", 1);
  109. pc.badgeIconComboBox.addItem ("small", 2);
  110. pc.badgeIconComboBox.addItem ("large", 3);
  111. pc.badgeIconComboBox.setSelectedItemIndex (2);
  112. pc.actionsComboBox.addItem ("none", 1);
  113. pc.actionsComboBox.addItem ("ok-cancel", 2);
  114. pc.actionsComboBox.addItem ("text-input", 3);
  115. #if JUCE_ANDROID
  116. pc.actionsComboBox.addItem ("ok-cancel-icons", 4);
  117. pc.actionsComboBox.addItem ("text-input-limited_responses", 5);
  118. #endif
  119. pc.actionsComboBox.setSelectedItemIndex (0);
  120. for (int i = 0; i < 7; ++i)
  121. pc.badgeNumberComboBox.addItem (String (i), i + 1);
  122. pc.badgeNumberComboBox.setSelectedItemIndex (0);
  123. #if JUCE_IOS
  124. String prefix = "sounds/";
  125. String extension = ".caf";
  126. #else
  127. String prefix;
  128. String extension;
  129. #endif
  130. pc.soundToPlayComboBox.addItem ("none", 1);
  131. pc.soundToPlayComboBox.addItem ("default_os_sound", 2);
  132. pc.soundToPlayComboBox.addItem (prefix + "demonstrative" + extension, 3);
  133. pc.soundToPlayComboBox.addItem (prefix + "isntit" + extension, 4);
  134. pc.soundToPlayComboBox.addItem (prefix + "jinglebellssms" + extension, 5);
  135. pc.soundToPlayComboBox.addItem (prefix + "served" + extension, 6);
  136. pc.soundToPlayComboBox.addItem (prefix + "solemn" + extension, 7);
  137. pc.soundToPlayComboBox.setSelectedItemIndex (1);
  138. for (int i = 0; i < 11; ++i)
  139. {
  140. pc.progressMaxComboBox .addItem (String (i * 10) + "%", i + 1);
  141. pc.progressCurrentComboBox.addItem (String (i * 10) + "%", i + 1);
  142. }
  143. pc.progressMaxComboBox .setSelectedItemIndex (0);
  144. pc.progressCurrentComboBox.setSelectedItemIndex (0);
  145. pc.notifCategoryComboBox.addItem ("unspecified", 1);
  146. pc.notifCategoryComboBox.addItem ("alarm", 2);
  147. pc.notifCategoryComboBox.addItem ("call", 3);
  148. pc.notifCategoryComboBox.addItem ("email", 4);
  149. pc.notifCategoryComboBox.addItem ("error", 5);
  150. pc.notifCategoryComboBox.addItem ("event", 6);
  151. pc.notifCategoryComboBox.addItem ("message", 7);
  152. pc.notifCategoryComboBox.addItem ("progress", 8);
  153. pc.notifCategoryComboBox.addItem ("promo", 9);
  154. pc.notifCategoryComboBox.addItem ("recommendation", 10);
  155. pc.notifCategoryComboBox.addItem ("reminder", 11);
  156. pc.notifCategoryComboBox.addItem ("service", 12);
  157. pc.notifCategoryComboBox.addItem ("social", 13);
  158. pc.notifCategoryComboBox.addItem ("status", 14);
  159. pc.notifCategoryComboBox.addItem ("system", 15);
  160. pc.notifCategoryComboBox.addItem ("transport", 16);
  161. pc.notifCategoryComboBox.setSelectedItemIndex (0);
  162. for (int i = -2; i < 3; ++i)
  163. pc.priorityComboBox.addItem (String (i), i + 3);
  164. pc.priorityComboBox.setSelectedItemIndex (2);
  165. pc.lockScreenVisibilityComboBox.addItem ("don't show", 1);
  166. pc.lockScreenVisibilityComboBox.addItem ("show partially", 2);
  167. pc.lockScreenVisibilityComboBox.addItem ("show completely", 3);
  168. pc.lockScreenVisibilityComboBox.setSelectedItemIndex (1);
  169. pc.groupAlertBehaviourComboBox.addItem ("alert all", 1);
  170. pc.groupAlertBehaviourComboBox.addItem ("alert summary", 2);
  171. pc.groupAlertBehaviourComboBox.addItem ("alert children", 3);
  172. pc.groupAlertBehaviourComboBox.setSelectedItemIndex (0);
  173. pc.timeoutAfterComboBox.addItem ("No timeout", 1);
  174. for (int i = 0; i < 10; ++i)
  175. {
  176. pc.ledMsToBeOnComboBox .addItem (String (i * 200) + "ms", i + 1);
  177. pc.ledMsToBeOffComboBox .addItem (String (i * 200) + "ms", i + 1);
  178. pc.vibratorMsToBeOnComboBox .addItem (String (i * 500) + "ms", i + 1);
  179. pc.vibratorMsToBeOffComboBox.addItem (String (i * 500) + "ms", i + 1);
  180. pc.timeoutAfterComboBox.addItem (String (5000 + 1000 * i) + "ms", i + 2);
  181. }
  182. pc.ledMsToBeOnComboBox .setSelectedItemIndex (5);
  183. pc.ledMsToBeOffComboBox .setSelectedItemIndex (5);
  184. pc.vibratorMsToBeOnComboBox .setSelectedItemIndex (0);
  185. pc.vibratorMsToBeOffComboBox.setSelectedItemIndex (0);
  186. pc.timeoutAfterComboBox.setSelectedItemIndex (0);
  187. pc.timestampVisibilityComboBox.addItem ("off", 1);
  188. pc.timestampVisibilityComboBox.addItem ("on", 2);
  189. pc.timestampVisibilityComboBox.addItem ("chronometer", 3);
  190. pc.timestampVisibilityComboBox.addItem ("count down", 4);
  191. pc.timestampVisibilityComboBox.setSelectedItemIndex (1);
  192. }
  193. void MainContentComponent::distributeControls()
  194. {
  195. auto& pc = paramControls;
  196. paramsOneView.addRowComponent (new RowComponent (pc.identifierLabel, pc.identifierEditor));
  197. paramsOneView.addRowComponent (new RowComponent (pc.titleLabel, pc.titleEditor));
  198. paramsOneView.addRowComponent (new RowComponent (pc.bodyLabel, pc.bodyEditor, 4));
  199. #if JUCE_IOS
  200. paramsOneView.addRowComponent (new RowComponent (pc.categoryLabel, pc.categoryComboBox));
  201. #elif JUCE_ANDROID
  202. paramsOneView.addRowComponent (new RowComponent (pc.channelIdLabel, pc.channelIdComboBox));
  203. #endif
  204. #if JUCE_ANDROID || JUCE_MAC
  205. paramsOneView.addRowComponent (new RowComponent (pc.iconLabel, pc.iconComboBox));
  206. #endif
  207. paramsTwoView.addRowComponent (new RowComponent (pc.subtitleLabel, pc.subtitleEditor));
  208. #if ! JUCE_MAC
  209. paramsTwoView.addRowComponent (new RowComponent (pc.badgeNumberLabel, pc.badgeNumberComboBox));
  210. #endif
  211. paramsTwoView.addRowComponent (new RowComponent (pc.soundToPlayLabel, pc.soundToPlayComboBox));
  212. paramsTwoView.addRowComponent (new RowComponent (pc.propertiesLabel, pc.propertiesEditor, 3));
  213. #if JUCE_IOS || JUCE_MAC
  214. paramsTwoView.addRowComponent (new RowComponent (pc.fireInLabel, pc.fireInComboBox));
  215. paramsTwoView.addRowComponent (new RowComponent (pc.repeatLabel, pc.repeatButton));
  216. #elif JUCE_ANDROID
  217. paramsTwoView.addRowComponent (new RowComponent (pc.largeIconLabel, pc.largeIconComboBox));
  218. paramsTwoView.addRowComponent (new RowComponent (pc.badgeIconLabel, pc.badgeIconComboBox));
  219. paramsTwoView.addRowComponent (new RowComponent (pc.tickerTextLabel, pc.tickerTextEditor));
  220. paramsTwoView.addRowComponent (new RowComponent (pc.autoCancelLabel, pc.autoCancelButton));
  221. paramsTwoView.addRowComponent (new RowComponent (pc.alertOnlyOnceLabel, pc.alertOnlyOnceButton));
  222. #endif
  223. #if JUCE_ANDROID || JUCE_MAC
  224. paramsTwoView.addRowComponent (new RowComponent (pc.actionsLabel, pc.actionsComboBox));
  225. #endif
  226. #if JUCE_ANDROID
  227. paramsThreeView.addRowComponent (new RowComponent (pc.progressMaxLabel, pc.progressMaxComboBox));
  228. paramsThreeView.addRowComponent (new RowComponent (pc.progressCurrentLabel, pc.progressCurrentComboBox));
  229. paramsThreeView.addRowComponent (new RowComponent (pc.progressIndeterminateLabel, pc.progressIndeterminateButton));
  230. paramsThreeView.addRowComponent (new RowComponent (pc.categoryLabel, pc.categoryComboBox));
  231. paramsThreeView.addRowComponent (new RowComponent (pc.priorityLabel, pc.priorityComboBox));
  232. paramsThreeView.addRowComponent (new RowComponent (pc.personLabel, pc.personEditor));
  233. paramsThreeView.addRowComponent (new RowComponent (pc.lockScreenVisibilityLabel, pc.lockScreenVisibilityComboBox));
  234. paramsThreeView.addRowComponent (new RowComponent (pc.groupIdLabel, pc.groupIdEditor));
  235. paramsThreeView.addRowComponent (new RowComponent (pc.sortKeyLabel, pc.sortKeyEditor));
  236. paramsThreeView.addRowComponent (new RowComponent (pc.groupSummaryLabel, pc.groupSummaryButton));
  237. paramsThreeView.addRowComponent (new RowComponent (pc.groupAlertBehaviourLabel, pc.groupAlertBehaviourComboBox));
  238. paramsFourView.addRowComponent (new RowComponent (pc.accentColourLabel, pc.accentColourButton));
  239. paramsFourView.addRowComponent (new RowComponent (pc.ledColourLabel, pc.ledColourButton));
  240. paramsFourView.addRowComponent (new RowComponent (pc.ledMsToBeOffLabel, pc.ledMsToBeOffComboBox));
  241. paramsFourView.addRowComponent (new RowComponent (pc.ledMsToBeOnLabel, pc.ledMsToBeOnComboBox));
  242. paramsFourView.addRowComponent (new RowComponent (pc.vibratorMsToBeOffLabel, pc.vibratorMsToBeOffComboBox));
  243. paramsFourView.addRowComponent (new RowComponent (pc.vibratorMsToBeOnLabel, pc.vibratorMsToBeOnComboBox));
  244. paramsFourView.addRowComponent (new RowComponent (pc.localOnlyLabel, pc.localOnlyButton));
  245. paramsFourView.addRowComponent (new RowComponent (pc.ongoingLabel, pc.ongoingButton));
  246. paramsFourView.addRowComponent (new RowComponent (pc.timestampVisibilityLabel, pc.timestampVisibilityComboBox));
  247. paramsFourView.addRowComponent (new RowComponent (pc.timeoutAfterLabel, pc.timeoutAfterComboBox));
  248. #endif
  249. }
  250. void MainContentComponent::paint (Graphics& g)
  251. {
  252. g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
  253. }
  254. void MainContentComponent::resized()
  255. {
  256. auto bounds = getLocalBounds().reduced (getWidth() / 20, getHeight() / 40);
  257. headerLabel.setBounds (bounds.removeFromTop (bounds.proportionOfHeight (0.1f)));
  258. mainTabs.setBounds (bounds.removeFromTop (bounds.proportionOfHeight (0.8f)));
  259. sendButton.setBounds (bounds);
  260. notAvailableYetLabel.setBounds (getLocalBounds());
  261. }
  262. void MainContentComponent::buttonClicked (Button* b)
  263. {
  264. if (b == &sendButton)
  265. sendLocalNotification();
  266. else if (b == &paramControls.accentColourButton)
  267. setupAccentColour();
  268. else if (b == &paramControls.ledColourButton)
  269. setupLedColour();
  270. else if (b == &auxActionsView.getDeliveredNotificationsButton)
  271. getDeliveredNotifications();
  272. else if (b == &auxActionsView.removeDeliveredNotifWithIdButton)
  273. PushNotifications::getInstance()->removeDeliveredNotification (auxActionsView.deliveredNotifIdentifier.getText());
  274. else if (b == &auxActionsView.removeAllDeliveredNotifsButton)
  275. PushNotifications::getInstance()->removeAllDeliveredNotifications();
  276. #if JUCE_IOS || JUCE_MAC
  277. else if (b == &auxActionsView.getPendingNotificationsButton)
  278. PushNotifications::getInstance()->getPendingLocalNotifications();
  279. else if (b == &auxActionsView.removePendingNotifWithIdButton)
  280. PushNotifications::getInstance()->removePendingLocalNotification (auxActionsView.pendingNotifIdentifier.getText());
  281. else if (b == &auxActionsView.removeAllPendingNotifsButton)
  282. PushNotifications::getInstance()->removeAllPendingLocalNotifications();
  283. #endif
  284. else if (b == &remoteView.getDeviceTokenButton)
  285. {
  286. String token = PushNotifications::getInstance()->getDeviceToken();
  287. DBG ("token = " + token);
  288. if (token.isEmpty())
  289. showRemoteInstructions();
  290. else
  291. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon, "Device token", token);
  292. }
  293. #if JUCE_ANDROID
  294. else if (b == &remoteView.sendRemoteMessageButton)
  295. {
  296. StringPairArray data;
  297. data.set ("key1", "value1");
  298. data.set ("key2", "value2");
  299. static int id = 100;
  300. PushNotifications::getInstance()->sendUpstreamMessage ("872047750958",
  301. "com.juce.pushnotificationsdemo",
  302. String (id++),
  303. "standardType",
  304. 3600,
  305. data);
  306. }
  307. else if (b == &remoteView.subscribeToSportsButton)
  308. {
  309. PushNotifications::getInstance()->subscribeToTopic ("sports");
  310. }
  311. else if (b == &remoteView.unsubscribeFromSportsButton)
  312. {
  313. PushNotifications::getInstance()->unsubscribeFromTopic ("sports");
  314. }
  315. #endif
  316. }
  317. void MainContentComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
  318. {
  319. if (comboBoxThatHasChanged == &paramControls.fireInComboBox)
  320. {
  321. const bool repeatsAllowed = paramControls.fireInComboBox.getSelectedItemIndex() >= 6;
  322. paramControls.repeatButton.setEnabled (repeatsAllowed);
  323. if (! repeatsAllowed)
  324. paramControls.repeatButton.setToggleState (false, NotificationType::sendNotification);
  325. }
  326. }
  327. void MainContentComponent::sendLocalNotification()
  328. {
  329. PushNotifications::Notification n;
  330. fillRequiredParams (n);
  331. fillOptionalParamsOne (n);
  332. #if JUCE_ANDROID
  333. fillOptionalParamsTwo (n);
  334. fillOptionalParamsThree (n);
  335. #endif
  336. if (! n.isValid())
  337. {
  338. #if JUCE_IOS
  339. String requiredFields = "identifier (from iOS 10), title, body and category";
  340. #elif JUCE_ANDROID
  341. String requiredFields = "channel ID (from Android O), title, body and icon";
  342. #else
  343. String requiredFields = "all required fields";
  344. #endif
  345. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  346. "Incorrect notifications setup",
  347. "Please make sure that "
  348. + requiredFields + " are set.");
  349. return;
  350. }
  351. PushNotifications::getInstance()->sendLocalNotification (n);
  352. }
  353. void MainContentComponent::fillRequiredParams (PushNotifications::Notification& n)
  354. {
  355. n.identifier = paramControls.identifierEditor.getText();
  356. n.title = paramControls.titleEditor.getText();
  357. n.body = paramControls.bodyEditor.getText();
  358. #if JUCE_IOS
  359. n.category = paramControls.categoryComboBox.getText();
  360. #elif JUCE_ANDROID || JUCE_MAC
  361. #if JUCE_MAC
  362. String prefix = "images/";
  363. String extension = ".png";
  364. #else
  365. String prefix;
  366. String extension;
  367. #endif
  368. if (paramControls.iconComboBox.getSelectedItemIndex() == 0)
  369. n.icon = prefix + "ic_stat_name" + extension;
  370. else if (paramControls.iconComboBox.getSelectedItemIndex() == 1)
  371. n.icon = prefix + "ic_stat_name2" + extension;
  372. else if (paramControls.iconComboBox.getSelectedItemIndex() == 2)
  373. n.icon = prefix + "ic_stat_name3" + extension;
  374. else if (paramControls.iconComboBox.getSelectedItemIndex() == 3)
  375. n.icon = prefix + "ic_stat_name4" + extension;
  376. else if (paramControls.iconComboBox.getSelectedItemIndex() == 4)
  377. n.icon = prefix + "ic_stat_name5" + extension;
  378. #endif
  379. #if JUCE_ANDROID
  380. // Note: this is not strictly speaking required param, just doing it here because it is the fastest way!
  381. n.publicVersion = new PushNotifications::Notification();
  382. n.publicVersion->identifier = "blahblahblah";
  383. n.publicVersion->title = "Public title!";
  384. n.publicVersion->body = "Public body!";
  385. n.publicVersion->icon = n.icon;
  386. #if __ANDROID_API__ >= 26
  387. n.channelId = String (paramControls.channelIdComboBox.getSelectedItemIndex() + 1);
  388. #endif
  389. #endif
  390. }
  391. void MainContentComponent::fillOptionalParamsOne (PushNotifications::Notification& n)
  392. {
  393. n.subtitle = paramControls.subtitleEditor.getText();
  394. n.badgeNumber = paramControls.badgeNumberComboBox.getSelectedItemIndex();
  395. if (paramControls.soundToPlayComboBox.getSelectedItemIndex() > 0)
  396. n.soundToPlay = URL (paramControls.soundToPlayComboBox.getItemText (paramControls.soundToPlayComboBox.getSelectedItemIndex()));
  397. n.properties = JSON::parse (paramControls.propertiesEditor.getText());
  398. #if JUCE_IOS || JUCE_MAC
  399. n.triggerIntervalSec = double (paramControls.fireInComboBox.getSelectedItemIndex() * 10);
  400. n.repeat = paramControls.repeatButton.getToggleState();
  401. #elif JUCE_ANDROID
  402. if (paramControls.largeIconComboBox.getSelectedItemIndex() == 1)
  403. n.largeIcon = ImageFileFormat::loadFrom (BinaryData::ic_stat_name6_png, BinaryData::ic_stat_name6_pngSize);
  404. else if (paramControls.largeIconComboBox.getSelectedItemIndex() == 2)
  405. n.largeIcon = ImageFileFormat::loadFrom (BinaryData::ic_stat_name7_png, BinaryData::ic_stat_name7_pngSize);
  406. else if (paramControls.largeIconComboBox.getSelectedItemIndex() == 3)
  407. n.largeIcon = ImageFileFormat::loadFrom (BinaryData::ic_stat_name8_png, BinaryData::ic_stat_name8_pngSize);
  408. else if (paramControls.largeIconComboBox.getSelectedItemIndex() == 4)
  409. n.largeIcon = ImageFileFormat::loadFrom (BinaryData::ic_stat_name9_png, BinaryData::ic_stat_name9_pngSize);
  410. else if (paramControls.largeIconComboBox.getSelectedItemIndex() == 5)
  411. n.largeIcon = ImageFileFormat::loadFrom (BinaryData::ic_stat_name10_png, BinaryData::ic_stat_name10_pngSize);
  412. n.badgeIconType = (PushNotifications::Notification::BadgeIconType) paramControls.badgeIconComboBox.getSelectedItemIndex();
  413. n.tickerText = paramControls.tickerTextEditor.getText();
  414. n.shouldAutoCancel = paramControls.autoCancelButton.getToggleState();
  415. n.alertOnlyOnce = paramControls.alertOnlyOnceButton.getToggleState();
  416. #endif
  417. #if JUCE_ANDROID || JUCE_MAC
  418. if (paramControls.actionsComboBox.getSelectedItemIndex() == 1)
  419. {
  420. PushNotifications::Notification::Action a, a2;
  421. a .style = PushNotifications::Notification::Action::button;
  422. a2.style = PushNotifications::Notification::Action::button;
  423. a .title = a .identifier = "Ok";
  424. a2.title = a2.identifier = "Cancel";
  425. n.actions.add (a);
  426. n.actions.add (a2);
  427. }
  428. else if (paramControls.actionsComboBox.getSelectedItemIndex() == 2)
  429. {
  430. PushNotifications::Notification::Action a, a2;
  431. a .title = a .identifier = "Input Text Here";
  432. a2.title = a2.identifier = "No";
  433. a .style = PushNotifications::Notification::Action::text;
  434. a2.style = PushNotifications::Notification::Action::button;
  435. a .icon = "ic_stat_name4";
  436. a2.icon = "ic_stat_name5";
  437. a.textInputPlaceholder = "placeholder text ...";
  438. n.actions.add (a);
  439. n.actions.add (a2);
  440. }
  441. else if (paramControls.actionsComboBox.getSelectedItemIndex() == 3)
  442. {
  443. PushNotifications::Notification::Action a, a2;
  444. a .title = a .identifier = "Ok";
  445. a2.title = a2.identifier = "Cancel";
  446. a .style = PushNotifications::Notification::Action::button;
  447. a2.style = PushNotifications::Notification::Action::button;
  448. a .icon = "ic_stat_name4";
  449. a2.icon = "ic_stat_name5";
  450. n.actions.add (a);
  451. n.actions.add (a2);
  452. }
  453. else if (paramControls.actionsComboBox.getSelectedItemIndex() == 4)
  454. {
  455. PushNotifications::Notification::Action a, a2;
  456. a .title = a .identifier = "Input Text Here";
  457. a2.title = a2.identifier = "No";
  458. a .style = PushNotifications::Notification::Action::text;
  459. a2.style = PushNotifications::Notification::Action::button;
  460. a .icon = "ic_stat_name4";
  461. a2.icon = "ic_stat_name5";
  462. a.textInputPlaceholder = "placeholder text ...";
  463. a.allowedResponses.add ("Response 1");
  464. a.allowedResponses.add ("Response 2");
  465. a.allowedResponses.add ("Response 3");
  466. n.actions.add (a);
  467. n.actions.add (a2);
  468. }
  469. #endif
  470. }
  471. void MainContentComponent::fillOptionalParamsTwo (PushNotifications::Notification& n)
  472. {
  473. using Notification = PushNotifications::Notification;
  474. Notification::Progress progress;
  475. progress.max = paramControls.progressMaxComboBox.getSelectedItemIndex() * 10;
  476. progress.current = paramControls.progressCurrentComboBox.getSelectedItemIndex() * 10;
  477. progress.indeterminate = paramControls.progressIndeterminateButton.getToggleState();
  478. n.progress = progress;
  479. n.person = paramControls.personEditor.getText();
  480. n.type = Notification::Type (paramControls.categoryComboBox.getSelectedItemIndex());
  481. n.priority = Notification::Priority (paramControls.priorityComboBox.getSelectedItemIndex() - 2);
  482. n.lockScreenAppearance = Notification::LockScreenAppearance (paramControls.lockScreenVisibilityComboBox.getSelectedItemIndex() - 1);
  483. n.groupId = paramControls.groupIdEditor.getText();
  484. n.groupSortKey = paramControls.sortKeyEditor.getText();
  485. n.groupSummary = paramControls.groupSummaryButton.getToggleState();
  486. n.groupAlertBehaviour = Notification::GroupAlertBehaviour (paramControls.groupAlertBehaviourComboBox.getSelectedItemIndex());
  487. }
  488. void MainContentComponent::fillOptionalParamsThree (PushNotifications::Notification& n)
  489. {
  490. n.accentColour = paramControls.accentColourButton.findColour (TextButton::buttonColourId, false);
  491. n.ledColour = paramControls.ledColourButton .findColour (TextButton::buttonColourId, false);
  492. using Notification = PushNotifications::Notification;
  493. Notification::LedBlinkPattern ledBlinkPattern;
  494. ledBlinkPattern.msToBeOn = paramControls.ledMsToBeOnComboBox .getSelectedItemIndex() * 200;
  495. ledBlinkPattern.msToBeOff = paramControls.ledMsToBeOffComboBox.getSelectedItemIndex() * 200;
  496. n.ledBlinkPattern = ledBlinkPattern;
  497. Array<int> vibrationPattern;
  498. if (paramControls.vibratorMsToBeOnComboBox .getSelectedItemIndex() > 0 &&
  499. paramControls.vibratorMsToBeOffComboBox.getSelectedItemIndex() > 0)
  500. {
  501. vibrationPattern.add (paramControls.vibratorMsToBeOffComboBox.getSelectedItemIndex() * 500);
  502. vibrationPattern.add (paramControls.vibratorMsToBeOnComboBox .getSelectedItemIndex() * 500);
  503. vibrationPattern.add (2 * paramControls.vibratorMsToBeOffComboBox.getSelectedItemIndex() * 500);
  504. vibrationPattern.add (2 * paramControls.vibratorMsToBeOnComboBox .getSelectedItemIndex() * 500);
  505. }
  506. n.vibrationPattern = vibrationPattern;
  507. n.localOnly = paramControls.localOnlyButton.getToggleState();
  508. n.ongoing = paramControls.ongoingButton.getToggleState();
  509. n.timestampVisibility = Notification::TimestampVisibility (paramControls.timestampVisibilityComboBox.getSelectedItemIndex());
  510. if (paramControls.timeoutAfterComboBox.getSelectedItemIndex() > 0)
  511. {
  512. auto index = paramControls.timeoutAfterComboBox.getSelectedItemIndex();
  513. n.timeoutAfterMs = index * 1000 + 4000;
  514. }
  515. }
  516. void MainContentComponent::setupAccentColour()
  517. {
  518. paramControls.accentColourSelector = new ColourSelector();
  519. paramControls.accentColourSelector->setName ("accent colour");
  520. paramControls.accentColourSelector->setCurrentColour (paramControls.accentColourButton.findColour (TextButton::buttonColourId));
  521. paramControls.accentColourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack);
  522. paramControls.accentColourSelector->setSize (200, 200);
  523. paramControls.accentColourSelector->addComponentListener (this);
  524. paramControls.accentColourSelector->addChangeListener (this);
  525. CallOutBox::launchAsynchronously (paramControls.accentColourSelector, paramControls.accentColourButton.getScreenBounds(), nullptr);
  526. }
  527. void MainContentComponent::setupLedColour()
  528. {
  529. paramControls.ledColourSelector = new ColourSelector();
  530. paramControls.ledColourSelector->setName ("led colour");
  531. paramControls.ledColourSelector->setCurrentColour (paramControls.ledColourButton.findColour (TextButton::buttonColourId));
  532. paramControls.ledColourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack);
  533. paramControls.ledColourSelector->setSize (200, 200);
  534. paramControls.ledColourSelector->addComponentListener (this);
  535. paramControls.ledColourSelector->addChangeListener (this);
  536. CallOutBox::launchAsynchronously (paramControls.ledColourSelector, paramControls.accentColourButton.getScreenBounds(), nullptr);
  537. }
  538. void MainContentComponent::changeListenerCallback (ChangeBroadcaster* source)
  539. {
  540. if (source == paramControls.accentColourSelector)
  541. {
  542. Colour c = paramControls.accentColourSelector->getCurrentColour();
  543. paramControls.accentColourButton.setColour (TextButton::buttonColourId, c);
  544. }
  545. else if (source == paramControls.ledColourSelector)
  546. {
  547. Colour c = paramControls.ledColourSelector->getCurrentColour();
  548. paramControls.ledColourButton.setColour (TextButton::buttonColourId, c);
  549. }
  550. }
  551. void MainContentComponent::componentBeingDeleted (Component& component)
  552. {
  553. if (&component == paramControls.accentColourSelector)
  554. paramControls.accentColourSelector = nullptr;
  555. else if (&component == paramControls.ledColourSelector)
  556. paramControls.ledColourSelector = nullptr;
  557. }
  558. void MainContentComponent::handleNotification (bool isLocalNotification, const PushNotifications::Notification& n)
  559. {
  560. ignoreUnused (isLocalNotification);
  561. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  562. "Received notification",
  563. "ID: " + n.identifier
  564. + ", title: " + n.title
  565. + ", body: " + n.body);
  566. }
  567. void MainContentComponent::handleNotificationAction (bool isLocalNotification,
  568. const PushNotifications::Notification& n,
  569. const String& actionIdentifier,
  570. const String& optionalResponse)
  571. {
  572. ignoreUnused (isLocalNotification);
  573. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  574. "Received notification action",
  575. "ID: " + n.identifier
  576. + ", title: " + n.title
  577. + ", body: " + n.body
  578. + ", action: " + actionIdentifier
  579. + ", optionalResponse: " + optionalResponse);
  580. PushNotifications::getInstance()->removeDeliveredNotification (n.identifier);
  581. }
  582. void MainContentComponent::localNotificationDismissedByUser (const PushNotifications::Notification& n)
  583. {
  584. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  585. "Notification dismissed by a user",
  586. "ID: " + n.identifier
  587. + ", title: " + n.title
  588. + ", body: " + n.body);
  589. }
  590. void MainContentComponent::getDeliveredNotifications()
  591. {
  592. PushNotifications::getInstance()->getDeliveredNotifications();
  593. }
  594. void MainContentComponent::deliveredNotificationsListReceived (const Array<PushNotifications::Notification>& notifs)
  595. {
  596. String text = "Received notifications: ";
  597. for (const auto& n : notifs)
  598. text << "(" << n.identifier << ", " << n.title << ", " << n.body << "), ";
  599. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon, "Received notification list", text);
  600. }
  601. void MainContentComponent::pendingLocalNotificationsListReceived (const Array<PushNotifications::Notification>& notifs)
  602. {
  603. String text = "Pending notifications: ";
  604. for (const auto& n : notifs)
  605. text << "(" << n.identifier << ", " << n.title << ", " << n.body << "), ";
  606. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon, "Pending notification list", text);
  607. }
  608. void MainContentComponent::deviceTokenRefreshed (const String& token)
  609. {
  610. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  611. "Device token refreshed",
  612. token);
  613. }
  614. #if JUCE_ANDROID
  615. void MainContentComponent::remoteNotificationsDeleted()
  616. {
  617. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  618. "Remote notifications deleted",
  619. "Some of the pending messages were removed!");
  620. }
  621. void MainContentComponent::upstreamMessageSent (const String& messageId)
  622. {
  623. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  624. "Upstream message sent",
  625. "Message id: " + messageId);
  626. }
  627. void MainContentComponent::upstreamMessageSendingError (const String& messageId, const String& error)
  628. {
  629. NativeMessageBox::showMessageBoxAsync (AlertWindow::InfoIcon,
  630. "Upstream message sending error",
  631. "Message id: " + messageId
  632. + "\nerror: " + error);
  633. }
  634. Array<PushNotifications::Channel> MainContentComponent::getAndroidChannels()
  635. {
  636. using Channel = PushNotifications::Channel;
  637. Channel ch1, ch2, ch3;
  638. ch1.identifier = "1";
  639. ch1.name = "HighImportance";
  640. ch1.importance = PushNotifications::Channel::max;
  641. ch1.lockScreenAppearance = PushNotifications::Notification::showCompletely;
  642. ch1.description = "High Priority Channel for important stuff";
  643. ch1.groupId = "demoGroup";
  644. ch1.ledColour = Colours::red;
  645. ch1.bypassDoNotDisturb = true;
  646. ch1.canShowBadge = true;
  647. ch1.enableLights = true;
  648. ch1.enableVibration = true;
  649. ch1.soundToPlay = URL ("demonstrative");
  650. ch1.vibrationPattern = { 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200 };
  651. ch2.identifier = "2";
  652. ch2.name = "MediumImportance";
  653. ch2.importance = PushNotifications::Channel::normal;
  654. ch2.lockScreenAppearance = PushNotifications::Notification::showPartially;
  655. ch2.description = "Medium Priority Channel for standard stuff";
  656. ch2.groupId = "demoGroup";
  657. ch2.ledColour = Colours::yellow;
  658. ch2.canShowBadge = true;
  659. ch2.enableLights = true;
  660. ch2.enableVibration = true;
  661. ch2.soundToPlay = URL ("default_os_sound");
  662. ch2.vibrationPattern = { 1000, 1000 };
  663. ch3.identifier = "3";
  664. ch3.name = "LowImportance";
  665. ch3.importance = PushNotifications::Channel::min;
  666. ch3.lockScreenAppearance = PushNotifications::Notification::dontShow;
  667. ch3.description = "Low Priority Channel for silly stuff";
  668. ch3.groupId = "demoGroup";
  669. return { ch1, ch2, ch3 };
  670. }
  671. #elif JUCE_IOS || JUCE_MAC
  672. PushNotifications::Settings MainContentComponent::getNotificationSettings()
  673. {
  674. PushNotifications::Settings settings;
  675. settings.allowAlert = true;
  676. settings.allowBadge = true;
  677. settings.allowSound = true;
  678. #if JUCE_IOS
  679. using Action = PushNotifications::Settings::Action;
  680. using Category = PushNotifications::Settings::Category;
  681. Action okAction;
  682. okAction.identifier = "okAction";
  683. okAction.title = "OK!";
  684. okAction.style = Action::button;
  685. okAction.triggerInBackground = true;
  686. Action cancelAction;
  687. cancelAction.identifier = "cancelAction";
  688. cancelAction.title = "Cancel";
  689. cancelAction.style = Action::button;
  690. cancelAction.triggerInBackground = true;
  691. cancelAction.destructive = true;
  692. Action textAction;
  693. textAction.identifier = "textAction";
  694. textAction.title = "Enter text";
  695. textAction.style = Action::text;
  696. textAction.triggerInBackground = true;
  697. textAction.destructive = false;
  698. textAction.textInputButtonText = "Ok";
  699. textAction.textInputPlaceholder = "Enter text...";
  700. Category okCategory;
  701. okCategory.identifier = "okCategory";
  702. okCategory.actions = { okAction };
  703. Category okCancelCategory;
  704. okCancelCategory.identifier = "okCancelCategory";
  705. okCancelCategory.actions = { okAction, cancelAction };
  706. Category textCategory;
  707. textCategory.identifier = "textCategory";
  708. textCategory.actions = { textAction };
  709. textCategory.sendDismissAction = true;
  710. settings.categories = { okCategory, okCancelCategory, textCategory };
  711. #endif
  712. return settings;
  713. }
  714. #endif