initial commit

This commit is contained in:
Oliwier Adamczyk
2025-10-05 10:07:06 +02:00
commit 4804732340
150 changed files with 5563 additions and 0 deletions

41
lib/ui/screen/home.dart Normal file
View File

@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:survive_app/ui/style/dimensions.dart';
import 'package:survive_app/ui/viewmodel/drag_sheet_viewmodel.dart';
import 'package:survive_app/ui/viewmodel/home_viewmodel.dart';
import 'package:survive_app/ui/widget/nav_drawer.dart';
import 'package:survive_app/ui/widget/drag_sheet.dart';
class HomeScreen extends StatelessWidget {
final HomeViewmodel vm;
const HomeScreen({super.key, required this.vm});
@override
Widget build(BuildContext context) {
return Scaffold(
key: vm.scaffoldKey,
backgroundColor: Colors.grey,
drawer: NavDrawer(),
body: Stack(
children: [
FlutterMap(
children: [
TileLayer(
urlTemplate:
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: const ['a', 'b', 'c'],
),
],
),
IconButton(
onPressed: () => vm.openDrawer(),
color: Colors.white,
padding: EdgeInsets.all(Margins.small),
icon: Icon(Icons.menu, color: Colors.black),
),
DragSheet(vm: DragSheetViewmodel()),
],
),
);
}
}

22
lib/ui/screen/router.dart Normal file
View File

@@ -0,0 +1,22 @@
import 'package:go_router/go_router.dart';
import 'package:survive_app/data/wikipedia/repository.dart';
import 'package:survive_app/ui/screen/home.dart';
import 'package:survive_app/ui/screen/wikipedia.dart';
import 'package:survive_app/ui/viewmodel/home_viewmodel.dart';
import 'package:survive_app/ui/viewmodel/wikipedia_viewmodel.dart';
final GoRouter router = GoRouter(
initialLocation: "/",
routes: [
GoRoute(
path: "/",
builder: (context, state) => HomeScreen(vm: HomeViewmodel()),
),
GoRoute(
path: "/wikipedia",
builder: (context, state) => WikipediaScreen(
vm: WikipediaViewmodel(wikipediaRepo: WikipediaRepository()),
),
),
],
);

View File

@@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:survive_app/ui/style/colors.dart';
import 'package:survive_app/ui/style/dimensions.dart';
import 'package:survive_app/ui/viewmodel/wikipedia_viewmodel.dart';
import 'package:survive_app/ui/widget/status_bar_spacer.dart';
class WikipediaScreen extends StatelessWidget {
final WikipediaViewmodel vm;
const WikipediaScreen({super.key, required this.vm});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(Margins.small),
child: Column(
spacing: Margins.small,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StatusBarSpacer(),
IconButton(
onPressed: () => vm.returnClick(context),
icon: Icon(Icons.arrow_back_outlined),
),
Text(
"Wikipedia",
style: TextStyle(
color: Colors.black,
fontSize: TextSizes.large,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
Expanded(
child: TextField(
cursorColor: ColorPalette.primary,
decoration: InputDecoration(
suffixIcon: Container(
decoration: BoxDecoration(
color: ColorPalette.secondary,
borderRadius: BorderRadius.all(
Radius.circular(100),
),
),
child: IconButton(
onPressed: () {},
color: Colors.black,
icon: Icon(Icons.download, size: 18),
),
),
hintText: "Podaj tytul artykulu...",
filled: true,
fillColor: ColorPalette.secondary,
focusColor: Colors.transparent,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(15)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(15)),
),
),
controller: vm.controller,
),
),
],
),
ValueListenableBuilder(
valueListenable: vm.articles,
builder: (context, value, child) {
return Column(
children: value.map((a) => Text(a.title)).toList(),
);
},
),
],
),
),
),
);
}
}

8
lib/ui/style/colors.dart Normal file
View File

@@ -0,0 +1,8 @@
import 'dart:ui';
class ColorPalette {
ColorPalette._();
static final Color primary = Color.fromARGB(255, 235, 35, 22);
static final Color secondary = Color.fromARGB(55, 125, 125, 125);
}

