Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
db34c34
Migrasi ke Flutter V2 Embedding
CoderJava Mar 8, 2021
ccc75fd
Update README.md
CoderJava Mar 24, 2021
79f3e12
Update README.md
CoderJava Mar 24, 2021
61d0166
Starting development v3.0.0
CoderJava Jul 9, 2021
ee90525
Merge remote-tracking branch 'origin/master' into dev-v3.0.0
CoderJava Nov 14, 2021
0471181
Update pubspec.yaml
CoderJava Nov 14, 2021
f58de8a
Create class base_url_config.dart
CoderJava Nov 14, 2021
f59fbb6
Create device_utils.dart
CoderJava Nov 14, 2021
18a63bf
Create flavor_config.dart
CoderJava Nov 14, 2021
098f3cd
Update .gitignore file
CoderJava Nov 21, 2021
83a9d0f
Delete widget_test.dart
CoderJava Nov 21, 2021
29394bd
Added .flutter-plugins-dependencies in .gitignore file
CoderJava Nov 21, 2021
d43ff6e
Add `flutter_lints` in pubspec.yaml
CoderJava Nov 21, 2021
0c6fc98
Create exception.dart file
CoderJava Nov 21, 2021
202e9c9
Create failure.dart file
CoderJava Nov 21, 2021
be8e2b0
Create network_info.dart file
CoderJava Nov 21, 2021
fe0fb39
Create app_route.dart file
CoderJava Nov 21, 2021
28603e7
Create analysis_options.yaml file
CoderJava Nov 21, 2021
385be6b
Create use_case.dart
CoderJava Nov 21, 2021
1f774f0
Create constant_error_message.dart file
CoderJava Nov 21, 2021
765f145
Update pubspec.lock file
CoderJava Dec 19, 2021
63f3e29
Create mock_helper.dart
CoderJava Dec 19, 2021
9431131
Create failure_test.dart
CoderJava Dec 19, 2021
83f2ffb
Create network_info_test.dart file
CoderJava Dec 19, 2021
39e6204
Update .gitignore file
CoderJava Dec 19, 2021
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flutter-plugins-dependencies
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-1.0.5/","dependencies":[]},{"name":"device_info","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.2/","dependencies":[]},{"name":"url_launcher","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.9/","dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-1.0.5/","dependencies":[]},{"name":"device_info","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.2/","dependencies":[]},{"name":"url_launcher","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.9/","dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.0.2/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-2.0.0/","dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.0.3/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-2.0.0/","dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.0.2/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-2.0.0/","dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.0.2/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/yudisetiawan/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-2.0.1/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"device_info","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-07-09 22:18:37.951759","version":"2.2.2"}
20 changes: 19 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
.pub-cache/
.pub/
/build/
.flutter-plugins-dependencies

# Linux
linux/flutter/generated_plugin_registrant.cc
linux/flutter/generated_plugin_registrant.h

# Mac
macos/Flutter/GeneratedPluginRegistrant.swift

# Windows
windows/flutter/generated_plugin_registrant.cc
windows/flutter/generated_plugin_registrant.h

# Web related
lib/generated_plugin_registrant.dart
Expand All @@ -36,4 +48,10 @@ lib/generated_plugin_registrant.dart
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

# Code coverage directory
coverage/
/coverage/

