Skip to content

Commit

Permalink
Merge pull request #34 from dshukertjr/feat/default-videos-on-search-tab
Browse files Browse the repository at this point in the history
Display some contents on search tab before user starts searching
  • Loading branch information
dshukertjr authored Jul 8, 2021
2 parents 6249df1 + e26aa97 commit 6c7b21e
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 202 deletions.
2 changes: 1 addition & 1 deletion ios/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ platform :ios do
)

deliver(
submit_for_review: true,
submit_for_review: false,
automatic_release: false,
skip_metadata: false,
skip_screenshots: false,
Expand Down
4 changes: 2 additions & 2 deletions ios/fastlane/metadata/en-US/release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
- You can upload videos on your device now
- Maps now have labels
- Search tab now displays the recently posted videos
- Video will display the location on lower left corner
37 changes: 2 additions & 35 deletions lib/components/user_profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:spot/app/constants.dart';
import 'package:spot/components/video_list.dart';
import 'package:spot/cubits/profile/profile_cubit.dart';
import 'package:spot/cubits/videos/videos_cubit.dart';
import 'package:spot/pages/edit_profile_page.dart';
import 'package:spot/pages/view_video_page.dart';
import 'package:spot/repositories/repository.dart';

import 'profile_image.dart';
Expand Down Expand Up @@ -57,40 +57,7 @@ class _UserPosts extends StatelessWidget {
return preloader;
} else if (state is VideosLoaded) {
final videos = state.videos;
return Wrap(
children: List.generate(videos.length, (index) {
final video = videos[index];
return FractionallySizedBox(
widthFactor: 0.5,
child: AspectRatio(
aspectRatio: 1,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(ViewVideoPage.route(video.id));
},
child: Image.network(
video.thumbnailUrl,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Center(
child: CircularProgressIndicator(
value: loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ??
10000000),
valueColor:
const AlwaysStoppedAnimation<Color>(appRed),
),
);
},
),
),
),
);
}),
);
return VideoList(videos: videos);
} else if (state is VideosError) {
return const Center(
child: Text('Something went wrong. Please reopen the app. '),
Expand Down
47 changes: 47 additions & 0 deletions lib/components/video_list.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:spot/app/constants.dart';
import 'package:spot/models/video.dart';
import 'package:spot/pages/view_video_page.dart';

class VideoList extends StatelessWidget {
const VideoList({
Key? key,
required this.videos,
}) : super(key: key);

final List<Video> videos;

@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: Wrap(
alignment: WrapAlignment.spaceBetween,
children: List.generate(videos.length, (index) {
final video = videos[index];
return SizedBox(
width: MediaQuery.of(context).size.width / 3,
child: AspectRatio(
aspectRatio: 1,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(ViewVideoPage.route(video.id));
},
child: Image.network(
video.thumbnailUrl,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
}
return preloader;
},
),
),
),
);
}),
),
);
}
}
15 changes: 14 additions & 1 deletion lib/cubits/search/search_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,23 @@ part 'search_state.dart';
class SearchCubit extends Cubit<SearchState> {
SearchCubit({required Repository repository})
: _repository = repository,
super(SearchInitial());
super(SearchLoading());

final Repository _repository;

Future<void> loadInitialVideos() async {
try {
final videos = await _repository.getNewVideos();
if (videos.isEmpty) {
emit(SearchEmpty());
} else {
emit(SearchLoaded(videos));
}
} catch (err) {
emit(SearchError());
}
}

Future<void> search(String queryString) async {
try {
emit(SearchLoading());
Expand Down
2 changes: 0 additions & 2 deletions lib/cubits/search/search_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ part of 'search_cubit.dart';
@immutable
abstract class SearchState {}

class SearchInitial extends SearchState {}

class SearchLoading extends SearchState {}

class SearchLoaded extends SearchState {
Expand Down
7 changes: 7 additions & 0 deletions lib/models/video.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class VideoDetail extends Video {
required this.commentCount,
required this.haveLiked,
required this.createdBy,
this.locationString,
}) : super(
id: id,
url: url,
Expand All @@ -137,6 +138,10 @@ class VideoDetail extends Video {
final bool haveLiked;
final Profile createdBy;

/// String representitive of the location
/// e.g. NewYork, USA
final String? locationString;

static VideoDetail fromData(Map<String, dynamic> data) {
return VideoDetail(
id: data['id'] as String,
Expand Down Expand Up @@ -174,11 +179,13 @@ class VideoDetail extends Video {
int? likeCount,
int? commentCount,
bool? haveLiked,
String? locationString,
}) {
return VideoDetail(
likeCount: likeCount ?? this.likeCount,
commentCount: commentCount ?? this.commentCount,
haveLiked: haveLiked ?? this.haveLiked,
locationString: locationString ?? this.locationString,
createdAt: createdAt,
createdBy: createdBy,
description: description,
Expand Down
65 changes: 5 additions & 60 deletions lib/pages/tabs/search_tab.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:spot/components/video_list.dart';
import 'package:spot/cubits/search/search_cubit.dart';
import 'package:spot/models/video.dart';

import '../../app/constants.dart';
import '../../repositories/repository.dart';
import '../view_video_page.dart';

class SearchTab extends StatefulWidget {
static Widget create() {
return BlocProvider<SearchCubit>(
create: (context) =>
SearchCubit(repository: RepositoryProvider.of<Repository>(context)),
SearchCubit(repository: RepositoryProvider.of<Repository>(context))
..loadInitialVideos(),
child: SearchTab(),
);
}
Expand Down Expand Up @@ -51,18 +51,11 @@ class _SearchTabState extends State<SearchTab> {
),
BlocBuilder<SearchCubit, SearchState>(
builder: (context, state) {
if (state is SearchInitial) {
return const Padding(
padding: EdgeInsets.all(16.0),
child: Center(
child: Text('Search anything you would like'),
),
);
} else if (state is SearchLoading) {
if (state is SearchLoading) {
return preloader;
} else if (state is SearchLoaded) {
final videos = state.videos;
return _SearchResults(videos: videos);
return VideoList(videos: videos);
} else if (state is SearchEmpty) {
return const Padding(
padding: EdgeInsets.all(16.0),
Expand Down Expand Up @@ -105,51 +98,3 @@ class _SearchTabState extends State<SearchTab> {
}
}
}

class _SearchResults extends StatelessWidget {
const _SearchResults({
Key? key,
required this.videos,
}) : super(key: key);

final List<Video> videos;

@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: Wrap(
children: List.generate(videos.length, (index) {
final video = videos[index];
return FractionallySizedBox(
widthFactor: 0.5,
child: AspectRatio(
aspectRatio: 1,
child: GestureDetector(
onTap: () {
Navigator.of(context).push(ViewVideoPage.route(video.id));
},
child: Image.network(
video.thumbnailUrl,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Center(
child: CircularProgressIndicator(
value: loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ?? 100000000),
valueColor: const AlwaysStoppedAnimation<Color>(appRed),
),
);
},
),
),
),
);
}),
),
);
}
}
Loading

0 comments on commit 6c7b21e

Please sign in to comment.