feat: GPS and web compatible
This commit is contained in:
parent
ad0c8e3124
commit
a6f9cfdaf4
@ -25,6 +25,7 @@ if (flutterVersionName == null) {
|
|||||||
android {
|
android {
|
||||||
namespace "com.example.uninav"
|
namespace "com.example.uninav"
|
||||||
compileSdk flutter.compileSdkVersion
|
compileSdk flutter.compileSdkVersion
|
||||||
|
compileSdkVersion 34
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@ -45,7 +46,8 @@ android {
|
|||||||
applicationId "com.example.uninav"
|
applicationId "com.example.uninav"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||||
minSdkVersion flutter.minSdkVersion
|
// minSdkVersion flutter.minSdkVersion
|
||||||
|
minSdkVersion 20
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
@ -41,4 +41,6 @@
|
|||||||
<data android:mimeType="text/plain"/>
|
<data android:mimeType="text/plain"/>
|
||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -384,7 +384,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"name": "O25",
|
"name": "O25",
|
||||||
"layer": "buildings",
|
"layer": "buildings",
|
||||||
"description": "connections: [o26, mensa]"
|
"description": "connections: [o26, mensa, outside]"
|
||||||
},
|
},
|
||||||
"geometry": {
|
"geometry": {
|
||||||
"type": "Polygon",
|
"type": "Polygon",
|
||||||
@ -2432,6 +2432,38 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"id": "gzMDI"
|
"id": "gzMDI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {
|
||||||
|
"name": "door",
|
||||||
|
"description": "type: door\nlevel: 2\nconnects: [o25, outside]",
|
||||||
|
"layer": "layer_2"
|
||||||
|
},
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
9.955606,
|
||||||
|
48.422081
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": "I5NTI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {
|
||||||
|
"name": "door",
|
||||||
|
"description": "type: door\nlevel: 2\nconnects: [o25, mensa]",
|
||||||
|
"layer": "layer_2"
|
||||||
|
},
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
9.955426,
|
||||||
|
48.422062
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": "c1NDY"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -107,7 +107,9 @@ List<Widget> _buildFeatureContent(Feature feature) {
|
|||||||
return feature.type.when(
|
return feature.type.when(
|
||||||
building: () => _buildBuildingContent(feature),
|
building: () => _buildBuildingContent(feature),
|
||||||
lectureHall: () => _buildLectureHallContent(feature),
|
lectureHall: () => _buildLectureHallContent(feature),
|
||||||
room: () => _buildRoomContent(feature),
|
room: (number) => _buildRoomContent(feature, number),
|
||||||
|
pcPool: (number) => _buildPcPoolContent(feature, number),
|
||||||
|
foodDrink: () => _buildFoodAndDrinkContent(feature),
|
||||||
door: (connects) => _buildDoorContent(feature, connects),
|
door: (connects) => _buildDoorContent(feature, connects),
|
||||||
toilet: (toiletType) => _buildToiletContent(feature, toiletType),
|
toilet: (toiletType) => _buildToiletContent(feature, toiletType),
|
||||||
stairs: (connectsLevels) => _buildStairsContent(feature, connectsLevels),
|
stairs: (connectsLevels) => _buildStairsContent(feature, connectsLevels),
|
||||||
@ -130,10 +132,18 @@ List<Widget> _buildLectureHallContent(Feature feature) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the content for the Room feature type.
|
/// Builds the content for the Room feature type.
|
||||||
List<Widget> _buildRoomContent(Feature feature) {
|
List<Widget> _buildRoomContent(Feature feature, String roomNumber) {
|
||||||
return [Text('Room: ${feature.name}')];
|
return [Text('Room: ${feature.name}')];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildPcPoolContent(Feature feature, String roomNumber) {
|
||||||
|
return [Text('PC Pool: ${feature.name}')];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildFoodAndDrinkContent(Feature feature) {
|
||||||
|
return [Text('${feature.name} (Food/Drink)')];
|
||||||
|
}
|
||||||
|
|
||||||
/// Builds the content for the Door feature type.
|
/// Builds the content for the Door feature type.
|
||||||
List<Widget> _buildDoorContent(Feature feature, List<String> connects) {
|
List<Widget> _buildDoorContent(Feature feature, List<String> connects) {
|
||||||
return [
|
return [
|
||||||
|
@ -14,6 +14,7 @@ List<Widget> renderLevel(
|
|||||||
int level,
|
int level,
|
||||||
) {
|
) {
|
||||||
return <Widget>[
|
return <Widget>[
|
||||||
|
// Lecture Halls
|
||||||
LevelLayer(
|
LevelLayer(
|
||||||
filter: (feature) =>
|
filter: (feature) =>
|
||||||
feature.level == level && feature.type is LectureHall,
|
feature.level == level && feature.type is LectureHall,
|
||||||
@ -43,6 +44,8 @@ List<Widget> renderLevel(
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Rooms (Seminar Rooms)
|
||||||
LevelLayer(
|
LevelLayer(
|
||||||
filter: (feature) => feature.level == level && feature.type is Room,
|
filter: (feature) => feature.level == level && feature.type is Room,
|
||||||
polyConstructor: (feature) => feature
|
polyConstructor: (feature) => feature
|
||||||
@ -55,7 +58,25 @@ List<Widget> renderLevel(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
markerConstructor: (feature) => Marker(
|
||||||
|
width: 100,
|
||||||
|
height: 70,
|
||||||
|
point: feature.getPoint().unwrap(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.co_present_rounded,
|
||||||
|
color: Colors.amber,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
(feature.type as Room).roomNumber,
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
)),
|
||||||
|
// Doors Layer
|
||||||
LevelLayer(
|
LevelLayer(
|
||||||
filter: (feature) => feature.level == level && feature.type is Door,
|
filter: (feature) => feature.level == level && feature.type is Door,
|
||||||
markerConstructor: (feature) {
|
markerConstructor: (feature) {
|
||||||
@ -72,6 +93,72 @@ List<Widget> renderLevel(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Food and Drink Layer
|
||||||
|
LevelLayer(
|
||||||
|
filter: (feature) => feature.level == level && feature.type is FoodDrink,
|
||||||
|
markerConstructor: (feature) {
|
||||||
|
final point = feature.getPoint().unwrap();
|
||||||
|
return Marker(
|
||||||
|
width: 21,
|
||||||
|
height: 21,
|
||||||
|
point: point,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.restaurant,
|
||||||
|
color: Colors.deepOrange,
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
polyConstructor: (feature) => feature
|
||||||
|
.getPolygon(
|
||||||
|
constructor: (pts) => Polygon(
|
||||||
|
points: pts,
|
||||||
|
color: Colors.deepOrange.withOpacity(0.2),
|
||||||
|
borderColor: Colors.deepOrange,
|
||||||
|
borderStrokeWidth: 2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// PC Pools layer
|
||||||
|
LevelLayer(
|
||||||
|
filter: (feature) => feature.level == level && feature.type is PcPool,
|
||||||
|
markerConstructor: (feature) {
|
||||||
|
final point = feature.getPoint().unwrap();
|
||||||
|
return Marker(
|
||||||
|
width: 100,
|
||||||
|
height: 70,
|
||||||
|
point: point,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.computer,
|
||||||
|
color: Colors.cyan,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
(feature.type as PcPool).roomNumber,
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
polyConstructor: (feature) => feature
|
||||||
|
.getPolygon(
|
||||||
|
constructor: (pts) => Polygon(
|
||||||
|
points: pts,
|
||||||
|
color: Colors.cyan.withOpacity(0.2),
|
||||||
|
borderColor: Colors.cyan,
|
||||||
|
borderStrokeWidth: 2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Toilets Layer
|
||||||
LevelLayer(
|
LevelLayer(
|
||||||
filter: (feature) => feature.level == level && feature.type is Toilet,
|
filter: (feature) => feature.level == level && feature.type is Toilet,
|
||||||
markerConstructor: (feature) {
|
markerConstructor: (feature) {
|
||||||
@ -84,12 +171,14 @@ List<Widget> renderLevel(
|
|||||||
point: point,
|
point: point,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
findToiletIcon(type),
|
findToiletIcon(type),
|
||||||
color: Colors.purple,
|
color: Colors.blue.shade700,
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Stairs layer
|
||||||
LevelLayer(
|
LevelLayer(
|
||||||
filter: (feature) =>
|
filter: (feature) =>
|
||||||
feature.type is Stairs &&
|
feature.type is Stairs &&
|
||||||
@ -108,6 +197,8 @@ List<Widget> renderLevel(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Lift layer
|
||||||
LevelLayer(
|
LevelLayer(
|
||||||
filter: (feature) =>
|
filter: (feature) =>
|
||||||
feature.type is Lift &&
|
feature.type is Lift &&
|
||||||
|
@ -1,910 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'isar_controller.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// IsarCollectionGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
// coverage:ignore-file
|
|
||||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
|
||||||
|
|
||||||
extension GetSettingsCollection on Isar {
|
|
||||||
IsarCollection<Settings> get settings => this.collection();
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingsSchema = CollectionSchema(
|
|
||||||
name: r'Settings',
|
|
||||||
id: -8656046621518759136,
|
|
||||||
properties: {
|
|
||||||
r'femaleToilets': PropertySchema(
|
|
||||||
id: 0,
|
|
||||||
name: r'femaleToilets',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'handicapToilets': PropertySchema(
|
|
||||||
id: 1,
|
|
||||||
name: r'handicapToilets',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'maleToilets': PropertySchema(
|
|
||||||
id: 2,
|
|
||||||
name: r'maleToilets',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showComputerPools': PropertySchema(
|
|
||||||
id: 3,
|
|
||||||
name: r'showComputerPools',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showDoors': PropertySchema(
|
|
||||||
id: 4,
|
|
||||||
name: r'showDoors',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showElevators': PropertySchema(
|
|
||||||
id: 5,
|
|
||||||
name: r'showElevators',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showFoodAndDrink': PropertySchema(
|
|
||||||
id: 6,
|
|
||||||
name: r'showFoodAndDrink',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showIcons': PropertySchema(
|
|
||||||
id: 7,
|
|
||||||
name: r'showIcons',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showLectureHalls': PropertySchema(
|
|
||||||
id: 8,
|
|
||||||
name: r'showLectureHalls',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showSeminarRooms': PropertySchema(
|
|
||||||
id: 9,
|
|
||||||
name: r'showSeminarRooms',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showStairs': PropertySchema(
|
|
||||||
id: 10,
|
|
||||||
name: r'showStairs',
|
|
||||||
type: IsarType.bool,
|
|
||||||
),
|
|
||||||
r'showToilets': PropertySchema(
|
|
||||||
id: 11,
|
|
||||||
name: r'showToilets',
|
|
||||||
type: IsarType.bool,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
estimateSize: _settingsEstimateSize,
|
|
||||||
serialize: _settingsSerialize,
|
|
||||||
deserialize: _settingsDeserialize,
|
|
||||||
deserializeProp: _settingsDeserializeProp,
|
|
||||||
idName: r'id',
|
|
||||||
indexes: {},
|
|
||||||
links: {},
|
|
||||||
embeddedSchemas: {},
|
|
||||||
getId: _settingsGetId,
|
|
||||||
getLinks: _settingsGetLinks,
|
|
||||||
attach: _settingsAttach,
|
|
||||||
version: '3.1.0+1',
|
|
||||||
);
|
|
||||||
|
|
||||||
int _settingsEstimateSize(
|
|
||||||
Settings object,
|
|
||||||
List<int> offsets,
|
|
||||||
Map<Type, List<int>> allOffsets,
|
|
||||||
) {
|
|
||||||
var bytesCount = offsets.last;
|
|
||||||
return bytesCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _settingsSerialize(
|
|
||||||
Settings object,
|
|
||||||
IsarWriter writer,
|
|
||||||
List<int> offsets,
|
|
||||||
Map<Type, List<int>> allOffsets,
|
|
||||||
) {
|
|
||||||
writer.writeBool(offsets[0], object.femaleToilets);
|
|
||||||
writer.writeBool(offsets[1], object.handicapToilets);
|
|
||||||
writer.writeBool(offsets[2], object.maleToilets);
|
|
||||||
writer.writeBool(offsets[3], object.showComputerPools);
|
|
||||||
writer.writeBool(offsets[4], object.showDoors);
|
|
||||||
writer.writeBool(offsets[5], object.showElevators);
|
|
||||||
writer.writeBool(offsets[6], object.showFoodAndDrink);
|
|
||||||
writer.writeBool(offsets[7], object.showIcons);
|
|
||||||
writer.writeBool(offsets[8], object.showLectureHalls);
|
|
||||||
writer.writeBool(offsets[9], object.showSeminarRooms);
|
|
||||||
writer.writeBool(offsets[10], object.showStairs);
|
|
||||||
writer.writeBool(offsets[11], object.showToilets);
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings _settingsDeserialize(
|
|
||||||
Id id,
|
|
||||||
IsarReader reader,
|
|
||||||
List<int> offsets,
|
|
||||||
Map<Type, List<int>> allOffsets,
|
|
||||||
) {
|
|
||||||
final object = Settings();
|
|
||||||
object.femaleToilets = reader.readBool(offsets[0]);
|
|
||||||
object.handicapToilets = reader.readBool(offsets[1]);
|
|
||||||
object.id = id;
|
|
||||||
object.maleToilets = reader.readBool(offsets[2]);
|
|
||||||
object.showComputerPools = reader.readBool(offsets[3]);
|
|
||||||
object.showDoors = reader.readBool(offsets[4]);
|
|
||||||
object.showElevators = reader.readBool(offsets[5]);
|
|
||||||
object.showFoodAndDrink = reader.readBool(offsets[6]);
|
|
||||||
object.showIcons = reader.readBool(offsets[7]);
|
|
||||||
object.showLectureHalls = reader.readBool(offsets[8]);
|
|
||||||
object.showSeminarRooms = reader.readBool(offsets[9]);
|
|
||||||
object.showStairs = reader.readBool(offsets[10]);
|
|
||||||
object.showToilets = reader.readBool(offsets[11]);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
P _settingsDeserializeProp<P>(
|
|
||||||
IsarReader reader,
|
|
||||||
int propertyId,
|
|
||||||
int offset,
|
|
||||||
Map<Type, List<int>> allOffsets,
|
|
||||||
) {
|
|
||||||
switch (propertyId) {
|
|
||||||
case 0:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 1:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 2:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 3:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 4:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 5:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 6:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 7:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 8:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 9:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 10:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
case 11:
|
|
||||||
return (reader.readBool(offset)) as P;
|
|
||||||
default:
|
|
||||||
throw IsarError('Unknown property with id $propertyId');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Id _settingsGetId(Settings object) {
|
|
||||||
return object.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<IsarLinkBase<dynamic>> _settingsGetLinks(Settings object) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
void _settingsAttach(IsarCollection<dynamic> col, Id id, Settings object) {
|
|
||||||
object.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQueryWhereSort on QueryBuilder<Settings, Settings, QWhere> {
|
|
||||||
QueryBuilder<Settings, Settings, QAfterWhere> anyId() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addWhereClause(const IdWhereClause.any());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQueryWhere on QueryBuilder<Settings, Settings, QWhereClause> {
|
|
||||||
QueryBuilder<Settings, Settings, QAfterWhereClause> idEqualTo(Id id) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addWhereClause(IdWhereClause.between(
|
|
||||||
lower: id,
|
|
||||||
upper: id,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterWhereClause> idNotEqualTo(Id id) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
if (query.whereSort == Sort.asc) {
|
|
||||||
return query
|
|
||||||
.addWhereClause(
|
|
||||||
IdWhereClause.lessThan(upper: id, includeUpper: false),
|
|
||||||
)
|
|
||||||
.addWhereClause(
|
|
||||||
IdWhereClause.greaterThan(lower: id, includeLower: false),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return query
|
|
||||||
.addWhereClause(
|
|
||||||
IdWhereClause.greaterThan(lower: id, includeLower: false),
|
|
||||||
)
|
|
||||||
.addWhereClause(
|
|
||||||
IdWhereClause.lessThan(upper: id, includeUpper: false),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterWhereClause> idGreaterThan(Id id,
|
|
||||||
{bool include = false}) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addWhereClause(
|
|
||||||
IdWhereClause.greaterThan(lower: id, includeLower: include),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterWhereClause> idLessThan(Id id,
|
|
||||||
{bool include = false}) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addWhereClause(
|
|
||||||
IdWhereClause.lessThan(upper: id, includeUpper: include),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterWhereClause> idBetween(
|
|
||||||
Id lowerId,
|
|
||||||
Id upperId, {
|
|
||||||
bool includeLower = true,
|
|
||||||
bool includeUpper = true,
|
|
||||||
}) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addWhereClause(IdWhereClause.between(
|
|
||||||
lower: lowerId,
|
|
||||||
includeLower: includeLower,
|
|
||||||
upper: upperId,
|
|
||||||
includeUpper: includeUpper,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQueryFilter
|
|
||||||
on QueryBuilder<Settings, Settings, QFilterCondition> {
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> femaleToiletsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'femaleToilets',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition>
|
|
||||||
handicapToiletsEqualTo(bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'handicapToilets',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> idEqualTo(Id value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'id',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> idGreaterThan(
|
|
||||||
Id value, {
|
|
||||||
bool include = false,
|
|
||||||
}) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
|
||||||
include: include,
|
|
||||||
property: r'id',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> idLessThan(
|
|
||||||
Id value, {
|
|
||||||
bool include = false,
|
|
||||||
}) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.lessThan(
|
|
||||||
include: include,
|
|
||||||
property: r'id',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> idBetween(
|
|
||||||
Id lower,
|
|
||||||
Id upper, {
|
|
||||||
bool includeLower = true,
|
|
||||||
bool includeUpper = true,
|
|
||||||
}) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.between(
|
|
||||||
property: r'id',
|
|
||||||
lower: lower,
|
|
||||||
includeLower: includeLower,
|
|
||||||
upper: upper,
|
|
||||||
includeUpper: includeUpper,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> maleToiletsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'maleToilets',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition>
|
|
||||||
showComputerPoolsEqualTo(bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showComputerPools',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> showDoorsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showDoors',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> showElevatorsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showElevators',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition>
|
|
||||||
showFoodAndDrinkEqualTo(bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showFoodAndDrink',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> showIconsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showIcons',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition>
|
|
||||||
showLectureHallsEqualTo(bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showLectureHalls',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition>
|
|
||||||
showSeminarRoomsEqualTo(bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showSeminarRooms',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> showStairsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showStairs',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterFilterCondition> showToiletsEqualTo(
|
|
||||||
bool value) {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addFilterCondition(FilterCondition.equalTo(
|
|
||||||
property: r'showToilets',
|
|
||||||
value: value,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQueryObject
|
|
||||||
on QueryBuilder<Settings, Settings, QFilterCondition> {}
|
|
||||||
|
|
||||||
extension SettingsQueryLinks
|
|
||||||
on QueryBuilder<Settings, Settings, QFilterCondition> {}
|
|
||||||
|
|
||||||
extension SettingsQuerySortBy on QueryBuilder<Settings, Settings, QSortBy> {
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByFemaleToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'femaleToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByFemaleToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'femaleToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByHandicapToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'handicapToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByHandicapToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'handicapToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByMaleToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'maleToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByMaleToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'maleToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowComputerPools() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showComputerPools', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowComputerPoolsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showComputerPools', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowDoors() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showDoors', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowDoorsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showDoors', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowElevators() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showElevators', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowElevatorsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showElevators', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowFoodAndDrink() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showFoodAndDrink', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowFoodAndDrinkDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showFoodAndDrink', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowIcons() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showIcons', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowIconsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showIcons', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowLectureHalls() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showLectureHalls', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowLectureHallsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showLectureHalls', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowSeminarRooms() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showSeminarRooms', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowSeminarRoomsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showSeminarRooms', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowStairs() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showStairs', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowStairsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showStairs', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> sortByShowToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQuerySortThenBy
|
|
||||||
on QueryBuilder<Settings, Settings, QSortThenBy> {
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByFemaleToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'femaleToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByFemaleToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'femaleToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByHandicapToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'handicapToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByHandicapToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'handicapToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenById() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'id', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByIdDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'id', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByMaleToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'maleToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByMaleToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'maleToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowComputerPools() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showComputerPools', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowComputerPoolsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showComputerPools', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowDoors() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showDoors', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowDoorsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showDoors', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowElevators() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showElevators', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowElevatorsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showElevators', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowFoodAndDrink() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showFoodAndDrink', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowFoodAndDrinkDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showFoodAndDrink', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowIcons() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showIcons', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowIconsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showIcons', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowLectureHalls() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showLectureHalls', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowLectureHallsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showLectureHalls', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowSeminarRooms() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showSeminarRooms', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowSeminarRoomsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showSeminarRooms', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowStairs() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showStairs', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowStairsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showStairs', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showToilets', Sort.asc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QAfterSortBy> thenByShowToiletsDesc() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addSortBy(r'showToilets', Sort.desc);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQueryWhereDistinct
|
|
||||||
on QueryBuilder<Settings, Settings, QDistinct> {
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByFemaleToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'femaleToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByHandicapToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'handicapToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByMaleToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'maleToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowComputerPools() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showComputerPools');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowDoors() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showDoors');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowElevators() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showElevators');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowFoodAndDrink() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showFoodAndDrink');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowIcons() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showIcons');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowLectureHalls() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showLectureHalls');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowSeminarRooms() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showSeminarRooms');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowStairs() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showStairs');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, Settings, QDistinct> distinctByShowToilets() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addDistinctBy(r'showToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SettingsQueryProperty
|
|
||||||
on QueryBuilder<Settings, Settings, QQueryProperty> {
|
|
||||||
QueryBuilder<Settings, int, QQueryOperations> idProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'id');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> femaleToiletsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'femaleToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> handicapToiletsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'handicapToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> maleToiletsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'maleToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showComputerPoolsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showComputerPools');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showDoorsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showDoors');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showElevatorsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showElevators');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showFoodAndDrinkProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showFoodAndDrink');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showIconsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showIcons');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showLectureHallsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showLectureHalls');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showSeminarRoomsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showSeminarRooms');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showStairsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showStairs');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder<Settings, bool, QQueryOperations> showToiletsProperty() {
|
|
||||||
return QueryBuilder.apply(this, (query) {
|
|
||||||
return query.addPropertyName(r'showToilets');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +1,17 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:anyhow/anyhow.dart';
|
import 'package:anyhow/anyhow.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:geojson_vi/geojson_vi.dart';
|
import 'package:geojson_vi/geojson_vi.dart';
|
||||||
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:uninav/components/feature_bottom_sheet.dart';
|
import 'package:uninav/components/feature_bottom_sheet.dart';
|
||||||
import 'package:uninav/data/geo/model.dart';
|
import 'package:uninav/data/geo/model.dart';
|
||||||
import 'package:uninav/data/geo/parser.dart';
|
import 'package:uninav/data/geo/parser.dart';
|
||||||
import 'package:uninav/util/geojson_util.dart';
|
import 'package:uninav/util/geojson_util.dart';
|
||||||
|
import 'package:uninav/util/geolocator.dart';
|
||||||
import 'package:uninav/util/geomath.dart';
|
import 'package:uninav/util/geomath.dart';
|
||||||
|
|
||||||
class MyMapController extends GetxController {
|
class MyMapController extends GetxController {
|
||||||
@ -17,6 +20,10 @@ class MyMapController extends GetxController {
|
|||||||
final RxList<Feature> features = <Feature>[].obs;
|
final RxList<Feature> features = <Feature>[].obs;
|
||||||
final currentLevel = 1.obs;
|
final currentLevel = 1.obs;
|
||||||
final levels = <int>[1].obs;
|
final levels = <int>[1].obs;
|
||||||
|
final Rx<Position?> position = null.obs;
|
||||||
|
|
||||||
|
bool _locationEnsured = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
onInit() async {
|
onInit() async {
|
||||||
print("init");
|
print("init");
|
||||||
@ -98,6 +105,8 @@ class MyMapController extends GetxController {
|
|||||||
feature.geometry, feature.id);
|
feature.geometry, feature.id);
|
||||||
if (parsed case Ok(:final ok)) {
|
if (parsed case Ok(:final ok)) {
|
||||||
featuresList.add(ok);
|
featuresList.add(ok);
|
||||||
|
} else {
|
||||||
|
print('Error parsing feature: $parsed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,4 +146,46 @@ class MyMapController extends GetxController {
|
|||||||
}
|
}
|
||||||
showFeatureBottomSheet(feature, closestFeatures);
|
showFeatureBottomSheet(feature, closestFeatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Result<Position>> getCurrentPosition() async {
|
||||||
|
if (!_locationEnsured) {
|
||||||
|
final ensureRes = await ensureLocationPermission();
|
||||||
|
if (ensureRes is Err) {
|
||||||
|
// TODO: check that it works
|
||||||
|
return ensureRes as Err<Position>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_locationEnsured = true;
|
||||||
|
try {
|
||||||
|
final pos = await Geolocator.getCurrentPosition(
|
||||||
|
// desiredAccuracy: LocationAccuracy.high,
|
||||||
|
timeLimit: Duration(minutes: 1),
|
||||||
|
);
|
||||||
|
position.value = pos;
|
||||||
|
return Ok(pos);
|
||||||
|
} on TimeoutException catch (e) {
|
||||||
|
return bail("Timeout while waiting for location lock: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Result<()>> subscribePosition() async {
|
||||||
|
if (!_locationEnsured) {
|
||||||
|
final ensureRes = await ensureLocationPermission();
|
||||||
|
if (ensureRes is Err) {
|
||||||
|
// TODO: check that it works
|
||||||
|
return ensureRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_locationEnsured = true;
|
||||||
|
Geolocator.getPositionStream(
|
||||||
|
locationSettings: const LocationSettings(
|
||||||
|
accuracy: LocationAccuracy.high,
|
||||||
|
distanceFilter: 100,
|
||||||
|
//timeLimit: Duration(minutes: 10)
|
||||||
|
),
|
||||||
|
).listen((pos) {
|
||||||
|
position.value = pos;
|
||||||
|
});
|
||||||
|
return const Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
72
lib/controllers/shared_prefs_controller.dart
Normal file
72
lib/controllers/shared_prefs_controller.dart
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'shared_prefs_controller.freezed.dart';
|
||||||
|
part 'shared_prefs_controller.g.dart';
|
||||||
|
|
||||||
|
class SharedPrefsController {
|
||||||
|
late SharedPreferences _sharedPrefs;
|
||||||
|
|
||||||
|
final Rx<Settings> settings = Settings().obs;
|
||||||
|
|
||||||
|
SharedPrefsController();
|
||||||
|
|
||||||
|
Future<void> initialize() async {
|
||||||
|
_sharedPrefs = await SharedPreferences.getInstance();
|
||||||
|
try {
|
||||||
|
final settingsJson = _sharedPrefs.getString("settings");
|
||||||
|
if (settingsJson != null) {
|
||||||
|
settings.value = Settings.fromJson(jsonDecode(settingsJson));
|
||||||
|
} else {
|
||||||
|
settings.value = const Settings();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
settings.value = const Settings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> persistSettings() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString('settings', jsonEncode(settings.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Settings> loadSettings() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final settingsJson = prefs.getString('settings');
|
||||||
|
return settingsJson != null
|
||||||
|
? Settings.fromJson(jsonDecode(settingsJson))
|
||||||
|
: const Settings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class Settings with _$Settings {
|
||||||
|
const factory Settings({
|
||||||
|
@Default(1) int id,
|
||||||
|
@Default(true) bool showIcons,
|
||||||
|
@Default(true) bool showElevators,
|
||||||
|
@Default(true) bool showFoodAndDrink,
|
||||||
|
@Default(true) bool showLectureHalls,
|
||||||
|
@Default(true) bool showComputerPools,
|
||||||
|
@Default(true) bool showSeminarRooms,
|
||||||
|
@Default(true) bool showToilets,
|
||||||
|
@Default(true) bool showStairs,
|
||||||
|
@Default(true) bool showDoors,
|
||||||
|
@Default(false) bool maleToilets,
|
||||||
|
@Default(false) bool femaleToilets,
|
||||||
|
@Default(false) bool handicapToilets,
|
||||||
|
}) = _Settings;
|
||||||
|
|
||||||
|
factory Settings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SettingsFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ToiletPreference {
|
||||||
|
male,
|
||||||
|
female,
|
||||||
|
disabled,
|
||||||
|
}
|
433
lib/controllers/shared_prefs_controller.freezed.dart
Normal file
433
lib/controllers/shared_prefs_controller.freezed.dart
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'shared_prefs_controller.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
Settings _$SettingsFromJson(Map<String, dynamic> json) {
|
||||||
|
return _Settings.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$Settings {
|
||||||
|
int get id => throw _privateConstructorUsedError;
|
||||||
|
bool get showIcons => throw _privateConstructorUsedError;
|
||||||
|
bool get showElevators => throw _privateConstructorUsedError;
|
||||||
|
bool get showFoodAndDrink => throw _privateConstructorUsedError;
|
||||||
|
bool get showLectureHalls => throw _privateConstructorUsedError;
|
||||||
|
bool get showComputerPools => throw _privateConstructorUsedError;
|
||||||
|
bool get showSeminarRooms => throw _privateConstructorUsedError;
|
||||||
|
bool get showToilets => throw _privateConstructorUsedError;
|
||||||
|
bool get showStairs => throw _privateConstructorUsedError;
|
||||||
|
bool get showDoors => throw _privateConstructorUsedError;
|
||||||
|
bool get maleToilets => throw _privateConstructorUsedError;
|
||||||
|
bool get femaleToilets => throw _privateConstructorUsedError;
|
||||||
|
bool get handicapToilets => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$SettingsCopyWith<Settings> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $SettingsCopyWith<$Res> {
|
||||||
|
factory $SettingsCopyWith(Settings value, $Res Function(Settings) then) =
|
||||||
|
_$SettingsCopyWithImpl<$Res, Settings>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
bool showIcons,
|
||||||
|
bool showElevators,
|
||||||
|
bool showFoodAndDrink,
|
||||||
|
bool showLectureHalls,
|
||||||
|
bool showComputerPools,
|
||||||
|
bool showSeminarRooms,
|
||||||
|
bool showToilets,
|
||||||
|
bool showStairs,
|
||||||
|
bool showDoors,
|
||||||
|
bool maleToilets,
|
||||||
|
bool femaleToilets,
|
||||||
|
bool handicapToilets});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$SettingsCopyWithImpl<$Res, $Val extends Settings>
|
||||||
|
implements $SettingsCopyWith<$Res> {
|
||||||
|
_$SettingsCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? showIcons = null,
|
||||||
|
Object? showElevators = null,
|
||||||
|
Object? showFoodAndDrink = null,
|
||||||
|
Object? showLectureHalls = null,
|
||||||
|
Object? showComputerPools = null,
|
||||||
|
Object? showSeminarRooms = null,
|
||||||
|
Object? showToilets = null,
|
||||||
|
Object? showStairs = null,
|
||||||
|
Object? showDoors = null,
|
||||||
|
Object? maleToilets = null,
|
||||||
|
Object? femaleToilets = null,
|
||||||
|
Object? handicapToilets = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
showIcons: null == showIcons
|
||||||
|
? _value.showIcons
|
||||||
|
: showIcons // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showElevators: null == showElevators
|
||||||
|
? _value.showElevators
|
||||||
|
: showElevators // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showFoodAndDrink: null == showFoodAndDrink
|
||||||
|
? _value.showFoodAndDrink
|
||||||
|
: showFoodAndDrink // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showLectureHalls: null == showLectureHalls
|
||||||
|
? _value.showLectureHalls
|
||||||
|
: showLectureHalls // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showComputerPools: null == showComputerPools
|
||||||
|
? _value.showComputerPools
|
||||||
|
: showComputerPools // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showSeminarRooms: null == showSeminarRooms
|
||||||
|
? _value.showSeminarRooms
|
||||||
|
: showSeminarRooms // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showToilets: null == showToilets
|
||||||
|
? _value.showToilets
|
||||||
|
: showToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showStairs: null == showStairs
|
||||||
|
? _value.showStairs
|
||||||
|
: showStairs // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showDoors: null == showDoors
|
||||||
|
? _value.showDoors
|
||||||
|
: showDoors // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
maleToilets: null == maleToilets
|
||||||
|
? _value.maleToilets
|
||||||
|
: maleToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
femaleToilets: null == femaleToilets
|
||||||
|
? _value.femaleToilets
|
||||||
|
: femaleToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
handicapToilets: null == handicapToilets
|
||||||
|
? _value.handicapToilets
|
||||||
|
: handicapToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$SettingsImplCopyWith<$Res>
|
||||||
|
implements $SettingsCopyWith<$Res> {
|
||||||
|
factory _$$SettingsImplCopyWith(
|
||||||
|
_$SettingsImpl value, $Res Function(_$SettingsImpl) then) =
|
||||||
|
__$$SettingsImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
bool showIcons,
|
||||||
|
bool showElevators,
|
||||||
|
bool showFoodAndDrink,
|
||||||
|
bool showLectureHalls,
|
||||||
|
bool showComputerPools,
|
||||||
|
bool showSeminarRooms,
|
||||||
|
bool showToilets,
|
||||||
|
bool showStairs,
|
||||||
|
bool showDoors,
|
||||||
|
bool maleToilets,
|
||||||
|
bool femaleToilets,
|
||||||
|
bool handicapToilets});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$SettingsImplCopyWithImpl<$Res>
|
||||||
|
extends _$SettingsCopyWithImpl<$Res, _$SettingsImpl>
|
||||||
|
implements _$$SettingsImplCopyWith<$Res> {
|
||||||
|
__$$SettingsImplCopyWithImpl(
|
||||||
|
_$SettingsImpl _value, $Res Function(_$SettingsImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? showIcons = null,
|
||||||
|
Object? showElevators = null,
|
||||||
|
Object? showFoodAndDrink = null,
|
||||||
|
Object? showLectureHalls = null,
|
||||||
|
Object? showComputerPools = null,
|
||||||
|
Object? showSeminarRooms = null,
|
||||||
|
Object? showToilets = null,
|
||||||
|
Object? showStairs = null,
|
||||||
|
Object? showDoors = null,
|
||||||
|
Object? maleToilets = null,
|
||||||
|
Object? femaleToilets = null,
|
||||||
|
Object? handicapToilets = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$SettingsImpl(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
showIcons: null == showIcons
|
||||||
|
? _value.showIcons
|
||||||
|
: showIcons // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showElevators: null == showElevators
|
||||||
|
? _value.showElevators
|
||||||
|
: showElevators // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showFoodAndDrink: null == showFoodAndDrink
|
||||||
|
? _value.showFoodAndDrink
|
||||||
|
: showFoodAndDrink // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showLectureHalls: null == showLectureHalls
|
||||||
|
? _value.showLectureHalls
|
||||||
|
: showLectureHalls // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showComputerPools: null == showComputerPools
|
||||||
|
? _value.showComputerPools
|
||||||
|
: showComputerPools // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showSeminarRooms: null == showSeminarRooms
|
||||||
|
? _value.showSeminarRooms
|
||||||
|
: showSeminarRooms // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showToilets: null == showToilets
|
||||||
|
? _value.showToilets
|
||||||
|
: showToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showStairs: null == showStairs
|
||||||
|
? _value.showStairs
|
||||||
|
: showStairs // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
showDoors: null == showDoors
|
||||||
|
? _value.showDoors
|
||||||
|
: showDoors // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
maleToilets: null == maleToilets
|
||||||
|
? _value.maleToilets
|
||||||
|
: maleToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
femaleToilets: null == femaleToilets
|
||||||
|
? _value.femaleToilets
|
||||||
|
: femaleToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
handicapToilets: null == handicapToilets
|
||||||
|
? _value.handicapToilets
|
||||||
|
: handicapToilets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$SettingsImpl implements _Settings {
|
||||||
|
const _$SettingsImpl(
|
||||||
|
{this.id = 1,
|
||||||
|
this.showIcons = true,
|
||||||
|
this.showElevators = true,
|
||||||
|
this.showFoodAndDrink = true,
|
||||||
|
this.showLectureHalls = true,
|
||||||
|
this.showComputerPools = true,
|
||||||
|
this.showSeminarRooms = true,
|
||||||
|
this.showToilets = true,
|
||||||
|
this.showStairs = true,
|
||||||
|
this.showDoors = true,
|
||||||
|
this.maleToilets = false,
|
||||||
|
this.femaleToilets = false,
|
||||||
|
this.handicapToilets = false});
|
||||||
|
|
||||||
|
factory _$SettingsImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$SettingsImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final int id;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showIcons;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showElevators;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showFoodAndDrink;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showLectureHalls;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showComputerPools;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showSeminarRooms;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showToilets;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showStairs;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool showDoors;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool maleToilets;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool femaleToilets;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool handicapToilets;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Settings(id: $id, showIcons: $showIcons, showElevators: $showElevators, showFoodAndDrink: $showFoodAndDrink, showLectureHalls: $showLectureHalls, showComputerPools: $showComputerPools, showSeminarRooms: $showSeminarRooms, showToilets: $showToilets, showStairs: $showStairs, showDoors: $showDoors, maleToilets: $maleToilets, femaleToilets: $femaleToilets, handicapToilets: $handicapToilets)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$SettingsImpl &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.showIcons, showIcons) ||
|
||||||
|
other.showIcons == showIcons) &&
|
||||||
|
(identical(other.showElevators, showElevators) ||
|
||||||
|
other.showElevators == showElevators) &&
|
||||||
|
(identical(other.showFoodAndDrink, showFoodAndDrink) ||
|
||||||
|
other.showFoodAndDrink == showFoodAndDrink) &&
|
||||||
|
(identical(other.showLectureHalls, showLectureHalls) ||
|
||||||
|
other.showLectureHalls == showLectureHalls) &&
|
||||||
|
(identical(other.showComputerPools, showComputerPools) ||
|
||||||
|
other.showComputerPools == showComputerPools) &&
|
||||||
|
(identical(other.showSeminarRooms, showSeminarRooms) ||
|
||||||
|
other.showSeminarRooms == showSeminarRooms) &&
|
||||||
|
(identical(other.showToilets, showToilets) ||
|
||||||
|
other.showToilets == showToilets) &&
|
||||||
|
(identical(other.showStairs, showStairs) ||
|
||||||
|
other.showStairs == showStairs) &&
|
||||||
|
(identical(other.showDoors, showDoors) ||
|
||||||
|
other.showDoors == showDoors) &&
|
||||||
|
(identical(other.maleToilets, maleToilets) ||
|
||||||
|
other.maleToilets == maleToilets) &&
|
||||||
|
(identical(other.femaleToilets, femaleToilets) ||
|
||||||
|
other.femaleToilets == femaleToilets) &&
|
||||||
|
(identical(other.handicapToilets, handicapToilets) ||
|
||||||
|
other.handicapToilets == handicapToilets));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
id,
|
||||||
|
showIcons,
|
||||||
|
showElevators,
|
||||||
|
showFoodAndDrink,
|
||||||
|
showLectureHalls,
|
||||||
|
showComputerPools,
|
||||||
|
showSeminarRooms,
|
||||||
|
showToilets,
|
||||||
|
showStairs,
|
||||||
|
showDoors,
|
||||||
|
maleToilets,
|
||||||
|
femaleToilets,
|
||||||
|
handicapToilets);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$SettingsImplCopyWith<_$SettingsImpl> get copyWith =>
|
||||||
|
__$$SettingsImplCopyWithImpl<_$SettingsImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$SettingsImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Settings implements Settings {
|
||||||
|
const factory _Settings(
|
||||||
|
{final int id,
|
||||||
|
final bool showIcons,
|
||||||
|
final bool showElevators,
|
||||||
|
final bool showFoodAndDrink,
|
||||||
|
final bool showLectureHalls,
|
||||||
|
final bool showComputerPools,
|
||||||
|
final bool showSeminarRooms,
|
||||||
|
final bool showToilets,
|
||||||
|
final bool showStairs,
|
||||||
|
final bool showDoors,
|
||||||
|
final bool maleToilets,
|
||||||
|
final bool femaleToilets,
|
||||||
|
final bool handicapToilets}) = _$SettingsImpl;
|
||||||
|
|
||||||
|
factory _Settings.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$SettingsImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get id;
|
||||||
|
@override
|
||||||
|
bool get showIcons;
|
||||||
|
@override
|
||||||
|
bool get showElevators;
|
||||||
|
@override
|
||||||
|
bool get showFoodAndDrink;
|
||||||
|
@override
|
||||||
|
bool get showLectureHalls;
|
||||||
|
@override
|
||||||
|
bool get showComputerPools;
|
||||||
|
@override
|
||||||
|
bool get showSeminarRooms;
|
||||||
|
@override
|
||||||
|
bool get showToilets;
|
||||||
|
@override
|
||||||
|
bool get showStairs;
|
||||||
|
@override
|
||||||
|
bool get showDoors;
|
||||||
|
@override
|
||||||
|
bool get maleToilets;
|
||||||
|
@override
|
||||||
|
bool get femaleToilets;
|
||||||
|
@override
|
||||||
|
bool get handicapToilets;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$SettingsImplCopyWith<_$SettingsImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
41
lib/controllers/shared_prefs_controller.g.dart
Normal file
41
lib/controllers/shared_prefs_controller.g.dart
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'shared_prefs_controller.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$SettingsImpl _$$SettingsImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SettingsImpl(
|
||||||
|
id: json['id'] as int? ?? 1,
|
||||||
|
showIcons: json['showIcons'] as bool? ?? true,
|
||||||
|
showElevators: json['showElevators'] as bool? ?? true,
|
||||||
|
showFoodAndDrink: json['showFoodAndDrink'] as bool? ?? true,
|
||||||
|
showLectureHalls: json['showLectureHalls'] as bool? ?? true,
|
||||||
|
showComputerPools: json['showComputerPools'] as bool? ?? true,
|
||||||
|
showSeminarRooms: json['showSeminarRooms'] as bool? ?? true,
|
||||||
|
showToilets: json['showToilets'] as bool? ?? true,
|
||||||
|
showStairs: json['showStairs'] as bool? ?? true,
|
||||||
|
showDoors: json['showDoors'] as bool? ?? true,
|
||||||
|
maleToilets: json['maleToilets'] as bool? ?? false,
|
||||||
|
femaleToilets: json['femaleToilets'] as bool? ?? false,
|
||||||
|
handicapToilets: json['handicapToilets'] as bool? ?? false,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$SettingsImplToJson(_$SettingsImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'showIcons': instance.showIcons,
|
||||||
|
'showElevators': instance.showElevators,
|
||||||
|
'showFoodAndDrink': instance.showFoodAndDrink,
|
||||||
|
'showLectureHalls': instance.showLectureHalls,
|
||||||
|
'showComputerPools': instance.showComputerPools,
|
||||||
|
'showSeminarRooms': instance.showSeminarRooms,
|
||||||
|
'showToilets': instance.showToilets,
|
||||||
|
'showStairs': instance.showStairs,
|
||||||
|
'showDoors': instance.showDoors,
|
||||||
|
'maleToilets': instance.maleToilets,
|
||||||
|
'femaleToilets': instance.femaleToilets,
|
||||||
|
'handicapToilets': instance.handicapToilets,
|
||||||
|
};
|
@ -99,11 +99,13 @@ class FeatureType with _$FeatureType {
|
|||||||
// multiple feature types like lecture hall, toliet, ...
|
// multiple feature types like lecture hall, toliet, ...
|
||||||
const factory FeatureType.building() = Building;
|
const factory FeatureType.building() = Building;
|
||||||
const factory FeatureType.lectureHall() = LectureHall;
|
const factory FeatureType.lectureHall() = LectureHall;
|
||||||
const factory FeatureType.room() = Room;
|
const factory FeatureType.room(String roomNumber) = Room;
|
||||||
const factory FeatureType.door(List<String> connects) = Door;
|
const factory FeatureType.door(List<String> connects) = Door;
|
||||||
const factory FeatureType.toilet(String toilet_type) = Toilet;
|
const factory FeatureType.toilet(String toilet_type) = Toilet;
|
||||||
const factory FeatureType.stairs(List<int> connects_levels) = Stairs;
|
const factory FeatureType.stairs(List<int> connects_levels) = Stairs;
|
||||||
const factory FeatureType.lift(List<int> connects_levels) = Lift;
|
const factory FeatureType.lift(List<int> connects_levels) = Lift;
|
||||||
|
const factory FeatureType.foodDrink() = FoodDrink;
|
||||||
const factory FeatureType.publicTransport(
|
const factory FeatureType.publicTransport(
|
||||||
List<String> bus_lines, List<String> tram_lines) = PublicTransport;
|
List<String> bus_lines, List<String> tram_lines) = PublicTransport;
|
||||||
|
const factory FeatureType.pcPool(String roomNumber) = PcPool;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,17 +20,20 @@ Result<Feature> parseFeature(
|
|||||||
|
|
||||||
// try parse yaml
|
// try parse yaml
|
||||||
if (description_yaml == null) {
|
if (description_yaml == null) {
|
||||||
print("warn: Description key is missing for feature $name");
|
print(
|
||||||
|
"warn: Description key is missing for feature $name\n\n$geometry\n\n$properties");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == null) {
|
if (layer == null) {
|
||||||
return bail("Layer key \'layer\' is missing for feature $name");
|
return bail(
|
||||||
|
"Layer key \'layer\' is missing for feature $name\n\n$geometry\n\n$properties");
|
||||||
}
|
}
|
||||||
dynamic yaml;
|
dynamic yaml;
|
||||||
try {
|
try {
|
||||||
yaml = loadYaml(description_yaml);
|
yaml = loadYaml(description_yaml);
|
||||||
} on YamlException catch (e) {
|
} on YamlException catch (e) {
|
||||||
return bail("Couldn't parse YAML in description for feature $name: $e");
|
return bail(
|
||||||
|
"Couldn't parse YAML in description for feature $name\n\n$description_yaml\n\nError: $e");
|
||||||
}
|
}
|
||||||
|
|
||||||
yaml = yaml as YamlMap? ?? {};
|
yaml = yaml as YamlMap? ?? {};
|
||||||
@ -70,8 +73,16 @@ Result<Feature> parseFeature(
|
|||||||
case 'lecture_hall':
|
case 'lecture_hall':
|
||||||
type = FeatureType.lectureHall();
|
type = FeatureType.lectureHall();
|
||||||
break;
|
break;
|
||||||
case 'room':
|
case 'seminar_room':
|
||||||
type = FeatureType.room();
|
type = FeatureType.room(getYamlKeyStringify(yaml, 'number')
|
||||||
|
.expect("Couldn't parse 'number' for seminar_room feature $name"));
|
||||||
|
break;
|
||||||
|
case 'pc_pool':
|
||||||
|
type = FeatureType.pcPool(getYamlKeyStringify(yaml, 'number')
|
||||||
|
.expect("Couldn't parse 'number' for PcPool feature $name"));
|
||||||
|
break;
|
||||||
|
case 'food_drink':
|
||||||
|
type = FeatureType.foodDrink();
|
||||||
break;
|
break;
|
||||||
case 'door':
|
case 'door':
|
||||||
final list = getYamlList<String>(yaml, 'connects')
|
final list = getYamlList<String>(yaml, 'connects')
|
||||||
@ -84,10 +95,8 @@ Result<Feature> parseFeature(
|
|||||||
type = FeatureType.toilet(toiletType);
|
type = FeatureType.toilet(toiletType);
|
||||||
break;
|
break;
|
||||||
case 'public_transport':
|
case 'public_transport':
|
||||||
final busLines = getYamlList<dynamic>(yaml, 'bus_lines')
|
final busLines = getYamlList<dynamic>(yaml, 'bus_lines').unwrapOr([]);
|
||||||
.expect("Couldn't parse 'bus_lines' for feature $name");
|
final tramLines = getYamlList<dynamic>(yaml, 'tram_lines').unwrapOr([]);
|
||||||
final tramLines = getYamlList<dynamic>(yaml, 'tram_lines')
|
|
||||||
.expect("Couldn't parse 'tram_lines' for feature $name");
|
|
||||||
|
|
||||||
type = FeatureType.publicTransport(
|
type = FeatureType.publicTransport(
|
||||||
stringifyList(busLines)
|
stringifyList(busLines)
|
||||||
@ -146,3 +155,15 @@ Result<T> getYamlKey<T>(YamlMap yaml, String key) {
|
|||||||
return bail("Failed to parse yaml key $key as ${T.toString()}: $e");
|
return bail("Failed to parse yaml key $key as ${T.toString()}: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<String> getYamlKeyStringify<T>(YamlMap yaml, String key) {
|
||||||
|
try {
|
||||||
|
final val = yaml[key] as T?;
|
||||||
|
if (val == null) {
|
||||||
|
return bail("Key $key is missing in yaml");
|
||||||
|
}
|
||||||
|
return Ok(val.toString());
|
||||||
|
} catch (e) {
|
||||||
|
return bail("Failed to parse yaml key $key as ${T.toString()}: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:uninav/controllers/isar_controller.dart';
|
|
||||||
import 'package:uninav/controllers/map_controller.dart';
|
import 'package:uninav/controllers/map_controller.dart';
|
||||||
|
import 'package:uninav/controllers/shared_prefs_controller.dart';
|
||||||
import 'package:uninav/map.dart';
|
import 'package:uninav/map.dart';
|
||||||
import 'package:uninav/settings.dart';
|
import 'package:uninav/settings.dart';
|
||||||
|
|
||||||
// TODO: maybe make not async?
|
// TODO: maybe make not async?
|
||||||
void main() async {
|
void main() {
|
||||||
Get.put(MyMapController());
|
Get.put(MyMapController());
|
||||||
await Get.find<MyMapController>()
|
rootBundle
|
||||||
.loadGeoJson(await rootBundle.loadString('assets/geo/uulm_beta.geojson'));
|
.loadString('assets/geo/uulm_beta.geojson')
|
||||||
|
.then((value) => Get.find<MyMapController>().loadGeoJson(value));
|
||||||
|
|
||||||
await Get.putAsync(() async {
|
Get.putAsync(() async {
|
||||||
final controller = IsarController();
|
final controller = SharedPrefsController();
|
||||||
await controller.initializeIsar();
|
await controller.initialize();
|
||||||
return controller;
|
return controller;
|
||||||
});
|
});
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
|
175
lib/map.dart
175
lib/map.dart
@ -1,7 +1,9 @@
|
|||||||
import 'package:anim_search_bar/anim_search_bar.dart';
|
import 'package:anim_search_bar/anim_search_bar.dart';
|
||||||
|
import 'package:anyhow/anyhow.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
|
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:rust_core/slice.dart';
|
import 'package:rust_core/slice.dart';
|
||||||
@ -42,8 +44,10 @@ class MapPage extends StatelessWidget {
|
|||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
// Add onPressed logic here
|
// Add onPressed logic here
|
||||||
|
var future = Get.find<MyMapController>().getCurrentPosition();
|
||||||
|
locationBottomSheet();
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.location_searching),
|
||||||
),
|
),
|
||||||
body: Stack(
|
body: Stack(
|
||||||
children: [
|
children: [
|
||||||
@ -105,6 +109,7 @@ class MapPage extends StatelessWidget {
|
|||||||
Get.find<MyMapController>().currentLevel.value,
|
Get.find<MyMapController>().currentLevel.value,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
CurrentLocationLayer(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
@ -176,3 +181,171 @@ class MapPage extends StatelessWidget {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void locationBottomSheet() {
|
||||||
|
print(Get.find<MyMapController>().position.value);
|
||||||
|
String buttonText = "Search for Location";
|
||||||
|
IconData locationIcon = Icons.location_searching;
|
||||||
|
bool spinner = false;
|
||||||
|
Get.bottomSheet(
|
||||||
|
Theme(
|
||||||
|
data: ThemeData.light(),
|
||||||
|
child: Container(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
// minHeight: 300,
|
||||||
|
),
|
||||||
|
width: Get.mediaQuery.size.width,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.black,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(30),
|
||||||
|
topRight: Radius.circular(30),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
width: 50,
|
||||||
|
height: 5,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
const Text(
|
||||||
|
'Select Location',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Container(
|
||||||
|
height: 300,
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: StatefulBuilder(builder: (context, setState) {
|
||||||
|
// TODO: make this persist closing the bottom sheet
|
||||||
|
return ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
fixedSize: const Size(300, 300),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(15),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
if (spinner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
buttonText = "Searching...";
|
||||||
|
locationIcon = Icons.location_searching;
|
||||||
|
spinner = true;
|
||||||
|
});
|
||||||
|
final pos = await Get.find<MyMapController>()
|
||||||
|
.getCurrentPosition();
|
||||||
|
if (!context.mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos case Ok(:final ok)) {
|
||||||
|
setState(() {
|
||||||
|
buttonText = "Location found!";
|
||||||
|
locationIcon = Icons.my_location;
|
||||||
|
spinner = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
buttonText = "Location not found! Try again";
|
||||||
|
locationIcon = Icons.error;
|
||||||
|
spinner = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(locationIcon,
|
||||||
|
size: 80,
|
||||||
|
color: Get.theme.colorScheme.inversePrimary),
|
||||||
|
if (spinner)
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: Get.theme.colorScheme.inversePrimary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
buttonText,
|
||||||
|
softWrap: true,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
/*
|
||||||
|
ListTile(
|
||||||
|
title: const Text(
|
||||||
|
'Current Location',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: const Text(
|
||||||
|
'Search Location',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
*/
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text(
|
||||||
|
'Cancel',
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isScrollControlled: true,
|
||||||
|
enterBottomSheetDuration: const Duration(milliseconds: 150),
|
||||||
|
exitBottomSheetDuration: const Duration(milliseconds: 200),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
647
lib/nav/graph.dart.old
Normal file
647
lib/nav/graph.dart.old
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
import 'package:anyhow/anyhow.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:directed_graph/directed_graph.dart';
|
||||||
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:geojson_vi/geojson_vi.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
import 'package:rust_core/iter.dart';
|
||||||
|
import 'package:uninav/data/geo/model.dart';
|
||||||
|
import 'package:uninav/util/geojson_util.dart';
|
||||||
|
import 'package:uninav/util/util.dart';
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
part 'graph.freezed.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class GraphFeature with _$GraphFeature {
|
||||||
|
const factory GraphFeature.buildingFloor(int floor, Feature building) =
|
||||||
|
BuildingFloor;
|
||||||
|
const factory GraphFeature.portal(int fromFloor, String from, int toFloor,
|
||||||
|
String to, Feature baseFeature) = Portal;
|
||||||
|
const factory GraphFeature.basicFeature(
|
||||||
|
int floor, String building, Feature feature) = BasicFeature;
|
||||||
|
|
||||||
|
const GraphFeature._();
|
||||||
|
|
||||||
|
Result<LatLng> getCenter() {
|
||||||
|
return when(
|
||||||
|
buildingFloor: (floor, building) => building.getCenterPoint(),
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) =>
|
||||||
|
baseFeature.getCenterPoint(),
|
||||||
|
basicFeature: (floor, building, feature) => feature.getCenterPoint(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double distanceTo(GraphFeature other, String unit) => distanceBetweenLatLng(
|
||||||
|
getCenter().unwrap(), other.getCenter().unwrap(), unit);
|
||||||
|
|
||||||
|
double metersTo(GraphFeature other) => distanceTo(other, "meters");
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return when(
|
||||||
|
buildingFloor: (floor, building) => 'Floor (${building.name}:$floor)',
|
||||||
|
portal: (fromFloor, from, toFloor, to, _) =>
|
||||||
|
'Portal ($from:$fromFloor -> $to:$toFloor)',
|
||||||
|
basicFeature: (floor, building, feature) =>
|
||||||
|
'Feature (${formatFeatureTitle(feature)} ($building:$floor))',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return when(
|
||||||
|
buildingFloor: (floor, building) => Object.hash(floor, building),
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) =>
|
||||||
|
Object.hash(fromFloor, from, toFloor, to, baseFeature),
|
||||||
|
basicFeature: (floor, building, feature) =>
|
||||||
|
Object.hash(floor, building, feature),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is GraphFeature &&
|
||||||
|
other.when(
|
||||||
|
buildingFloor: (floor, building) =>
|
||||||
|
this is BuildingFloor &&
|
||||||
|
(this as BuildingFloor).floor == floor &&
|
||||||
|
(this as BuildingFloor).building == building,
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) =>
|
||||||
|
this is Portal &&
|
||||||
|
(this as Portal).fromFloor == fromFloor &&
|
||||||
|
(this as Portal).from == from &&
|
||||||
|
(this as Portal).toFloor == toFloor &&
|
||||||
|
(this as Portal).to == to &&
|
||||||
|
(this as Portal).baseFeature == baseFeature,
|
||||||
|
basicFeature: (floor, building, feature) =>
|
||||||
|
this is BasicFeature &&
|
||||||
|
(this as BasicFeature).floor == floor &&
|
||||||
|
(this as BasicFeature).building == building &&
|
||||||
|
(this as BasicFeature).feature == feature,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Graph {
|
||||||
|
final List<(GraphFeature, double, GraphFeature)> _edges = [];
|
||||||
|
final HashSet<GraphFeature> _nodes = HashSet();
|
||||||
|
final HashSet<(GraphFeature, GraphFeature)> _edgesSet = HashSet();
|
||||||
|
|
||||||
|
Iterable<GraphFeature> get nodes => _nodes.iter();
|
||||||
|
|
||||||
|
void addNode(GraphFeature node) {
|
||||||
|
_nodes.add(node);
|
||||||
|
if (node is BasicFeature && node.feature.name == 'H22') {
|
||||||
|
print(node);
|
||||||
|
print(node.hashCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addEdge(GraphFeature from, GraphFeature to, double weight) {
|
||||||
|
addNode(from);
|
||||||
|
addNode(to);
|
||||||
|
if (!_edgesSet.contains((from, to))) {
|
||||||
|
_edgesSet.add((from, to));
|
||||||
|
_edges.add((from, weight, to));
|
||||||
|
}
|
||||||
|
if (!_edgesSet.contains((to, from))) {
|
||||||
|
_edgesSet.add((to, from));
|
||||||
|
_edges.add((to, weight, from));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<(GraphFeature, double, GraphFeature)> getEdges(GraphFeature node) {
|
||||||
|
return _edges.where((edge) => edge.$1 == node).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(GraphFeature node) {
|
||||||
|
return _nodes.contains(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsEdge(GraphFeature from, GraphFeature to) {
|
||||||
|
return _edgesSet.contains((from, to));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Graph(_edges: $_edges, _nodes: $_nodes, _edgesSet: $_edgesSet)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is Graph &&
|
||||||
|
listEquals(other._edges, _edges) &&
|
||||||
|
setEquals(other._nodes, _nodes) &&
|
||||||
|
setEquals(other._edgesSet, _edgesSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _edges.hashCode ^ _nodes.hashCode ^ _edgesSet.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<GraphFeature> wrap(Feature feature, int floor, String buildingFrom) {
|
||||||
|
return feature.type
|
||||||
|
.maybeWhen(
|
||||||
|
building: () => [GraphFeature.buildingFloor(floor, feature)],
|
||||||
|
stairs: (floors) => stairPortalGenerator(floors, floor, feature),
|
||||||
|
lift: (floors) => stairPortalGenerator(floors, floor, feature, 99),
|
||||||
|
door: (connections) =>
|
||||||
|
doorPortalGenerator(connections, floor, buildingFrom, feature),
|
||||||
|
orElse: () => [
|
||||||
|
GraphFeature.basicFeature(
|
||||||
|
floor, feature.building ?? buildingFrom, feature)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GraphFeature> doorPortalGenerator(
|
||||||
|
List<String> connections, int floor, String from, Feature feature) {
|
||||||
|
final portals = <GraphFeature>[];
|
||||||
|
|
||||||
|
for (final connection in connections.where((c) => !eq(c, from))) {
|
||||||
|
portals.add(GraphFeature.portal(floor, from, floor, connection, feature));
|
||||||
|
}
|
||||||
|
|
||||||
|
return portals;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GraphFeature> stairPortalGenerator(
|
||||||
|
List<int> floors, int floor, Feature feature,
|
||||||
|
[int maxDist = 1]) {
|
||||||
|
final portals = <GraphFeature>[];
|
||||||
|
for (int i = 1; i <= maxDist; i++) {
|
||||||
|
if (floors.contains(floor - i)) {
|
||||||
|
portals.add(GraphFeature.portal(
|
||||||
|
floor, feature.building!, floor - i, feature.building!, feature));
|
||||||
|
}
|
||||||
|
if (floors.contains(floor + i)) {
|
||||||
|
portals.add(GraphFeature.portal(
|
||||||
|
floor, feature.building!, floor + i, feature.building!, feature));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return portals;
|
||||||
|
}
|
||||||
|
|
||||||
|
Feature unwrap(GraphFeature feature) {
|
||||||
|
return feature.when(
|
||||||
|
buildingFloor: (floor, building) => building,
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) => baseFeature,
|
||||||
|
basicFeature: (floor, building, f) => f,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double sum(double left, double right) => left + right;
|
||||||
|
|
||||||
|
// WeightedDirectedGraph createGraph(Feature origin, List<Feature> allFeatures) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
List<GraphFeature> findAdjacent(
|
||||||
|
GraphFeature feature, Iterable<Feature> allFeatures) {
|
||||||
|
List<GraphFeature> adjacentFeatures = [];
|
||||||
|
|
||||||
|
if (feature is BuildingFloor) {
|
||||||
|
// find all features in the building on the right floor
|
||||||
|
adjacentFeatures = allFeatures
|
||||||
|
.where((f) => eq(f.building, feature.building.name) || f.type is Door)
|
||||||
|
.where((f) => f.type.maybeWhen(
|
||||||
|
lift: (levels) => levels.contains(feature.floor),
|
||||||
|
stairs: (levels) => levels.contains(feature.floor),
|
||||||
|
door: (connections) =>
|
||||||
|
f.level == feature.floor &&
|
||||||
|
connections
|
||||||
|
.map((e) => e.toLowerCase())
|
||||||
|
.contains(feature.building.name.toLowerCase()),
|
||||||
|
orElse: () => f.level == feature.floor))
|
||||||
|
.mapMany((f) => wrap(f, feature.floor, feature.building.name))
|
||||||
|
.toList();
|
||||||
|
} else if (feature is Portal) {
|
||||||
|
adjacentFeatures = allFeatures
|
||||||
|
.where((f) => eq(f.name, feature.to) && f.type is Building)
|
||||||
|
.mapMany((f) => wrap(f, feature.toFloor, feature.to))
|
||||||
|
.toList();
|
||||||
|
} else if (feature is BasicFeature) {
|
||||||
|
adjacentFeatures = allFeatures
|
||||||
|
.where(
|
||||||
|
(f) => eq(f.name, feature.feature.building) && f.type is Building)
|
||||||
|
.mapMany((f) => wrap(f, feature.feature.level!, f.name))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return adjacentFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph makeGraph(GraphFeature origin, List<Feature> allFeatures,
|
||||||
|
[Graph? graph]) {
|
||||||
|
// final usedFeatures = <GraphFeature>[origin];
|
||||||
|
|
||||||
|
graph ??= Graph();
|
||||||
|
graph.addNode(origin);
|
||||||
|
|
||||||
|
final adjacent = findAdjacent(origin, allFeatures);
|
||||||
|
for (final feature in adjacent.asSet()..removeAll(graph.nodes)) {
|
||||||
|
graph.addEdge(origin, feature, origin.metersTo(feature));
|
||||||
|
final _ = makeGraph(feature, allFeatures, graph);
|
||||||
|
// graph.addAll(deeper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GraphFeature> createGraphList(
|
||||||
|
GraphFeature origin, List<Feature> allFeatures,
|
||||||
|
[Set<GraphFeature>? visited]) {
|
||||||
|
// final usedFeatures = <GraphFeature>[origin];
|
||||||
|
|
||||||
|
visited ??= <GraphFeature>{origin};
|
||||||
|
|
||||||
|
final adjacent = findAdjacent(origin, allFeatures);
|
||||||
|
for (final feature in adjacent.asSet()..removeAll(visited)) {
|
||||||
|
visited.add(feature);
|
||||||
|
final deeper = createGraphList(feature, allFeatures, visited);
|
||||||
|
visited.addAll(deeper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return visited.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<GraphFeature, Map<GraphFeature, double>> createGraphMap(
|
||||||
|
GraphFeature origin, List<Feature> allFeatures) {
|
||||||
|
final graphList = createGraphList(origin, allFeatures);
|
||||||
|
final graphMap = <GraphFeature, Map<GraphFeature, double>>{};
|
||||||
|
for (final node in graphList) {
|
||||||
|
final adjacents = node.when(
|
||||||
|
buildingFloor: (floor, building) {
|
||||||
|
return graphList
|
||||||
|
.where((f) =>
|
||||||
|
f is Portal &&
|
||||||
|
eq(f.from, building.name) &&
|
||||||
|
f.fromFloor == floor ||
|
||||||
|
f is BasicFeature &&
|
||||||
|
eq(f.building, building.name) &&
|
||||||
|
f.floor == floor)
|
||||||
|
.map((f) => f.when(
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) => (
|
||||||
|
f,
|
||||||
|
f.metersTo(node),
|
||||||
|
),
|
||||||
|
basicFeature: (floor, building, feature) =>
|
||||||
|
(f, f.metersTo(node)),
|
||||||
|
buildingFloor: (floor, building) => throw StateError(
|
||||||
|
"BUG: createGraphMap(): BuildingFloors shouldn't "
|
||||||
|
"be matched by BuildingFloors"),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) {
|
||||||
|
return graphList
|
||||||
|
.where((f) =>
|
||||||
|
f is BuildingFloor &&
|
||||||
|
eq(f.building.name, to) &&
|
||||||
|
f.floor == toFloor)
|
||||||
|
.map((f) => f.when(
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) =>
|
||||||
|
throw StateError(
|
||||||
|
"BUG: createGraphMap(): Portals shouldn't "
|
||||||
|
"be matched by Portals"),
|
||||||
|
basicFeature: (floor, building, feature) => throw StateError(
|
||||||
|
"BUG: createGraphMap(): BasicFeatures shouldn't "
|
||||||
|
"be matched by BasicFeatures"),
|
||||||
|
buildingFloor: (floor, building) => (
|
||||||
|
f,
|
||||||
|
f.metersTo(node) +
|
||||||
|
5 /* 5 extra meters for all portals. TODO: smarter!*/
|
||||||
|
),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
basicFeature: (floor, building, feature) {
|
||||||
|
return graphList
|
||||||
|
.where((f) =>
|
||||||
|
f is BuildingFloor &&
|
||||||
|
eq(f.building.name, building) &&
|
||||||
|
f.floor == floor)
|
||||||
|
.map((f) => f.when(
|
||||||
|
portal: (fromFloor, from, toFloor, to, baseFeature) =>
|
||||||
|
throw StateError(
|
||||||
|
"BUG: createGraphMap(): Portal shouldn't be matched "
|
||||||
|
"by BasicFeature"),
|
||||||
|
basicFeature: (floor, building, feature) => throw StateError(
|
||||||
|
"BUG: createGraphMap(): BasicFeatures shouldn't "
|
||||||
|
"be matched by BasicFeatures"),
|
||||||
|
buildingFloor: (floor, building) => (f, f.metersTo(node)),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
graphMap[node] =
|
||||||
|
Map.fromEntries(adjacents.map((tup) => MapEntry(tup.$1, tup.$2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return graphMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeightedDirectedGraph<GraphFeature, double> createGraph(
|
||||||
|
GraphFeature origin, List<Feature> allFeatures) {
|
||||||
|
final map = createGraphMap(origin, allFeatures);
|
||||||
|
final graph = WeightedDirectedGraph<GraphFeature, double>(
|
||||||
|
map,
|
||||||
|
summation: sum,
|
||||||
|
zero: 0.0,
|
||||||
|
comparator: (a, b) => compareGraphFeatures(a, b),
|
||||||
|
);
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<List<(GraphFeature, double)>> findShortestPathUndir(GraphFeature origin,
|
||||||
|
bool Function(GraphFeature) destinationSelector, List<Feature> allFeatures,
|
||||||
|
{heuristicVariant = "zero", heuristicMultiplier = 0.2}) {
|
||||||
|
Graph graph = makeGraph(origin, allFeatures);
|
||||||
|
|
||||||
|
final GraphFeature? destination =
|
||||||
|
graph.nodes.firstWhereOrNull(destinationSelector);
|
||||||
|
|
||||||
|
if (!(graph.contains(origin) &&
|
||||||
|
destination != null &&
|
||||||
|
graph.contains(destination))) {
|
||||||
|
return bail("Origin or destination not in graph");
|
||||||
|
}
|
||||||
|
|
||||||
|
// euclidean distance heuristic
|
||||||
|
|
||||||
|
double Function(GraphFeature) heuristic =
|
||||||
|
(GraphFeature node) => 0.0; // standard zero
|
||||||
|
if (heuristicVariant == "zero") {
|
||||||
|
heuristic = (GraphFeature node) => 0.0;
|
||||||
|
} else if (heuristicVariant == "euclidean") {
|
||||||
|
heuristic =
|
||||||
|
(GraphFeature node) => node.metersTo(destination) * heuristicMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
//heuristic(GraphFeature node) => 0.0;
|
||||||
|
|
||||||
|
// openlist
|
||||||
|
// format: (heuristic, g-val, parent?, node)
|
||||||
|
PriorityQueue<(double, double, GraphFeature?, GraphFeature)> openlist =
|
||||||
|
HeapPriorityQueue(
|
||||||
|
// reverse order (cmp b to a) because lower f-val (shorter distance) is better
|
||||||
|
(a, b) => (b.$1 + b.$2).compareTo((a.$1 + a.$2)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<GraphFeature, (GraphFeature?, double)> bestPathMap = {
|
||||||
|
origin: (null, 0.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
openlist.add((heuristic(origin), 0.0, null, origin));
|
||||||
|
|
||||||
|
// closed list
|
||||||
|
Set<GraphFeature> closedlist = {};
|
||||||
|
|
||||||
|
var cost = 0.0;
|
||||||
|
|
||||||
|
while (openlist.isNotEmpty) {
|
||||||
|
final (f, g, parent, node) = openlist.removeFirst();
|
||||||
|
closedlist.add(node);
|
||||||
|
bestPathMap[node] = (parent, g);
|
||||||
|
if (node == destination) {
|
||||||
|
cost = g;
|
||||||
|
break;
|
||||||
|
// TODO: restore path
|
||||||
|
}
|
||||||
|
|
||||||
|
// expand node
|
||||||
|
final edges = graph.getEdges(node);
|
||||||
|
for (final entry in edges) {
|
||||||
|
final adjNode = entry.$3;
|
||||||
|
final adjCost = entry.$2;
|
||||||
|
|
||||||
|
if (closedlist.contains(adjNode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (final open in openlist.unorderedElements) {
|
||||||
|
if (open.$4 == adjNode) {
|
||||||
|
found = true;
|
||||||
|
if (g + adjCost < open.$2) {
|
||||||
|
openlist.remove(open);
|
||||||
|
openlist.add((
|
||||||
|
open.$1 /* heuristic stays the same */,
|
||||||
|
g + adjCost,
|
||||||
|
adjNode,
|
||||||
|
open.$4
|
||||||
|
));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
openlist.add((
|
||||||
|
f + heuristic(adjNode),
|
||||||
|
g + adjCost,
|
||||||
|
node,
|
||||||
|
adjNode,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestPathMap.isNotEmpty) {
|
||||||
|
final path = <(GraphFeature, double)>[];
|
||||||
|
(GraphFeature?, double)? currentNode = (destination, cost);
|
||||||
|
while (currentNode?.$1 != null) {
|
||||||
|
final nextNode = bestPathMap[currentNode!.$1];
|
||||||
|
path.insert(
|
||||||
|
0, (currentNode!.$1!, currentNode.$2 - (nextNode?.$2 ?? 0.0)));
|
||||||
|
currentNode = nextNode;
|
||||||
|
}
|
||||||
|
return Ok(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bail("No path found");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<List<(GraphFeature, double)>> findShortestPath(
|
||||||
|
GraphFeature origin, GraphFeature destination, List<Feature> allFeatures,
|
||||||
|
[heuristicVariant = "zero", heuristicMultiplier = 0.2]) {
|
||||||
|
var graph = createGraphMap(origin, allFeatures);
|
||||||
|
|
||||||
|
if (!(graph.keys.contains(origin) &&
|
||||||
|
graph.values.firstWhereOrNull((vals) => vals.containsKey(destination)) !=
|
||||||
|
null)) {
|
||||||
|
return bail("Origin or destination not in graph");
|
||||||
|
}
|
||||||
|
|
||||||
|
// euclidean distance heuristic
|
||||||
|
|
||||||
|
double Function(GraphFeature) heuristic =
|
||||||
|
(GraphFeature node) => 0.0; // standard zero
|
||||||
|
if (heuristicVariant == "zero") {
|
||||||
|
heuristic = (GraphFeature node) => 0.0;
|
||||||
|
} else if (heuristicVariant == "euclidean") {
|
||||||
|
heuristic =
|
||||||
|
(GraphFeature node) => node.metersTo(destination) * heuristicMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
//heuristic(GraphFeature node) => 0.0;
|
||||||
|
|
||||||
|
// openlist
|
||||||
|
// format: (heuristic, g-val, parent?, node)
|
||||||
|
PriorityQueue<(double, double, GraphFeature?, GraphFeature)> openlist =
|
||||||
|
HeapPriorityQueue(
|
||||||
|
// reverse order (cmp b to a) because lower f-val (shorter distance) is better
|
||||||
|
(a, b) => (b.$1 + b.$2).compareTo((a.$1 + a.$2)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<GraphFeature, (GraphFeature?, double)> bestPathMap = {
|
||||||
|
origin: (null, 0.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
openlist.add((heuristic(origin), 0.0, null, origin));
|
||||||
|
|
||||||
|
// closed list
|
||||||
|
Set<GraphFeature> closedlist = {};
|
||||||
|
|
||||||
|
var cost = 0.0;
|
||||||
|
|
||||||
|
while (openlist.isNotEmpty) {
|
||||||
|
final (f, g, parent, node) = openlist.removeFirst();
|
||||||
|
closedlist.add(node);
|
||||||
|
bestPathMap[node] = (parent, g);
|
||||||
|
if (node == destination) {
|
||||||
|
cost = g;
|
||||||
|
break;
|
||||||
|
// TODO: restore path
|
||||||
|
}
|
||||||
|
|
||||||
|
// expand node
|
||||||
|
final adjacents = graph[node]!;
|
||||||
|
for (final entry in adjacents.entries) {
|
||||||
|
final adjNode = entry.key;
|
||||||
|
final adjCost = entry.value;
|
||||||
|
|
||||||
|
if (closedlist.contains(adjNode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (final open in openlist.unorderedElements) {
|
||||||
|
if (open.$4 == adjNode) {
|
||||||
|
found = true;
|
||||||
|
if (g + adjCost < open.$2) {
|
||||||
|
openlist.remove(open);
|
||||||
|
openlist.add((
|
||||||
|
open.$1 /* heuristic stays the same */,
|
||||||
|
g + adjCost,
|
||||||
|
adjNode,
|
||||||
|
open.$4
|
||||||
|
));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
openlist.add((
|
||||||
|
f + heuristic(adjNode),
|
||||||
|
g + adjCost,
|
||||||
|
node,
|
||||||
|
adjNode,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestPathMap.isNotEmpty) {
|
||||||
|
final path = <(GraphFeature, double)>[];
|
||||||
|
(GraphFeature?, double)? currentNode = (destination, cost);
|
||||||
|
while (currentNode?.$1 != null) {
|
||||||
|
final nextNode = bestPathMap[currentNode!.$1];
|
||||||
|
path.insert(
|
||||||
|
0, (currentNode!.$1!, currentNode.$2 - (nextNode?.$2 ?? 0.0)));
|
||||||
|
currentNode = nextNode;
|
||||||
|
}
|
||||||
|
return Ok(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bail("No path found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compares two [GraphFeature] instances and determines their relative order.
|
||||||
|
///
|
||||||
|
/// The comparison is based on the specific subtypes and properties of the
|
||||||
|
/// [GraphFeature] instances. The comparison logic is as follows:
|
||||||
|
///
|
||||||
|
/// 1. If both instances are [BuildingFloor], they are compared first by the
|
||||||
|
/// building name and then by the floor number.
|
||||||
|
/// 2. If one instance is a [Portal] and the other is a [BuildingFloor] or
|
||||||
|
/// [BasicFeature], the [Portal] is considered greater.
|
||||||
|
/// 3. If both instances are [Portal], they are compared first by the `from`
|
||||||
|
/// property, then by the `to` property, and finally by the `baseFeature` name.
|
||||||
|
/// 4. If one instance is a [BasicFeature] and the other is a [BuildingFloor] or
|
||||||
|
/// [Portal], the [BasicFeature] is considered greater.
|
||||||
|
/// 5. If both instances are [BasicFeature], they are compared first by the
|
||||||
|
/// building name, then by the floor number, and finally by the feature name.
|
||||||
|
///
|
||||||
|
/// Returns a negative value if [a] is considered "less than" [b], a positive
|
||||||
|
/// value if [a] is considered "greater than" [b], and zero if they are considered
|
||||||
|
/// equal.
|
||||||
|
///
|
||||||
|
/// This function can be used as a comparator for sorting or ordering
|
||||||
|
/// [GraphFeature] instances.
|
||||||
|
int compareGraphFeatures(GraphFeature a, GraphFeature b) {
|
||||||
|
return a.when(
|
||||||
|
buildingFloor: (floorA, buildingA) {
|
||||||
|
return b.when(
|
||||||
|
buildingFloor: (floorB, buildingB) {
|
||||||
|
final buildingComparison = buildingA.name.compareTo(buildingB.name);
|
||||||
|
if (buildingComparison != 0) {
|
||||||
|
return buildingComparison;
|
||||||
|
}
|
||||||
|
return floorA.compareTo(floorB);
|
||||||
|
},
|
||||||
|
portal: (fromFloorB, fromB, toFloorB, toB, baseFeatureB) => -1,
|
||||||
|
basicFeature: (floorB, buildingB, featureB) => -1,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
portal: (fromFloorA, fromA, toFloorA, toA, baseFeatureA) {
|
||||||
|
return b.when(
|
||||||
|
buildingFloor: (floorB, buildingB) => 1,
|
||||||
|
portal: (fromFloorB, fromB, toFloorB, toB, baseFeatureB) {
|
||||||
|
final fromComparison = fromA.compareTo(fromB);
|
||||||
|
if (fromComparison != 0) {
|
||||||
|
return fromComparison;
|
||||||
|
}
|
||||||
|
final toComparison = toA.compareTo(toB);
|
||||||
|
if (toComparison != 0) {
|
||||||
|
return toComparison;
|
||||||
|
}
|
||||||
|
return baseFeatureA.name.compareTo(baseFeatureB.name);
|
||||||
|
},
|
||||||
|
basicFeature: (floorB, buildingB, featureB) => -1,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
basicFeature: (floorA, buildingA, featureA) {
|
||||||
|
return b.when(
|
||||||
|
buildingFloor: (floorB, buildingB) => 1,
|
||||||
|
portal: (fromFloorB, fromB, toFloorB, toB, baseFeatureB) => 1,
|
||||||
|
basicFeature: (floorB, buildingB, featureB) {
|
||||||
|
final buildingComparison = buildingA.compareTo(buildingB);
|
||||||
|
if (buildingComparison != 0) {
|
||||||
|
return buildingComparison;
|
||||||
|
}
|
||||||
|
final floorComparison = floorA.compareTo(floorB);
|
||||||
|
if (floorComparison != 0) {
|
||||||
|
return floorComparison;
|
||||||
|
}
|
||||||
|
return featureA.name.compareTo(featureB.name);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -2,15 +2,15 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:uninav/components/drawer.dart';
|
import 'package:uninav/components/drawer.dart';
|
||||||
import 'package:uninav/components/hamburger_menu.dart';
|
import 'package:uninav/components/hamburger_menu.dart';
|
||||||
import 'package:uninav/controllers/isar_controller.dart';
|
import 'package:uninav/controllers/shared_prefs_controller.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
const SettingsPage({super.key});
|
const SettingsPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isarController = Get.find<IsarController>();
|
final persistenceController = Get.find<SharedPrefsController>();
|
||||||
final settings = isarController.settings;
|
final settings = persistenceController.settings;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@ -32,90 +32,90 @@ class SettingsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
value: settings.value.showIcons,
|
value: settings.value.showIcons,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showIcons = value;
|
showIcons: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Elevators'),
|
title: const Text('Show Elevators'),
|
||||||
value: settings.value.showElevators,
|
value: settings.value.showElevators,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showElevators = value;
|
showElevators: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Food and Drink'),
|
title: const Text('Show Food and Drink'),
|
||||||
value: settings.value.showFoodAndDrink,
|
value: settings.value.showFoodAndDrink,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showFoodAndDrink = value;
|
showFoodAndDrink: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Lecture Halls'),
|
title: const Text('Show Lecture Halls'),
|
||||||
value: settings.value.showLectureHalls,
|
value: settings.value.showLectureHalls,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showLectureHalls = value;
|
showLectureHalls: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Computer Pools'),
|
title: const Text('Show Computer Pools'),
|
||||||
value: settings.value.showComputerPools,
|
value: settings.value.showComputerPools,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showComputerPools = value;
|
showComputerPools: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Seminar Rooms'),
|
title: const Text('Show Seminar Rooms'),
|
||||||
value: settings.value.showSeminarRooms,
|
value: settings.value.showSeminarRooms,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showSeminarRooms = value;
|
showSeminarRooms: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Toilets'),
|
title: const Text('Show Toilets'),
|
||||||
value: settings.value.showToilets,
|
value: settings.value.showToilets,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showToilets = value;
|
showToilets: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Stairs'),
|
title: const Text('Show Stairs'),
|
||||||
value: settings.value.showStairs,
|
value: settings.value.showStairs,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showStairs = value;
|
showStairs: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('Show Doors'),
|
title: const Text('Show Doors'),
|
||||||
value: settings.value.showDoors,
|
value: settings.value.showDoors,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.showDoors = value;
|
showDoors: value,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
@ -127,37 +127,37 @@ class SettingsPage extends StatelessWidget {
|
|||||||
title: const Text('Male Toilets'),
|
title: const Text('Male Toilets'),
|
||||||
value: settings.value.maleToilets,
|
value: settings.value.maleToilets,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.maleToilets = value ?? false;
|
maleToilets: value ?? false,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
title: const Text('Female Toilets'),
|
title: const Text('Female Toilets'),
|
||||||
value: settings.value.femaleToilets,
|
value: settings.value.femaleToilets,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.femaleToilets = value ?? false;
|
femaleToilets: value ?? false,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
title: const Text('Handicap Toilets'),
|
title: const Text('Handicap Toilets'),
|
||||||
value: settings.value.handicapToilets,
|
value: settings.value.handicapToilets,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
settings.update((val) {
|
settings.value = settings.value.copyWith(
|
||||||
val?.handicapToilets = value ?? false;
|
handicapToilets: value ?? false,
|
||||||
});
|
);
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
settings.value = Settings();
|
settings.value = const Settings();
|
||||||
isarController.persistSettings();
|
persistenceController.persistSettings();
|
||||||
},
|
},
|
||||||
child: const Text("Reset Settings"),
|
child: const Text("Reset Settings"),
|
||||||
),
|
),
|
||||||
|
48
lib/util/geolocator.dart
Normal file
48
lib/util/geolocator.dart
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import 'package:anyhow/anyhow.dart';
|
||||||
|
import 'package:geolocator/geolocator.dart';
|
||||||
|
|
||||||
|
/// Determine the current position of the device.
|
||||||
|
///
|
||||||
|
/// When the location services are not enabled or permissions
|
||||||
|
/// are denied the `Future` will return an error.
|
||||||
|
|
||||||
|
Future<Result<()>> ensureLocationPermission() async {
|
||||||
|
try {
|
||||||
|
bool serviceEnabled;
|
||||||
|
LocationPermission permission;
|
||||||
|
|
||||||
|
// Test if location services are enabled.
|
||||||
|
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
|
if (!serviceEnabled) {
|
||||||
|
// Location services are not enabled don't continue
|
||||||
|
// accessing the position and request users of the
|
||||||
|
// App to enable the location services.
|
||||||
|
return bail('Location services are disabled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
permission = await Geolocator.checkPermission();
|
||||||
|
if (permission == LocationPermission.denied) {
|
||||||
|
permission = await Geolocator.requestPermission();
|
||||||
|
if (permission == LocationPermission.denied) {
|
||||||
|
// Permissions are denied, next time you could try
|
||||||
|
// requesting permissions again (this is also where
|
||||||
|
// Android's shouldShowRequestPermissionRationale
|
||||||
|
// returned true. According to Android guidelines
|
||||||
|
// your App should show an explanatory UI now.
|
||||||
|
return bail('Location permissions are denied');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission == LocationPermission.deniedForever) {
|
||||||
|
// Permissions are denied forever, handle appropriately.
|
||||||
|
return bail(
|
||||||
|
'Location permissions are permanently denied, we cannot request permissions.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// When we reach here, permissions are granted and we can
|
||||||
|
// continue accessing the position of the device.
|
||||||
|
return const Ok(());
|
||||||
|
} catch (e) {
|
||||||
|
return bail("Ensuring Location Permission failed: $e");
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,9 @@ String formatFeatureTitle(Feature feature) {
|
|||||||
return feature.type.when(
|
return feature.type.when(
|
||||||
building: () => '${feature.name} (Building)',
|
building: () => '${feature.name} (Building)',
|
||||||
lectureHall: () => '${feature.name} (Lecture Hall)',
|
lectureHall: () => '${feature.name} (Lecture Hall)',
|
||||||
room: () => 'Room ${feature.name}',
|
room: (number) => 'Room ${feature.building ?? "??"}/$number',
|
||||||
|
pcPool: (number) => 'PC Pool ${feature.name}',
|
||||||
|
foodDrink: () => '${feature.name} (Food/Drink)',
|
||||||
door: (_) => 'Door',
|
door: (_) => 'Door',
|
||||||
toilet: (type) => 'Toilet (${formatToiletType(feature.type as Toilet)})',
|
toilet: (type) => 'Toilet (${formatToiletType(feature.type as Toilet)})',
|
||||||
stairs: (_) => 'Stairs',
|
stairs: (_) => 'Stairs',
|
||||||
|
@ -5,12 +5,16 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import geolocator_apple
|
||||||
import isar_flutter_libs
|
import isar_flutter_libs
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
|
import shared_preferences_foundation
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
||||||
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))
|
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
}
|
}
|
||||||
|
152
pubspec.lock
152
pubspec.lock
@ -193,14 +193,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.3.2"
|
||||||
dartx:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dartx
|
|
||||||
sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
directed_graph:
|
directed_graph:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -262,6 +254,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_compass:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_compass
|
||||||
|
sha256: be642484f9f6975c1c6edff568281b001f2f1e604de27ecea18d97eebbdef22f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -278,6 +278,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "6.1.0"
|
||||||
|
flutter_map_location_marker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_map_location_marker
|
||||||
|
sha256: "5873a47606b092bf181b6d17dd42a124e9a8d5d9caad58b5f98fc182e799994f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "8.0.8"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -320,6 +328,54 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.3"
|
version: "2.2.3"
|
||||||
|
geolocator:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: geolocator
|
||||||
|
sha256: "694ec58afe97787b5b72b8a0ab78c1a9244811c3c10e72c4362ef3c0ceb005cd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.0.0"
|
||||||
|
geolocator_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geolocator_android
|
||||||
|
sha256: f15d1536cd01b1399578f1da1eb5d566e7a718db6a3648f2c24d2e2f859f0692
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.5.4"
|
||||||
|
geolocator_apple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geolocator_apple
|
||||||
|
sha256: bc2aca02423ad429cb0556121f56e60360a2b7d694c8570301d06ea0c00732fd
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.7"
|
||||||
|
geolocator_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geolocator_platform_interface
|
||||||
|
sha256: "009a21c4bc2761e58dccf07c24f219adaebe0ff707abdfd40b0a763d4003fab9"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.2"
|
||||||
|
geolocator_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geolocator_web
|
||||||
|
sha256: "49d8f846ebeb5e2b6641fe477a7e97e5dd73f03cbfef3fd5c42177b7300fb0ed"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
|
geolocator_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geolocator_windows
|
||||||
|
sha256: "53da08937d07c24b0d9952eb57a3b474e29aae2abf9dd717f7e1230995f13f0e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.3"
|
||||||
get:
|
get:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -400,14 +456,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0+1"
|
version: "3.1.0+1"
|
||||||
isar_generator:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: isar_generator
|
|
||||||
sha256: "76c121e1295a30423604f2f819bc255bc79f852f3bc8743a24017df6068ad133"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.0+1"
|
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -680,6 +728,62 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.3"
|
version: "0.5.3"
|
||||||
|
shared_preferences:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shared_preferences
|
||||||
|
sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.3"
|
||||||
|
shared_preferences_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_android
|
||||||
|
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.2"
|
||||||
|
shared_preferences_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_foundation
|
||||||
|
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.5"
|
||||||
|
shared_preferences_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_linux
|
||||||
|
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.2"
|
||||||
|
shared_preferences_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_platform_interface
|
||||||
|
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.2"
|
||||||
|
shared_preferences_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_web
|
||||||
|
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
|
shared_preferences_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_windows
|
||||||
|
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.2"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -789,14 +893,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.6.1"
|
||||||
time:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: time
|
|
||||||
sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.4"
|
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -957,14 +1053,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
xxh3:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: xxh3
|
|
||||||
sha256: a92b30944a9aeb4e3d4f3c3d4ddb3c7816ca73475cd603682c4f8149690f56d7
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
yaml:
|
yaml:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -51,12 +51,15 @@ dependencies:
|
|||||||
json_annotation: ^4.8.1
|
json_annotation: ^4.8.1
|
||||||
rust_core: ^0.5.3
|
rust_core: ^0.5.3
|
||||||
anyhow: ^1.3.0
|
anyhow: ^1.3.0
|
||||||
isar: ^3.1.0+1
|
# isar: ^3.1.0+1
|
||||||
isar_flutter_libs: ^3.1.0+1
|
# isar_flutter_libs: ^3.1.0+1
|
||||||
path_provider: ^2.1.3
|
path_provider: ^2.1.3
|
||||||
directed_graph: ^0.4.3
|
directed_graph: ^0.4.3
|
||||||
fast_immutable_collections: ^10.2.2
|
fast_immutable_collections: ^10.2.2
|
||||||
collection: ^1.18.0
|
collection: ^1.18.0
|
||||||
|
flutter_map_location_marker: ^8.0.8
|
||||||
|
geolocator: ^11.0.0
|
||||||
|
shared_preferences: ^2.2.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -71,7 +74,7 @@ dev_dependencies:
|
|||||||
build_runner: ^2.4.9
|
build_runner: ^2.4.9
|
||||||
freezed: ^2.5.2
|
freezed: ^2.5.2
|
||||||
json_serializable: ^6.7.1
|
json_serializable: ^6.7.1
|
||||||
isar_generator: ^3.1.0+1
|
# isar_generator: ^3.1.0+1
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <geolocator_windows/geolocator_windows.h>
|
||||||
#include <isar_flutter_libs/isar_flutter_libs_plugin.h>
|
#include <isar_flutter_libs/isar_flutter_libs_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
GeolocatorWindowsRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
||||||
IsarFlutterLibsPluginRegisterWithRegistrar(
|
IsarFlutterLibsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin"));
|
registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
geolocator_windows
|
||||||
isar_flutter_libs
|
isar_flutter_libs
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user