Skip to content
4 changes: 4 additions & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,7 @@ List<String> connectWithUs = [
'Developers'
];
String softwareLicenses = 'Software Licenses';
String tryDifferentSearchSuggestion = 'Try a different search term';
String noInstrumentsFoundMessage = 'No instruments found';
String searchInstrumentsHint = 'Search instruments...';
String instrumentsTitle = 'Instruments';
179 changes: 162 additions & 17 deletions lib/view/instruments_screen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pslab/colors.dart';
import 'package:pslab/constants.dart';
import 'package:pslab/view/widgets/applications_list_item.dart';
import 'package:pslab/view/widgets/main_scaffold_widget.dart';
Expand All @@ -13,6 +14,8 @@ class InstrumentsScreen extends StatefulWidget {
}

class _InstrumentsScreenState extends State<InstrumentsScreen> {
final TextEditingController _searchController = TextEditingController();
List<int> _filteredIndices = <int>[];
void _onItemTapped(int index) {
switch (index) {
case 0:
Expand All @@ -32,49 +35,191 @@ class _InstrumentsScreenState extends State<InstrumentsScreen> {
}
}

void _filterInstruments(String query) {
setState(() {
if (query.isEmpty) {
_filteredIndices =
List<int>.generate(instrumentHeadings.length, (index) => index);
} else {
_filteredIndices = List.generate(instrumentHeadings.length, (i) => i)
.where((i) => instrumentHeadings[i]
.toLowerCase()
.contains(query.toLowerCase()))
.toList();
}
});
}

@override
void initState() {
super.initState();
_filteredIndices =
List<int>.generate(instrumentHeadings.length, (index) => index);
WidgetsBinding.instance.addPostFrameCallback((_) {
_setOrientation();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
});
super.initState();
Permission.microphone.request();
}

void _setOrientation() {
SystemChrome.setPreferredOrientations([
SystemChrome.setPreferredOrientations(<DeviceOrientation>[
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}

@override
void dispose() {
_searchController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MainScaffold(
index: 0,
title: 'Instruments',
title: instrumentsTitle,
body: SafeArea(
child: ScrollConfiguration(
behavior: const ScrollBehavior(),
child: ListView.builder(
itemCount: instrumentHeadings.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () => _onItemTapped(index),
child: ApplicationsListItem(
heading: instrumentHeadings[index],
description: instrumentDesc[index],
instrumentIcon: instrumentIcons[index],
child: Column(
children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
boxShadow: const <BoxShadow>[
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.1),
blurRadius: 8,
offset: Offset(0, 2),
),
],
),
child: TextField(
controller: _searchController,
onChanged: _filterInstruments,
decoration: InputDecoration(
hintText: searchInstrumentsHint,
hintStyle: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withAlpha(153),
),
prefixIcon: Icon(
Icons.search,
color: Theme.of(context)
.colorScheme
.onSurface
.withAlpha(179),
),
suffixIcon: _searchController.text.isNotEmpty
? IconButton(
icon: Icon(
Icons.clear,
color: Theme.of(context)
.colorScheme
.onSurface
.withAlpha(179),
),
onPressed: () {
_searchController.clear();
_filterInstruments('');
},
)
: null,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(
color: primaryRed,
width: 1.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(
color: primaryRed,
width: 2.5,
),
),
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20.0,
vertical: 16.0,
),
),
),
);
},
),
),
),
Expanded(
child: _filteredIndices.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.search_off,
size: 64,
color: Theme.of(context)
.colorScheme
.onSurface
.withAlpha(128),
),
const SizedBox(height: 16),
Text(
noInstrumentsFoundMessage,
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(
color: Theme.of(context)
.colorScheme
.onSurface
.withAlpha(179),
),
),
const SizedBox(height: 8),
Text(
tryDifferentSearchSuggestion,
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(
color: Theme.of(context)
.colorScheme
.onSurface
.withAlpha(128),
),
),
],
),
)
: ScrollConfiguration(
behavior: const ScrollBehavior(),
child: ListView.builder(
itemCount: _filteredIndices.length,
itemBuilder: (context, index) {
final int originalIndex = _filteredIndices[index];
return GestureDetector(
onTap: () => _onItemTapped(originalIndex),
child: ApplicationsListItem(
heading: instrumentHeadings[originalIndex],
description: instrumentDesc[originalIndex],
instrumentIcon: instrumentIcons[originalIndex],
),
);
},
),
),
),
],
),
),
);
Expand Down