Skip to content

Commit 46e6b3f

Browse files
Refactor movie app to new Stac structure (#381)
* refactor: Update movie app structure and dependencies - Updated Dart SDK version in pubspec.yaml to ^3.8.0. - Upgraded dependencies including stac and stac_core. - Removed unused JSON screen files and light theme configuration. - Introduced new constants for API endpoints and asset paths. - Added default Stac options for initialization. - Implemented onboarding, home, and detail screens using Stac widgets. - Refactored movie carousel widget to use Stac's JSON serialization. - Enhanced theme management with a dedicated dark theme implementation. * refactor: Update movie app theme management and remove unused files - Removed the deprecated app_theme.dart file and updated references to StacThemeData in various screens. - Adjusted theme usage in detail, home, and onboarding screens to utilize StacThemeData for consistency. - Cleaned up pubspec.lock by removing unused freezed_annotation dependency. * refactor: Improve JSON serialization and update styling in movie app screens * chore: Remove unnecessary blank line in default_stac_options.dart * refactor: Update image dimensions to use double.maxFinite in movie app screens
1 parent ffa42d1 commit 46e6b3f

19 files changed

+1235
-1057
lines changed

examples/movie_app/assets/jsons/screens/detail_screen.json

Lines changed: 0 additions & 408 deletions
This file was deleted.

examples/movie_app/assets/jsons/screens/home_screen.json

Lines changed: 0 additions & 453 deletions
This file was deleted.

examples/movie_app/assets/jsons/screens/onboarding_screen.json

Lines changed: 0 additions & 102 deletions
This file was deleted.

examples/movie_app/assets/jsons/theme/light_theme.json

Whitespace-only changes.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/// Application API endpoints and configuration
2+
///
3+
/// This file contains all API-related constants including base URLs,
4+
/// endpoints, and API configuration.
5+
class AppApi {
6+
AppApi._(); // Private constructor to prevent instantiation
7+
8+
// ============================================================================
9+
// Base Configuration
10+
// ============================================================================
11+
12+
static const String baseUrl = 'https://api.themoviedb.org/3';
13+
static const String imageBaseUrl =
14+
'https://media.themoviedb.org/t/p/w440_and_h660_face';
15+
static const String language = 'en-US';
16+
17+
// ============================================================================
18+
// Movie Endpoints
19+
// ============================================================================
20+
21+
/// Trending movies endpoint for the current day
22+
static String getTrendingMoviesUrl([int page = 1]) =>
23+
'$baseUrl/trending/movie/day?language=$language&page=$page';
24+
25+
/// Now playing movies endpoint
26+
static String getNowPlayingMoviesUrl([int page = 1]) =>
27+
'$baseUrl/movie/now_playing?language=$language&page=$page';
28+
29+
/// Popular movies endpoint
30+
static String getPopularMoviesUrl([int page = 1]) =>
31+
'$baseUrl/movie/popular?language=$language&page=$page';
32+
33+
/// Top rated movies endpoint
34+
static String getTopRatedMoviesUrl([int page = 1]) =>
35+
'$baseUrl/movie/top_rated?language=$language&page=$page';
36+
37+
/// Upcoming movies endpoint
38+
static String getUpcomingMoviesUrl([int page = 1]) =>
39+
'$baseUrl/movie/upcoming?language=$language&page=$page';
40+
41+
/// Movie details endpoint
42+
static String getMovieDetailsUrl(int movieId) =>
43+
'$baseUrl/movie/$movieId?language=$language';
44+
45+
/// Movie credits endpoint
46+
static String getMovieCreditsUrl(int movieId) =>
47+
'$baseUrl/movie/$movieId/credits?language=$language';
48+
49+
/// Similar movies endpoint
50+
static String getSimilarMoviesUrl(int movieId, [int page = 1]) =>
51+
'$baseUrl/movie/$movieId/similar?language=$language&page=$page';
52+
53+
// ============================================================================
54+
// Image URLs
55+
// ============================================================================
56+
57+
/// Get full poster image URL from poster path
58+
static String getPosterImageUrl(String posterPath) =>
59+
'$imageBaseUrl/$posterPath';
60+
61+
/// Get full profile image URL from profile path
62+
static String getProfileImageUrl(String profilePath) =>
63+
'$imageBaseUrl/$profilePath';
64+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/// Application asset paths
2+
///
3+
/// This file contains all asset paths used throughout the application.
4+
class AppAssets {
5+
AppAssets._(); // Private constructor to prevent instantiation
6+
7+
// ============================================================================
8+
// Images
9+
// ============================================================================
10+
11+
static const String onboardingImage = 'assets/images/image.png';
12+
13+
// ============================================================================
14+
// JSON Screens
15+
// ============================================================================
16+
17+
static const String onboardingScreenJson =
18+
'assets/jsons/screens/onboarding_screen.json';
19+
static const String homeScreenJson = 'assets/jsons/screens/home_screen.json';
20+
static const String detailScreenJson =
21+
'assets/jsons/screens/detail_screen.json';
22+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
library;
2+
3+
/// Applicationwide constants
4+
///
5+
/// This file exports all constants used throughout the application
6+
/// for convenient access via a single import.
7+
export 'app_api.dart';
8+
export 'app_assets.dart';
9+
export 'app_strings.dart';
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/// Application-wide string constants
2+
///
3+
/// This file contains all user-facing strings and text content used throughout
4+
/// the application. Grouped by feature/screen for easy maintenance.
5+
class AppStrings {
6+
AppStrings._(); // Private constructor to prevent instantiation
7+
8+
// ============================================================================
9+
// Onboarding Screen
10+
// ============================================================================
11+
12+
static const String onboardingTitle = 'Movie ';
13+
static const String onboardingTitleAccent = '\nDatabase';
14+
static const String onboardingDescription =
15+
'Watch & enjoy a variety of award winning TV shows, movies, anime, and a lot more';
16+
static const String onboardingGetStartedButton = 'Get Started';
17+
18+
// ============================================================================
19+
// Home Screen
20+
// ============================================================================
21+
22+
static const String nowPlaying = 'Now Playing';
23+
static const String popularMovies = 'Popular Movies';
24+
static const String trendingMovies = 'Trending Movies';
25+
static const String topRated = 'Top Rated';
26+
static const String upcomingMovies = 'Upcoming Movies';
27+
28+
// Bottom Navigation
29+
static const String bottomNavHome = 'Home';
30+
static const String bottomNavSearch = 'Search';
31+
static const String bottomNavProfile = 'Profile';
32+
33+
// ============================================================================
34+
// Detail Screen
35+
// ============================================================================
36+
37+
static const String watchTrailer = 'Watch Trailer';
38+
static const String addToWatchlist = 'Add to Watchlist';
39+
static const String about = 'About';
40+
static const String cast = 'Cast';
41+
static const String similarMovies = 'Similar Movies';
42+
43+
// ============================================================================
44+
// Common
45+
// ============================================================================
46+
47+
static const String search = 'Search';
48+
static const String profile = 'Profile';
49+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This file is automatically generated by stac init.
2+
3+
import 'package:stac_core/core/stac_options.dart';
4+
5+
/// Default [StacOptions] for use with your stac project.
6+
///
7+
/// Use this to initialize stac **before** calling [runApp].
8+
///
9+
/// Example:
10+
/// ```dart
11+
/// import 'package:flutter/material.dart';
12+
/// import 'package:stac/stac.dart';
13+
/// import 'default_stac_options.dart';
14+
///
15+
/// void main() {
16+
/// Stac.initialize(options: defaultStacOptions);
17+
///
18+
/// runApp(...);
19+
/// }
20+
/// ```
21+
StacOptions get defaultStacOptions => StacOptions(
22+
name: 'movie_app',
23+
description: '',
24+
projectId: 'pha1PAyoVRqREK5M2k3E',
25+
);

examples/movie_app/lib/main.dart

Lines changed: 9 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'package:dio/dio.dart';
22
import 'package:flutter/material.dart';
3+
import 'package:movie_app/default_stac_options.dart';
4+
import 'package:movie_app/themes/app_theme.dart';
35
import 'package:movie_app/widgets/movie_carousel/movie_carousel_parser.dart';
46
import 'package:stac/stac.dart';
57

@@ -17,7 +19,11 @@ void main() async {
1719
),
1820
);
1921

20-
await Stac.initialize(dio: dio, parsers: [MovieCarouselParser()]);
22+
await Stac.initialize(
23+
options: defaultStacOptions,
24+
dio: dio,
25+
parsers: [MovieCarouselParser()],
26+
);
2127

2228
runApp(const MyApp());
2329
}
@@ -29,83 +35,10 @@ class MyApp extends StatelessWidget {
2935
Widget build(BuildContext context) {
3036
return StacApp(
3137
title: 'Flutter Demo',
32-
theme: StacTheme.fromJson(darkThemeJson),
38+
theme: darkTheme,
3339
homeBuilder: (_) {
34-
return Stac.fromAssets('assets/jsons/screens/onboarding_screen.json');
40+
return Stac(routeName: 'onboarding_screen');
3541
},
3642
);
3743
}
3844
}
39-
40-
final Map<String, dynamic> lightThemeJson = {
41-
"brightness": "light",
42-
"colorScheme": {
43-
"brightness": "light",
44-
"primary": "#14865F",
45-
"onPrimary": "#FFFFFF",
46-
"secondary": "#14865F",
47-
"onSecondary": "#FFFFFF",
48-
"background": "#FFFFFF",
49-
"onBackground": "#010810",
50-
"surface": "#FFFFFF",
51-
"onSurface": "#010810",
52-
"surfaceVariant": "#F6F7F8",
53-
"onSurfaceVariant": "#65010810",
54-
"error": "#FD1717",
55-
"onError": "#FFFFFF",
56-
"outline": "#080110810",
57-
"onOutline": "#120110810",
58-
},
59-
};
60-
61-
final Map<String, dynamic> darkThemeJson = {
62-
"brightness": "dark",
63-
"colorScheme": {
64-
"brightness": "dark",
65-
"primary": "#95E183",
66-
"onPrimary": "#050608",
67-
"secondary": "#95E183",
68-
"onSecondary": "#FFFFFF",
69-
"background": "#050608",
70-
"onBackground": "#FFFFFF",
71-
"surface": "#050608",
72-
"onSurface": "#FFFFFF",
73-
"surfaceVariant": "#101214",
74-
"onSurfaceVariant": "#65FFFFFF",
75-
"error": "#FF6565",
76-
"onError": "#050608",
77-
"outline": "#08FFFFFF",
78-
"onOutline": "#12FFFFFF",
79-
},
80-
"textTheme": {
81-
"displayLarge": {"fontSize": 48, "fontWeight": "w700", "height": 1.1},
82-
"displayMedium": {"fontSize": 40, "fontWeight": "w700", "height": 1.1},
83-
"displaySmall": {"fontSize": 34, "fontWeight": "w700", "height": 1.1},
84-
"headlineLarge": {"fontSize": 30, "fontWeight": "w700", "height": 1.3},
85-
"headlineMedium": {"fontSize": 26, "fontWeight": "w700", "height": 1.3},
86-
"headlineSmall": {"fontSize": 23, "fontWeight": "w700", "height": 1.3},
87-
"titleLarge": {"fontSize": 20, "fontWeight": "w500", "height": 1.3},
88-
"titleMedium": {"fontSize": 18, "fontWeight": "w500", "height": 1.3},
89-
"titleSmall": {"fontSize": 16, "fontWeight": "w500", "height": 1.3},
90-
"labelLarge": {"fontSize": 16, "fontWeight": "w700", "height": 1.3},
91-
"labelMedium": {"fontSize": 14, "fontWeight": "w600", "height": 1.3},
92-
"labelSmall": {"fontSize": 12, "fontWeight": "w500", "height": 1.3},
93-
"bodyLarge": {"fontSize": 18, "fontWeight": "w400", "height": 1.5},
94-
"bodyMedium": {"fontSize": 16, "fontWeight": "w400", "height": 1.5},
95-
"bodySmall": {"fontSize": 14, "fontWeight": "w400", "height": 1.5},
96-
},
97-
"filledButtonTheme": {
98-
"minimumSize": {"width": 120, "height": 40},
99-
"textStyle": {"fontSize": 16, "fontWeight": "w500", "height": 1.3},
100-
"padding": {"left": 10, "right": 10, "top": 8, "bottom": 8},
101-
"shape": {"type": "roundedRectangleBorder", "borderRadius": 8},
102-
},
103-
"outlinedButtonTheme": {
104-
"minimumSize": {"width": 120, "height": 40},
105-
"textStyle": {"fontSize": 16, "fontWeight": "w500", "height": 1.3},
106-
"padding": {"left": 10, "right": 10, "top": 8, "bottom": 8},
107-
"side": {"color": "#95E183", "width": 1.0},
108-
"shape": {"type": "roundedRectangleBorder", "borderRadius": 8},
109-
},
110-
"dividerTheme": {"color": "#24FFFFFF", "thickness": 1},
111-
};

0 commit comments

Comments
 (0)