# iOS
/ios/Podfile.lock
/ios/build
*.g.dart
*.mocks.dart
89 changes: 10 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,16 @@
[![Codemagic build status](https://api.codemagic.io/apps/5e93249b1838ac3d3e52a5bc/5e93249b1838ac3d3e52a5bb/status_badge.svg)](https://codemagic.io/apps/5e93249b1838ac3d3e52a5bc/5e93249b1838ac3d3e52a5bb/latest_build)
[![codecov](https://codecov.io/gh/CoderJava/Flutter-News-App/branch/dev-v2.0.0/graph/badge.svg)](https://codecov.io/gh/CoderJava/Flutter-News-App)
[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://github.com/tenhobi/effective_dart)
[![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT)
# flutter_news_app

![Flutter News App](https://github.com/CoderJava/Flutter-News-App/blob/master/screenshots/social%20media%20preview.png)
A new Flutter project.

# Flutter News App
News App developed with Flutter and API from [News API](https://newsapi.org)
## Getting Started

## Versions
- [v1.0.0](https://github.com/CoderJava/Flutter-News-App/tree/v1.0.0)
- [v2.0.0](https://github.com/CoderJava/Flutter-News-App/tree/v2.0.0)
- v3.0.0 under development. You can check the progress [in here](https://trello.com/b/5whQTw74/flutter-news-app-v3)
This project is a starting point for a Flutter application.

## Usage
1. Please open file **constant_config.dart** and change `YOUR API KEY` in the variable `keyNewsApi` with your own.
2. In development mode, I'm used fake json server. So, the data is not realtime.
3. Build flavor only work for Android. So, if you want to run as development mode you can use this command.
```
flutter run -t lib/main_development.dart --flavor development -d <device_id>
```
or in production mode.
```
flutter run --release -t lib/main_production.dart --flavor production -d <device_id>
```
*Note: If you want to build and release this app to Play Store. Please use this command.*
```
flutter build appbundle --release --flavor production -t lib/main_production.dart
```
4. For iOS, you can use this command as development mode.
```
flutter run -t lib/main_development.dart -d <device_id>
```
or in production mode.
```
flutter run --release -t lib/main_production.dart -d <device_id>
```
For iOS, to build and release there is no configuration. Just follow the instructions from the [documentation](https://flutter.dev/docs/deployment/ios).
A few resources to get you started if this is your first Flutter project:

## Feature
- [X] List daily news.
- [X] Filter daily news by category.
- [X] Refresh list daily news with pull to refresh style.
- [X] Go to detail news website.
- [X] Search news.
- [X] Dark mode support.
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)

## Technology
1. Dio<br />
A powerful Http client for Dart, which supports interceptors, FormData, Request Cancellation, File Downloading, Timeout, etc.
2. Flutter BLoC<br />
Flutter widgets that make it easy to implement the BLoC design pattern.
3. Intl<br />
Package providers internationalization and localization facilities, including message translation, plurals and genders, date/number formatting and parsing, and bidirectional text.
4. Url Launcher<br />
Flutter plugin for launching a URL in the mobile platform. Supports iOS and Android.
5. Cached Network Image<br />
Flutter library to load and cache network images. Can also be used with placeholder and error widgets.
6. Get It<br />
Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App.
7. Dartz<br />
Functional Programming in Dart. Purify your Dart code using efficient immutable data structures, monads, lenses and other FP tools.
8. Equatable<br />
An abstract class that helps to implement equality without needing to explicitly override == and hashCode.
9. Data Connection Checker<br />
A pure Dart library that checks for internet by opening a socket to a list of specified addresses, each with individual port and timeout.
10. Flutter ScreenUtil<br />
A Flutter plugin for adapting screen and font size.
11. Pedantic<br />
How to get the most value from Dart static analysis.
12. Device Info<br />
Flutter plugin providing detailed information about the device (make, model, etc).
13. Flutter SVG<br />
An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files.
14. Build Runner<br />
Tools to write binaries that run builders.
15. Mockito<br />
A mock framework inspired by Mockito.
16. Bloc Test<br />
A testing library which makes it easy to test blocs.
17. JSON Serializable<br />
Automatically generate code for converting to and from JSON by annotating Dart classes.
18. Hive<br />
Lightweight and blazing fast key-value database written in pure Dart.
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
6 changes: 5 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
include: package:pedantic/analysis_options.yaml
include: package:flutter_lints/flutter.yaml

linter:
rules:
unnecessary_overrides: false
4 changes: 4 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ gradle-wrapper.jar
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java

# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
24 changes: 2 additions & 22 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,19 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 28
compileSdkVersion 30

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.ysn.flutter_news_app"
minSdkVersion 16
targetSdkVersion 28
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
Expand All @@ -53,18 +48,6 @@ android {
signingConfig signingConfigs.debug
}
}

flavorDimensions "production, development"
productFlavors {
production {
resValue "string", "app_name", "News App"
}
development {
resValue "string", "app_name", "dev-News App"
applicationIdSuffix ".development"
versionNameSuffix "-dev"
}
}
}

flutter {
Expand All @@ -73,7 +56,4 @@ flutter {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
41 changes: 23 additions & 18 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,35 +1,40 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ysn.flutter_news_app">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->

<uses-permission android:name="android.permission.INTERNET" />

<application
android:name="io.flutter.app.FlutterApplication"
android:label="@string/app_name"
android:label="flutter_news_app"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
package com.ysn.flutter_news_app

import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
class MainActivity : FlutterActivity() {
}
11 changes: 11 additions & 0 deletions android/app/src/main/res/drawable-v21/launch_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />

<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
18 changes: 18 additions & 0 deletions android/app/src/main/res/values-night/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
12 changes: 11 additions & 1 deletion android/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.

This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
4 changes: 1 addition & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand All @@ -21,8 +21,6 @@ allprojects {
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}

Expand Down
1 change: 0 additions & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
18 changes: 7 additions & 11 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
include ':app'

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()

def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }

plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
Binary file removed assets/images/img_business.png
Binary file not shown.
Binary file removed assets/images/img_entertainment.png
Binary file not shown.
Binary file removed assets/images/img_health.png
Binary file not shown.
Binary file removed assets/images/img_not_found.jpg
Binary file not shown.
Binary file removed assets/images/img_placeholder.jpg
Binary file not shown.
Binary file removed assets/images/img_science.png
Binary file not shown.
Binary file removed assets/images/img_sport.png
Binary file not shown.
Binary file removed assets/images/img_technology.png
Binary file not shown.
Loading