View File

@@ -0,0 +1,14 @@
class Margins {
Margins._();
static double extraSmall = 4;
static double small = 8;
static double medium = 16;
}
class TextSizes {
TextSizes._();
static double small = 14;
static double medium = 18;
static double large = 24;
}

View File

@@ -0,0 +1,6 @@
import 'package:flutter/material.dart';
class DragSheetViewmodel {
final controller = DraggableScrollableController();
final waypointInputController = TextEditingController();
}

View File

@@ -0,0 +1,7 @@
import 'package:flutter/material.dart';
class HomeViewmodel {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
void openDrawer() => scaffoldKey.currentState?.openDrawer();
}

View File

@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:survive_app/data/wikipedia/model.dart';
import 'package:survive_app/data/wikipedia/repository.dart';
class WikipediaViewmodel {
final IWikipediaRepository wikipediaRepo;
WikipediaViewmodel({required this.wikipediaRepo});
final TextEditingController controller = TextEditingController();
final ValueNotifier<List<WikiArticleModel>> articles = ValueNotifier([]);
void downloadArticles() async => await wikipediaRepo.downloadArticles();
void returnClick(BuildContext context) => context.pop();
Future<void> searchArticles() async {
final articleQueryData = WikiArticleQueryModel(title: controller.text);
articles.value = await wikipediaRepo.queryArticles(articleQueryData);
}
}

View File

@@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:survive_app/ui/style/colors.dart';
import 'package:survive_app/ui/style/dimensions.dart';
import 'package:survive_app/ui/viewmodel/drag_sheet_viewmodel.dart';
class DragSheet extends StatelessWidget {
final DragSheetViewmodel vm;
const DragSheet({super.key, required this.vm});
@override
Widget build(BuildContext context) {
return DraggableScrollableSheet(
controller: vm.controller,
initialChildSize: 0.45,
minChildSize: 0.3,
maxChildSize: 0.75,
snap: true,
snapSizes: const [0.60],
builder: (context, scrollController) {
return Container(
width: double.infinity,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
boxShadow: [
BoxShadow(color: Color.fromARGB(100, 20, 20, 20), blurRadius: 10),
],
),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(Margins.medium),
child: Column(
children: [
TextField(
cursorColor: ColorPalette.primary,
decoration: InputDecoration(
suffixIcon: Container(
decoration: BoxDecoration(
color: ColorPalette.secondary,
borderRadius: BorderRadius.all(Radius.circular(100)),
),
child: IconButton(
onPressed: () {},
color: ColorPalette.primary,
icon: Icon(Icons.download, size: 18),
),
),
hintText: "Podaj nazwe punktu orientacyjnego...",
filled: true,
fillColor: ColorPalette.secondary,
focusColor: Colors.transparent,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(15)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(15)),
),
),
controller: vm.waypointInputController,
),
],
),
),
),
);
},
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:survive_app/ui/style/dimensions.dart';
import 'package:survive_app/ui/widget/status_bar_spacer.dart';
class NavDrawer extends StatelessWidget {
const NavDrawer({super.key});
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.all(Margins.medium),
children: [
StatusBarSpacer(),
NavDrawerElement(
route: "/wikipedia",
icon: Icons.article_outlined,
caption: "Wikipedia",
),
NavDrawerElement(
route: "/resources",
icon: Icons.fastfood_outlined,
caption: "Zasoby",
),
NavDrawerElement(
route: "/guides",
icon: Icons.bookmarks_outlined,
caption: "Poradniki",
),
],
),
);
}
}
class NavDrawerElement extends StatelessWidget {
final String route;
final IconData icon;
final String caption;
const NavDrawerElement({
super.key,
required this.route,
required this.icon,
required this.caption,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => context.push(route),
child: SizedBox(
child: Row(
children: [
Icon(icon),
Text(caption, style: TextStyle(fontSize: TextSizes.medium)),
],
),
),
);
}
}

View File

@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class StatusBarSpacer extends StatelessWidget {
const StatusBarSpacer({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(height: MediaQuery.of(context).padding.top);
}
}