Skip to content

Commit

Permalink
feat: stories displaying
Browse files Browse the repository at this point in the history
  • Loading branch information
IamMuuo committed Sep 29, 2024
1 parent f94db5f commit f5568e3
Show file tree
Hide file tree
Showing 19 changed files with 1,310 additions and 168 deletions.
11 changes: 6 additions & 5 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@ class Academia extends StatelessWidget {
Get.put(RewardController());
Get.put(CoursesController());
Get.put(EventsController());
Get.put(OrganizationController());

LocalNotifierService().requestPermission();
return GetMaterialApp(
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.amber,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
useMaterial3: true,
colorSchemeSeed: Colors.amber,
),
// darkTheme: ThemeData(
// brightness: Brightness.dark,
// useMaterial3: true,
// colorSchemeSeed: Colors.amber,
// ),
home: Obx(
() => userController.isLoggedIn.value
? const LayoutPage()
Expand Down
2 changes: 1 addition & 1 deletion lib/models/core/settings/settings_model.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class _$SettingsImpl implements _Settings {
this.showAudit = false,
this.showExamTimetable = false,
this.passcode = "",
this.primaryColor = "#FFFFFF"});
this.primaryColor = "##72D5E0"});

factory _$SettingsImpl.fromJson(Map<String, dynamic> json) =>
_$$SettingsImplFromJson(json);
Expand Down
2 changes: 1 addition & 1 deletion lib/models/core/settings/settings_model.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 0 additions & 28 deletions lib/storage/schemas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,34 +68,6 @@ const schemas = <String, String>{
awarded_at TEXT NOT NULL
);
""",

// Organizations
"organizations": """
CREATE TABLE IF NOT EXISTS organizations (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
phone TEXT,
email TEXT,
description TEXT,
profile TEXT,
date_added TEXT
);
""",

// Stories
"stories": """
CREATE TABLE IF NOT EXISTS stories (
id TEXT PRIMARY KEY,
organization TEXT NOT NULL,
hex_code TEXT,
text TEXT,
media TEXT,
viewed INTEGER,
date_added TEXT,
date_of_expiry TEXT
);
""",

// todos
"todos": """
CREATE TABLE IF NOT EXISTS todos (
Expand Down
42 changes: 14 additions & 28 deletions lib/tools/chirp/pages/chirp_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,40 +44,26 @@ class ChirpHomePage extends StatelessWidget {
icon: const Icon(Ionicons.flame_outline),
),
],
expandedHeight: 300,
flexibleSpace: FlexibleSpaceBar(
background: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/images/sketchbook-passersby-people-working-around-1.png",
),
),
),
),
),
expandedHeight: 200,
pinned: true,
floating: true,
snap: true,
bottom: const TabBar(
tabs: [
Tab(text: 'Trending'),
Tab(text: "Your Posts"),
Tab(text: "Organizations"),
],
),
),
SliverVisibility(
visible: false,
sliver: SliverPersistentHeader(
floating: true,
delegate:
PersistentStorySliverDelegate(child: const SizedBox()),
),
bottom: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 140),
child: const Column(
children: [
StoryHeader(),
TabBar(tabs: [
Tab(text: 'Trending'),
Tab(text: "Your Posts"),
Tab(text: "Organizations"),
]),
],
)),
),
const SliverFillRemaining(
hasScrollBody: true,
fillOverscroll: true,
fillOverscroll: false,
child: TabBarView(
children: [
FeedPage(),
Expand Down
108 changes: 108 additions & 0 deletions lib/tools/chirp/pages/story_view_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import 'package:academia/exports/barrel.dart';
import 'package:story_view/story_view.dart';

class StoryViewPage extends StatefulWidget {
const StoryViewPage({
super.key,
required this.organization,
required this.stories,
});

final Organization organization;
final List<Story> stories;

@override
State<StoryViewPage> createState() => _StoryViewPageState();
}

class _StoryViewPageState extends State<StoryViewPage> {
final StoryController _storyController = StoryController();

List<StoryItem> buildStoryItems(List<Story> stories) {
List<StoryItem> storyItems = [];
for (final story in stories) {
switch (story.fileType) {
case "image":
storyItems.add(
StoryItem.pageImage(
url: "${ChirpService.urlPrefix}${story.media}",
controller: _storyController,
caption: Text(
story.description,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
),
loadingWidget: const CircularProgressIndicator.adaptive(),
),
);

break;
case "video":
storyItems.add(
StoryItem.pageVideo(
"${ChirpService.urlPrefix}${story.media}",
controller: _storyController,
caption: Text(
story.description,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
),
loadingWidget: const CircularProgressIndicator.adaptive(),
),
);
break;

case "text":
storyItems.add(
StoryItem.text(
title: story.description,
backgroundColor:
Theme.of(context).colorScheme.tertiaryContainer),
);
break;

default:
}
}

return storyItems;
}

@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Row(
children: [
CircleAvatar(
backgroundImage: CachedNetworkImageProvider(
widget.organization.logo!,
),
),
const SizedBox(width: 8),
Text(
widget.organization.name,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
),
],
),
),
body: StoryView(
repeat: false,
onComplete: () {
Navigator.pop(context);
},
indicatorColor: Theme.of(context).colorScheme.secondaryContainer,
indicatorForegroundColor: Theme.of(context).primaryColor,
storyItems: buildStoryItems(widget.stories),
controller: _storyController,
),
);
}
}
111 changes: 79 additions & 32 deletions lib/tools/chirp/widgets/story_header.dart
Original file line number Diff line number Diff line change
@@ -1,40 +1,87 @@
import 'package:academia/exports/barrel.dart';
import 'package:flutter/material.dart';
import 'package:academia/tools/chirp/pages/story_view_page.dart';
import 'package:get/get.dart';

