@@ -90,6 +90,7 @@ class HomeScreen : public UIScreen {
9090 bool _shutdown_init;
9191 AdvertPath recent[UI_RECENT_LIST_SIZE];
9292
93+
9394 void renderBatteryIndicator (DisplayDriver& display, uint16_t batteryMilliVolts) {
9495 // Convert millivolts to percentage
9596 const int minMilliVolts = 3000 ; // Minimum voltage (e.g., 3.0V)
@@ -157,10 +158,12 @@ class HomeScreen : public UIScreen {
157158 int render (DisplayDriver& display) override {
158159 char tmp[80 ];
159160 // node name
160- display.setCursor (0 , 0 );
161161 display.setTextSize (1 );
162162 display.setColor (DisplayDriver::GREEN);
163- display.print (_node_prefs->node_name );
163+ char filtered_name[sizeof (_node_prefs->node_name )];
164+ display.translateUTF8ToBlocks (filtered_name, _node_prefs->node_name , sizeof (filtered_name));
165+ display.setCursor (0 , 0 );
166+ display.print (filtered_name);
164167
165168 // battery voltage
166169 renderBatteryIndicator (display, _task->getBattMilliVolts ());
@@ -199,8 +202,6 @@ class HomeScreen : public UIScreen {
199202 for (int i = 0 ; i < UI_RECENT_LIST_SIZE; i++, y += 11 ) {
200203 auto a = &recent[i];
201204 if (a->name [0 ] == 0 ) continue ; // empty slot
202- display.setCursor (0 , y);
203- display.print (a->name );
204205 int secs = _rtc->getCurrentTime () - a->recv_timestamp ;
205206 if (secs < 60 ) {
206207 sprintf (tmp, " %ds" , secs);
@@ -209,7 +210,14 @@ class HomeScreen : public UIScreen {
209210 } else {
210211 sprintf (tmp, " %dh" , secs / (60 *60 ));
211212 }
212- display.setCursor (display.width () - display.getTextWidth (tmp) - 1 , y);
213+
214+ int timestamp_width = display.getTextWidth (tmp);
215+ int max_name_width = display.width () - timestamp_width - 1 ;
216+
217+ char filtered_recent_name[sizeof (a->name )];
218+ display.translateUTF8ToBlocks (filtered_recent_name, a->name , sizeof (filtered_recent_name));
219+ display.drawTextEllipsized (0 , y, max_name_width, filtered_recent_name);
220+ display.setCursor (display.width () - timestamp_width - 1 , y);
213221 display.print (tmp);
214222 }
215223 } else if (_page == HomePage::RADIO) {
@@ -348,9 +356,7 @@ class HomeScreen : public UIScreen {
348356 return true ;
349357 }
350358 if (c == KEY_ENTER && _page == HomePage::ADVERT) {
351- #ifdef PIN_BUZZER
352- _task->soundBuzzer (UIEventType::ack);
353- #endif
359+ _task->notify (UIEventType::ack);
354360 if (the_mesh.advert ()) {
355361 _task->showAlert (" Advert sent!" , 1000 );
356362 } else {
@@ -427,11 +433,15 @@ class MsgPreviewScreen : public UIScreen {
427433
428434 display.setCursor (0 , 14 );
429435 display.setColor (DisplayDriver::YELLOW);
430- display.print (p->origin );
436+ char filtered_origin[sizeof (p->origin )];
437+ display.translateUTF8ToBlocks (filtered_origin, p->origin , sizeof (filtered_origin));
438+ display.print (filtered_origin);
431439
432440 display.setCursor (0 , 25 );
433441 display.setColor (DisplayDriver::LIGHT);
434- display.printWordWrap (p->msg , display.width ());
442+ char filtered_msg[sizeof (p->msg )];
443+ display.translateUTF8ToBlocks (filtered_msg, p->msg , sizeof (filtered_msg));
444+ display.printWordWrap (filtered_msg, display.width ());
435445
436446#if AUTO_OFF_MILLIS==0 // probably e-ink
437447 return 10000 ; // 10 s
@@ -483,6 +493,10 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
483493 buzzer.begin ();
484494#endif
485495
496+ #ifdef PIN_VIBRATION
497+ vibration.begin ();
498+ #endif
499+
486500 ui_started_at = millis ();
487501 _alert_expiry = 0 ;
488502
@@ -497,9 +511,9 @@ void UITask::showAlert(const char* text, int duration_millis) {
497511 _alert_expiry = millis () + duration_millis;
498512}
499513
500- void UITask::soundBuzzer (UIEventType bet ) {
514+ void UITask::notify (UIEventType t ) {
501515#if defined(PIN_BUZZER)
502- switch (bet ){
516+ switch (t ){
503517 case UIEventType::contactMessage:
504518 // gemini's pick
505519 buzzer.play (" MsgRcv3:d=4,o=6,b=200:32e,32g,32b,16c7" );
@@ -517,8 +531,16 @@ switch(bet){
517531 break ;
518532}
519533#endif
534+
535+ #ifdef PIN_VIBRATION
536+ // Trigger vibration for all UI events except none
537+ if (t != UIEventType::none) {
538+ vibration.trigger ();
539+ }
540+ #endif
520541}
521542
543+
522544void UITask::msgRead (int msgcount) {
523545 _msgcount = msgcount;
524546 if (msgcount == 0 ) {
@@ -687,6 +709,10 @@ void UITask::loop() {
687709#endif
688710 }
689711
712+ #ifdef PIN_VIBRATION
713+ vibration.loop ();
714+ #endif
715+
690716#ifdef AUTO_SHUTDOWN_MILLIVOLTS
691717 if (millis () > next_batt_chck) {
692718 uint16_t milliVolts = getBattMilliVolts ();
@@ -755,11 +781,11 @@ void UITask::toggleGPS() {
755781 if (strcmp (_sensors->getSettingName (i), " gps" ) == 0 ) {
756782 if (strcmp (_sensors->getSettingValue (i), " 1" ) == 0 ) {
757783 _sensors->setSettingValue (" gps" , " 0" );
758- soundBuzzer (UIEventType::ack);
784+ notify (UIEventType::ack);
759785 showAlert (" GPS: Disabled" , 800 );
760786 } else {
761787 _sensors->setSettingValue (" gps" , " 1" );
762- soundBuzzer (UIEventType::ack);
788+ notify (UIEventType::ack);
763789 showAlert (" GPS: Enabled" , 800 );
764790 }
765791 _next_refresh = 0 ;
@@ -774,7 +800,7 @@ void UITask::toggleBuzzer() {
774800 #ifdef PIN_BUZZER
775801 if (buzzer.isQuiet ()) {
776802 buzzer.quiet (false );
777- soundBuzzer (UIEventType::ack);
803+ notify (UIEventType::ack);
778804 showAlert (" Buzzer: ON" , 800 );
779805 } else {
780806 buzzer.quiet (true );
0 commit comments