Docs
This commit is contained in:
parent
841a494503
commit
626335208e
7 changed files with 1019 additions and 37 deletions
34
README.md
34
README.md
|
@ -1,13 +1,39 @@
|
|||
# mc_gallery
|
||||
|
||||
## Dart docs explanation
|
||||
The first line of docs are like normal Dart docs. The second line is less of a 'further'
|
||||
explanation, and more of an active commentary for the viewer.
|
||||
|
||||
## Emulation
|
||||
### Main API
|
||||
The unsplash_images_api contains code for fetching data from an external website. Since I have used 'source.unsplash.com', there is no actual daa
|
||||
data (in the form of protected URLs or raw JSON like Facebook API) that is sent back. So this base URL can directly be used to cache the images.<br>
|
||||
|
||||
But I wanted to give a more realistic procedure. So, I manually serialize the same data about the URL to JSON and then deserialize it, just a step
|
||||
further on needlessly. In addition to it, constant fetch delays have added in as well. But in theory, the first serialization can be replaced by actual data-fetch,
|
||||
while the rest works as expected
|
||||
|
||||
### Search API
|
||||
Since websites also have a server-side search call that is available, functionality had been included to make use of that too. But again, this is mocked
|
||||
by the steps mentioned above.
|
||||
|
||||
## Maintaining scope
|
||||
It's an 'assignment'
|
||||
|
||||
## Model vs. DTO
|
||||
Since it's just a demo assignment, I have tried to keep the scope of the functionalities small. By that, I mean I have not fully optimized performance-critical sections,
|
||||
or fixed some rare-case bugs. But instead I have left either a 'todo' for them, or mentioned that in the docs themselves
|
||||
|
||||
## Extra quirks
|
||||
Just because I had those assets lying around
|
||||
A lot of the empty directories and unused asset files are left in, as I used my project templated from my other templates. I decided to leave them in, in any case since they
|
||||
may give a better indication about how I code, should you choose to look into them. A lot of the functionality that I used, is something that I have already made for my previous project(s),
|
||||
so it was not as much work as it seems. One of my recent ones, (luckily) literally had a Gallery feature as well, for congregating social media posts into one place. So a lot of assets were reused from there.
|
||||
|
||||
Some of the extra quirks that I added in are:
|
||||
1. Dark mode support.
|
||||
2. Live search -> both for locally (cached) image files, and Web (using a website's search API).
|
||||
3. Clearing image cache on app going to background, and then restarting the program (way easier on an emulator using hot restart).
|
||||
+ I found it easier to directly use the change in app life cycle, than implement a pull-down-refresh.
|
||||
4. Logging.
|
||||
5. Local storage of favourites state -> on restart, the favourites stay.
|
||||
+ Not very useful on a real device as app restart can only be triggered with app life cycle state change, which would clear the download cache,
|
||||
which would be an invalidate them -> so clearing them away with the image cache for now.
|
||||
6. Web API unit test
|
||||
7. Project UML diagram using `dcdg` and a graphviz pipeline in `docs\` directory.
|
983
doc/Class UML.svg
Normal file
983
doc/Class UML.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 457 KiB |
|
@ -1,7 +1,7 @@
|
|||
abstract class ConstValues {
|
||||
static const String httpsScheme = 'https';
|
||||
static const String backendHost = 'source.unsplash.com';
|
||||
static const List<String> backendUrlPathSegments = ['user', 'c_v_r'];
|
||||
static const String imagesHostServer = 'source.unsplash.com';
|
||||
static const List<String> imagesHostUrlPathSegments = ['user', 'c_v_r'];
|
||||
|
||||
static const int numberOfImages = 25;
|
||||
static const int minImageSize = 50;
|
||||
|
|
|
@ -93,8 +93,8 @@ class UnsplashImagesApi implements ImagesApi {
|
|||
|
||||
Uri _imageUrlGenerator({required int imageSide}) => Uri(
|
||||
scheme: ConstValues.httpsScheme,
|
||||
host: ConstValues.backendHost,
|
||||
pathSegments: [...ConstValues.backendUrlPathSegments, '${imageSide}x$imageSide'],
|
||||
host: ConstValues.imagesHostServer,
|
||||
pathSegments: [...ConstValues.imagesHostUrlPathSegments, '${imageSide}x$imageSide'],
|
||||
);
|
||||
|
||||
static UnsplashImagesApi get locate => Locator.locate();
|
||||
|
|
|
@ -105,6 +105,8 @@ class ImageCarouselView extends StatelessWidget {
|
|||
const Gap(24),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
// Assuming that this data is coming from an external CRM, if it is coming with the
|
||||
// image itself, then add it to the DTO and the Model as well, and access it here.
|
||||
child: MarkdownBody(data: model.strings.imageDetails),
|
||||
),
|
||||
const Gap(16),
|
||||
|
|
0
test/api/images_api_test.dart
Normal file
0
test/api/images_api_test.dart
Normal file
|
@ -1,29 +0,0 @@
|
|||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mc_gallery/app.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(const McgApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue