fix: make keyboard dismissable on mobile devices

This commit is contained in:
Rainer Killinger
2022-09-23 13:48:07 +00:00
parent 4a3f79ca20
commit b2cc1fd91f
10 changed files with 86 additions and 7 deletions

View File

@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest package="de.anyschool.app" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
<activity android:exported="true" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/title_activity_main" android:launchMode="singleTask" android:name="de.anyschool.app.MainActivity" android:theme="@style/AppTheme.NoActionBarLaunch">
<activity android:exported="true" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:windowSoftInputMode="adjustPan" android:label="@string/title_activity_main" android:launchMode="singleTask" android:name="de.anyschool.app.MainActivity" android:theme="@style/AppTheme.NoActionBarLaunch">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@@ -22,6 +22,7 @@ import {environment} from '../environments/environment';
import {StatusBar, Style} from '@capacitor/status-bar';
import {Capacitor} from '@capacitor/core';
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';
import {Keyboard, KeyboardResize} from '@capacitor/keyboard';
/**
* TODO
@@ -45,6 +46,11 @@ export class AppComponent implements AfterContentInit {
title: string;
}>;
/**
* Angular component selectors that should not infulence keyboard state
*/
ommitedEventSources = ['ion-input', 'ion-searchbar'];
/**
*
* @param platform TODO
@@ -104,6 +110,11 @@ export class AppComponent implements AfterContentInit {
'others',
]);
});
window.addEventListener('touchmove', this.touchMoveEvent, true);
if (Capacitor.isNativePlatform()) {
Keyboard.setResizeMode({mode: KeyboardResize.None});
}
}
private async authNotificationsInit() {
@@ -129,4 +140,30 @@ export class AppComponent implements AfterContentInit {
});
await toast.present();
}
/**
* Checks if keyboard should be dissmissed
*/
touchMoveEvent = (event: Event): void => {
if (
this.ommitedEventSources.includes(
(event?.target as unknown as Record<string, string>)?.[
's-hn'
]?.toLowerCase(),
)
) {
return;
}
this.unfocusActiveElement();
};
/**
* Loses focus on the currently active element (meant for input fields).
* Results in virtual keyboard being dissmissed on native and web plattforms.
*/
unfocusActiveElement() {
const activeElement = document.activeElement;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(activeElement as any)?.blur();
}
}

View File

@@ -50,7 +50,10 @@
<ion-content fullscreen="true" #ionContent>
<stapps-navigation-section></stapps-navigation-section>
<stapps-search-section></stapps-search-section>
<stapps-search-section
#search
(focusin)="onSearchBarFocus($event)"
></stapps-search-section>
<stapps-news-section></stapps-news-section>
<stapps-mensa-section></stapps-mensa-section>
<stapps-favorites-section></stapps-favorites-section>

View File

@@ -52,6 +52,8 @@ export class DashboardComponent implements OnInit, OnDestroy {
@ViewChild('schedule', {read: ElementRef}) scheduleRef: ElementRef;
@ViewChild('search', {read: ElementRef}) searchRef: ElementRef;
@ViewChild('ionContent') ionContentRef: IonContent;
collapseAnimation: DashboardCollapse;
@@ -88,6 +90,11 @@ export class DashboardComponent implements OnInit, OnDestroy {
},
};
/**
* Offset from search bar to top
*/
searchToTopOffset = 0;
constructor(
private readonly dataRoutingService: DataRoutingService,
private scheduleProvider: ScheduleProvider,
@@ -121,6 +128,11 @@ export class DashboardComponent implements OnInit, OnDestroy {
);
}
ionViewDidEnter() {
this.searchToTopOffset =
this.searchRef.nativeElement?.getBoundingClientRect().top - 100;
}
async loadNextEvent() {
const dataSeries = await this.scheduleProvider.getDateSeries(
this.uuids,
@@ -142,4 +154,15 @@ export class DashboardComponent implements OnInit, OnDestroy {
this._uuidSubscription.unsubscribe();
this.collapseAnimation.destroy();
}
async onSearchBarFocus(_event: Event) {
this.ionContentRef.getScrollElement().then(element => {
if (
element.scrollHeight - element.clientHeight >=
this.searchToTopOffset
) {
this.ionContentRef.scrollToPoint(0, this.searchToTopOffset, 100);
}
});
}
}

View File

@@ -20,9 +20,11 @@
<div class="searchbar">
<ion-input
type="search"
enterkeyhint="search"
placeholder="{{ 'search.search_bar.placeholder' | translate }}"
(submit)="onSubmitSearch()"
(keyup.enter)="onSubmitSearch()"
(search)="onSubmitSearch()"
[(ngModel)]="searchTerm"
></ion-input>
<ion-icon

View File

@@ -22,10 +22,8 @@
border-radius: var(--border-radius-default);
--padding-start: var(--spacing-md);
--padding-end: var(--spacing-md);
--padding-top: var(--spacing-xl);
--padding-bottom: var(--spacing-xl);
font-size: var(--font-size-xs);
--placeholder-font-weight: var(--font-weight-bold);
--padding-top: var(--spacing-md);
--padding-bottom: var(--spacing-md);
box-shadow: var(--shadow-default);
}
ion-icon {

View File

@@ -14,6 +14,8 @@
*/
import {Component} from '@angular/core';
import {Router} from '@angular/router';
import {Capacitor} from '@capacitor/core';
import {Keyboard} from '@capacitor/keyboard';
/**
* Shows a search input field
@@ -32,6 +34,17 @@ export class SearchSectionComponent {
* User submits search
*/
onSubmitSearch() {
this.router.navigate(['/search', this.searchTerm]);
this.router
.navigate(['/search', this.searchTerm])
.then(() => this.hideKeyboard());
}
/**
* Hides keyboard in native app environments
*/
hideKeyboard() {
if (Capacitor.isNativePlatform()) {
Keyboard.hide();
}
}
}

View File

@@ -25,6 +25,7 @@
<ion-searchbar
(ngModelChange)="searchStringChanged($event)"
(keyup.enter)="hideKeyboard()"
(search)="hideKeyboard()"
[(ngModel)]="queryText"
showClearButton="always"
placeholder="{{ 'search.search_bar.placeholder' | translate }}"

View File

@@ -9,6 +9,7 @@
<ion-searchbar
(ngModelChange)="searchStringChanged($event)"
(keyup.enter)="hideKeyboard()"
(search)="hideKeyboard()"
[(ngModel)]="queryText"
mode="md"
placeholder="{{ 'hebisSearch.search_bar.placeholder' | translate }}"

View File

@@ -26,6 +26,7 @@
<ion-searchbar
(keyup)="searchKeyUp($event)"
(keyup.enter)="hideKeyboard()"
(search)="hideKeyboard()"
[(ngModel)]="queryText"
(ionClear)="searchStringChanged()"
mode="md"