class PersistentStorySliverDelegate extends SliverPersistentHeaderDelegate {
PersistentStorySliverDelegate({
required this.child,
this.numberofStories = 5,
});
final Widget child;
int numberofStories;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.symmetric(horizontal: 4),
child: ListView.separated(
itemBuilder: (context, index) {
return const CircleAvatar(
radius: 45,
);
},
itemCount: numberofStories,
separatorBuilder: (context, index) => const SizedBox(width: 4),
scrollDirection: Axis.horizontal,
),
);
}
class StoryHeader extends StatelessWidget {
const StoryHeader({super.key});

@override
double get maxExtent => 120.0; // Height of the header
Widget build(BuildContext context) {
final OrganizationController organizationController =
Get.find<OrganizationController>();
final UserController userController = Get.find<UserController>();

@override
double get minExtent => 100.0; // Height of the header when scrolled
return SizedBox(
height: 100,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: FutureBuilder(
future:
organizationController.fetchStories(userController.authHeaders),
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => const CircleAvatar(radius: 35),
);
}

@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return oldDelegate != this;
return Obx(
() => ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: organizationController.stories.keys.length,
separatorBuilder: (context, index) => const SizedBox(width: 4),
itemBuilder: (context, index) {
final data =
organizationController.stories.keys.elementAt(index);
return Visibility(
visible: organizationController.stories.values
.elementAt(index)
.isNotEmpty,
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StoryViewPage(
organization: data,
stories: organizationController.stories.values
.elementAt(index),
),
),
);
},
child: Column(
children: [
Badge(
backgroundColor: Colors.blue,
label: Text(
organizationController.stories.values
.elementAt(index)
.length
.toString(),
),
child: CircleAvatar(
radius: 35,
backgroundImage:
CachedNetworkImageProvider(data.logo!),
),
),
Text(
data.name,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
);
},
),
);
},
),
),
);
}
}
Loading

0 comments on commit f5568e3

Please sign in to comment.