├── ios
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── project.pbxproj
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
└── .gitignore
├── images
├── zaim.jpg
└── icon_user.png
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ └── Icon-512.png
├── manifest.json
└── index.html
├── android
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v21
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── values
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-night
│ │ │ │ │ └── styles.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── newsly
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── google-services.json
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
└── build.gradle
├── .metadata
├── lib
├── main.dart
├── model
│ ├── article.dart
│ └── news.dart
├── view
│ ├── widget
│ │ ├── dateTimeField.dart
│ │ ├── shimmerLoading.dart
│ │ ├── card_widget.dart
│ │ ├── dialog_widget.dart
│ │ └── newsList.dart
│ ├── page
│ │ ├── sport
│ │ │ ├── topHeadlinesSport.dart
│ │ │ ├── breakNewsSport.dart
│ │ │ └── sportNews.dart
│ │ ├── health
│ │ │ ├── topHeadlinesHealth.dart
│ │ │ ├── breakNewsHealth.dart
│ │ │ └── healthNews.dart
│ │ ├── general
│ │ │ ├── topHeadlineGeneral.dart
│ │ │ ├── breakNewsGeneral.dart
│ │ │ └── generalNews.dart
│ │ ├── technology
│ │ │ ├── topHeadlinesTechnology.dart
│ │ │ ├── breakNewsTechnology.dart
│ │ │ └── technologyNews.dart
│ │ ├── business
│ │ │ ├── topHeadlinesBusiness.dart
│ │ │ ├── breakNewsBusiness.dart
│ │ │ └── businessNews.dart
│ │ └── articles
│ │ │ ├── articles_page.dart
│ │ │ ├── formAddArticle.dart
│ │ │ └── formUpdateArticle.dart
│ ├── splash.dart
│ ├── detailNews.dart
│ ├── drawer.dart
│ ├── beranda.dart
│ └── home.dart
└── viewmodel
│ └── service
│ ├── api_service.dart
│ └── firestore_service.dart
├── .gitignore
├── README.md
├── test
└── widget_test.dart
├── pubspec.yaml
└── pubspec.lock
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/images/zaim.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/images/zaim.jpg
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/web/favicon.png
--------------------------------------------------------------------------------
/images/icon_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/images/icon_user.png
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/newsly/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.newsly
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity()
6 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MZaimM/Newsly-Flutter-App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: d79295af24c3ed621c33713ecda14ad196fd9c31
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:firebase_core/firebase_core.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:newsly/view/splash.dart';
4 |
5 | void main() {
6 | runApp(MyApp());
7 | }
8 |
9 | class MyApp extends StatelessWidget {
10 | // This widget is the root of your application.
11 | @override
12 | Widget build(BuildContext context) {
13 | Firebase.initializeApp();
14 | return MaterialApp(
15 | debugShowCheckedModeBanner: false,
16 | title: 'Newsly',
17 | theme: ThemeData(
18 | primarySwatch: Colors.blue,
19 | ),
20 | home:SplashScreen(),
21 | );
22 | }
23 | }
--------------------------------------------------------------------------------
/lib/model/article.dart:
--------------------------------------------------------------------------------
1 | class Article {
2 | String? id;
3 | String? title;
4 | String? date;
5 | String? author;
6 | String? urlArtikel;
7 | String? description;
8 |
9 | String? get deskripsi => description;
10 |
11 | set deskripsi(String? deskripsi) {
12 | description = deskripsi;
13 | }
14 | String? image;
15 |
16 | String? get gambar => image;
17 |
18 | set gambar(String? image) {
19 | image = image;
20 | }
21 |
22 | Article(
23 | {this.author,
24 | this.date,
25 | this.description,
26 | this.id,
27 | this.image,
28 | this.title,
29 | this.urlArtikel});
30 | }
31 |
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "newsly",
3 | "short_name": "newsly",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/ephemeral/
22 | Flutter/app.flx
23 | Flutter/app.zip
24 | Flutter/flutter_assets/
25 | Flutter/flutter_export_environment.sh
26 | ServiceDefinitions.json
27 | Runner/GeneratedPluginRegistrant.*
28 |
29 | # Exceptions to above rules.
30 | !default.mode1v3
31 | !default.mode2v3
32 | !default.pbxuser
33 | !default.perspectivev3
34 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | classpath 'com.google.gms:google-services:4.3.10'
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | }
20 | }
21 |
22 | rootProject.buildDir = '../build'
23 | subprojects {
24 | project.buildDir = "${rootProject.buildDir}/${project.name}"
25 | project.evaluationDependsOn(':app')
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/lib/view/widget/dateTimeField.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:date_field/date_field.dart';
3 |
4 | class DateTimeField extends StatelessWidget {
5 | DateTimeField({Key? key}) : super(key: key);
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return DateTimeFormField(
10 | decoration: InputDecoration(
11 | hintText: "Date",
12 | labelText: "Date",
13 | prefixIcon: Icon(Icons.date_range_outlined),
14 | border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.0))),
15 | mode: DateTimeFieldPickerMode.dateAndTime,
16 | autovalidateMode: AutovalidateMode.always,
17 | validator: (e) => (e?.day ?? 0) == 1 ? 'Please not the first day' : null,
18 | onDateSelected: (DateTime value) {
19 | print(value);
20 | },
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Newsly Flutter App
2 |
3 | Newsly is an application built using the flutter framework. In this application, it has a feature to read news and add your own articles to the newsly application. Newsly uses the MVVM (Model-View-Viewmodel) architecture. On the backend side, the data is obtained from https://newsapi.org/ and uses firebase in its data storage.
4 |
5 |
6 | 
7 | 
8 |
9 |
10 | ## Getting Started
11 |
12 | This project is a starting point for a Flutter application.
13 |
14 | A few resources to get you started if this is your first Flutter project:
15 |
16 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
17 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
18 |
19 | For help getting started with Flutter, view our
20 | [online documentation](https://flutter.dev/docs), which offers tutorials,
21 | samples, guidance on mobile development, and a full API reference.
22 |
--------------------------------------------------------------------------------
/lib/view/page/sport/topHeadlinesSport.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class TopHeadlinesSport extends StatelessWidget {
9 | const TopHeadlinesSport({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | child: FutureBuilder>(
17 | future: api.fetchNewsSport(http.Client()),
18 | builder: (context, snapshot) {
19 | if (snapshot.hasError) {
20 | return Center(
21 | child: Text("Pengambilan Data API Error"),
22 | );
23 | }else if (snapshot.hasData){
24 | return TopHeadlinesList(news: snapshot.data!);
25 | }
26 | return Center(
27 | child: ShimmerLoadingTopHead(),
28 | );
29 | },
30 | ),
31 | );
32 | }
33 | }
--------------------------------------------------------------------------------
/android/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "517842577037",
4 | "project_id": "newsly-c7bc0",
5 | "storage_bucket": "newsly-c7bc0.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:517842577037:android:53380392d1b80db4ace4c4",
11 | "android_client_info": {
12 | "package_name": "com.example.newsly"
13 | }
14 | },
15 | "oauth_client": [
16 | {
17 | "client_id": "517842577037-h7hbp2omei0hkbtbuu9q4p4fsuu7roji.apps.googleusercontent.com",
18 | "client_type": 3
19 | }
20 | ],
21 | "api_key": [
22 | {
23 | "current_key": "AIzaSyD3GDyq0Ktg5LlqU90UkylJEtn0ErI1I6k"
24 | }
25 | ],
26 | "services": {
27 | "appinvite_service": {
28 | "other_platform_oauth_client": [
29 | {
30 | "client_id": "517842577037-h7hbp2omei0hkbtbuu9q4p4fsuu7roji.apps.googleusercontent.com",
31 | "client_type": 3
32 | }
33 | ]
34 | }
35 | }
36 | }
37 | ],
38 | "configuration_version": "1"
39 | }
--------------------------------------------------------------------------------
/lib/view/page/health/topHeadlinesHealth.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:newsly/view/widget/newsList.dart';
5 | import 'package:http/http.dart' as http;
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class TopHeadlinesHealth extends StatelessWidget {
9 | const TopHeadlinesHealth({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | child: FutureBuilder>(
17 | future: api.fetchNewsHealth(http.Client()),
18 | builder: (context, snapshot) {
19 | if (snapshot.hasError) {
20 | return Center(
21 | child: Text("Pengambilan Data API Error"),
22 | );
23 | }else if (snapshot.hasData){
24 | return TopHeadlinesList(news: snapshot.data!);
25 | }
26 | return Center(
27 | child: ShimmerLoadingTopHead(),
28 | );
29 | },
30 | ),
31 | );
32 | }
33 | }
--------------------------------------------------------------------------------
/lib/view/page/general/topHeadlineGeneral.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:http/http.dart' as http;
3 | import 'package:newsly/model/news.dart';
4 | import 'package:newsly/viewmodel/service/api_service.dart';
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class TopHeadlinesGeneral extends StatelessWidget {
9 | const TopHeadlinesGeneral({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | child: FutureBuilder>(
17 | future: api.fetchNewsGeneral(http.Client()),
18 | builder: (context, snapshot) {
19 | if (snapshot.hasError) {
20 | return Center(
21 | child: Text("Pengambilan Data API Error"),
22 | );
23 | }else if (snapshot.hasData){
24 | return TopHeadlinesList(news: snapshot.data!);
25 | }
26 | return Center(
27 | child: ShimmerLoadingTopHead(),
28 | );
29 | },
30 | ),
31 | );
32 | }
33 | }
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:newsly/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/lib/view/page/sport/breakNewsSport.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class BreakNewsSport extends StatelessWidget {
9 | const BreakNewsSport({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | height: 270,
17 | child: FutureBuilder>(
18 | future: api.fetchNewsSport(http.Client()),
19 | builder: (context, snapshot) {
20 | if (snapshot.hasError) {
21 | return Center(
22 | child: Text("Pengambilan Data API Error"),
23 | );
24 | }else if (snapshot.hasData){
25 | return BreakNewsList(news: snapshot.data!);
26 | }
27 | return Center(
28 | child: ShimmerLoadingBreakNews(),
29 | );
30 | },
31 | ),
32 | );
33 | }
34 | }
--------------------------------------------------------------------------------
/lib/view/page/health/breakNewsHealth.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class BreakNewsHealth extends StatelessWidget {
9 | const BreakNewsHealth({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | height: 270,
17 | child: FutureBuilder>(
18 | future: api.fetchNewsHealth(http.Client()),
19 | builder: (context, snapshot) {
20 | if (snapshot.hasError) {
21 | return Center(
22 | child: Text("Pengambilan Data API Error"),
23 | );
24 | }else if (snapshot.hasData){
25 | return BreakNewsList(news: snapshot.data!);
26 | }
27 | return Center(
28 | child: ShimmerLoadingBreakNews(),
29 | );
30 | },
31 | ),
32 | );
33 | }
34 | }
--------------------------------------------------------------------------------
/lib/view/page/technology/topHeadlinesTechnology.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class TopHeadlinesTechnology extends StatelessWidget {
9 | const TopHeadlinesTechnology({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | child: FutureBuilder>(
17 | future: api.fetchNewsTechnology(http.Client()),
18 | builder: (context, snapshot) {
19 | if (snapshot.hasError) {
20 | return Center(
21 | child: Text("Pengambilan Data API Error"),
22 | );
23 | }else if (snapshot.hasData){
24 | return TopHeadlinesList(news: snapshot.data!);
25 | }
26 | return Center(
27 | child: ShimmerLoadingTopHead(),
28 | );
29 | },
30 | ),
31 | );
32 | }
33 | }
--------------------------------------------------------------------------------
/lib/view/page/general/breakNewsGeneral.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class BreakNewsGeneral extends StatelessWidget {
9 | const BreakNewsGeneral({ Key? key }) : super(key: key);
10 |
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | ApiService api = ApiService();
15 |
16 | return Container(
17 | height: 270,
18 | child: FutureBuilder>(
19 | future: api.fetchNewsGeneral(http.Client()),
20 | builder: (context, snapshot) {
21 | if (snapshot.hasError) {
22 | return Center(
23 | child: Text("Pengambilan Data API Error"),
24 | );
25 | }else if (snapshot.hasData){
26 | return BreakNewsList(news: snapshot.data!);
27 | }
28 | return Center(
29 | child: ShimmerLoadingBreakNews(),
30 | );
31 | },
32 | ),
33 | );
34 | }
35 | }
--------------------------------------------------------------------------------
/lib/view/splash.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:animated_splash_screen/animated_splash_screen.dart';
3 | import 'package:newsly/view/beranda.dart';
4 | import 'package:page_transition/page_transition.dart';
5 | import 'package:shimmer/shimmer.dart';
6 |
7 | class SplashScreen extends StatelessWidget {
8 | const SplashScreen({Key? key}) : super(key: key);
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return MaterialApp(
13 | debugShowCheckedModeBanner: false,
14 | home: AnimatedSplashScreen(
15 | splash: Shimmer.fromColors(
16 | baseColor: Colors.white,
17 | highlightColor: Colors.lightBlue,
18 | child: Center(
19 | child: Text(
20 | "Newsly",
21 | style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
22 | ),
23 | ),
24 | ),
25 | nextScreen: Beranda(),
26 | duration: 2000,
27 | splashTransition: SplashTransition.fadeTransition,
28 | pageTransitionType: PageTransitionType.fade,
29 | backgroundColor: Colors.blue,
30 | ),
31 | );
32 | }
33 | }
34 |
35 |
36 |
--------------------------------------------------------------------------------
/lib/view/page/technology/breakNewsTechnology.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:newsly/view/widget/newsList.dart';
5 | import 'package:http/http.dart' as http;
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class BreakNewsTechnology extends StatelessWidget {
9 | const BreakNewsTechnology({ Key? key }) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | ApiService api = ApiService();
14 |
15 | return Container(
16 | height: 270,
17 | child: FutureBuilder>(
18 | future: api.fetchNewsTechnology(http.Client()),
19 | builder: (context, snapshot) {
20 | if (snapshot.hasError) {
21 | return Center(
22 | child: Text("Pengambilan Data API Error"),
23 | );
24 | }else if (snapshot.hasData){
25 | return BreakNewsList(news: snapshot.data!);
26 | }
27 | return Center(
28 | child: ShimmerLoadingBreakNews(),
29 | );
30 | },
31 | ),
32 | );
33 | }
34 | }
--------------------------------------------------------------------------------
/lib/view/page/business/topHeadlinesBusiness.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:newsly/view/widget/newsList.dart';
5 | import 'package:http/http.dart' as http;
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class TopHeadlinesBusiness extends StatefulWidget {
9 | const TopHeadlinesBusiness({ Key? key }) : super(key: key);
10 |
11 | @override
12 | _TopHeadlinesBusinessState createState() => _TopHeadlinesBusinessState();
13 | }
14 |
15 | class _TopHeadlinesBusinessState extends State {
16 | @override
17 | Widget build(BuildContext context) {
18 | ApiService api = ApiService();
19 |
20 | return Container(
21 | child: FutureBuilder>(
22 | future: api.fetchNewsBusiness(http.Client()),
23 | builder: (context, snapshot) {
24 | if (snapshot.hasError) {
25 | return Center(
26 | child: Text("Pengambilan Data API Error"),
27 | );
28 | }else if (snapshot.hasData){
29 | return TopHeadlinesList(news: snapshot.data!);
30 | }
31 | return Center(
32 | child: ShimmerLoadingTopHead(),
33 | );
34 | },
35 | ),
36 | );
37 | }
38 | }
--------------------------------------------------------------------------------
/lib/view/page/business/breakNewsBusiness.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/model/news.dart';
3 | import 'package:newsly/viewmodel/service/api_service.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'package:newsly/view/widget/newsList.dart';
6 | import 'package:newsly/view/widget/shimmerLoading.dart';
7 |
8 | class BreakNewsBusiness extends StatefulWidget {
9 | const BreakNewsBusiness({ Key? key }) : super(key: key);
10 |
11 | @override
12 | _BreakNewsBusinessState createState() => _BreakNewsBusinessState();
13 | }
14 |
15 | class _BreakNewsBusinessState extends State {
16 | @override
17 | Widget build(BuildContext context) {
18 | ApiService api = ApiService();
19 |
20 | return Container(
21 | height: 270,
22 | child: FutureBuilder>(
23 | future: api.fetchNewsBusiness(http.Client()),
24 | builder: (context, snapshot) {
25 | if (snapshot.hasError) {
26 | return Center(
27 | child: Text("Pengambilan Data API Error"),
28 | );
29 | }else if (snapshot.hasData){
30 | return BreakNewsList(news: snapshot.data!);
31 | }
32 | return Center(
33 | child: ShimmerLoadingBreakNews(),
34 | );
35 | },
36 | ),
37 | );
38 | }
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/lib/view/detailNews.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:webview_flutter/webview_flutter.dart';
5 |
6 | class DetailNews extends StatelessWidget {
7 | String? author;
8 | String? title;
9 | String? image;
10 | String? published;
11 | String? content;
12 | String? url;
13 | String? source;
14 | Completer _controller = Completer();
15 |
16 | DetailNews(
17 | {Key? key,
18 | this.author,
19 | this.title,
20 | this.image,
21 | this.published,
22 | this.content,
23 | this.url,
24 | this.source})
25 | : super(key: key);
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return Scaffold(
30 | appBar: AppBar(
31 | backgroundColor: Colors.white,
32 | elevation: 0,
33 | title: Text(
34 | source!,
35 | style: TextStyle(color: Colors.blue),
36 | ),
37 | leading: IconButton(
38 | icon: Icon(
39 | Icons.arrow_back,
40 | color: Colors.black,
41 | ),
42 | onPressed: () {
43 | Navigator.pop(context);
44 | },
45 | ),
46 | ),
47 | backgroundColor: Colors.white,
48 | body: WebView(
49 | initialUrl: url,
50 | javascriptMode: JavascriptMode.unrestricted,
51 | onWebViewCreated: (WebViewController webViewController) {
52 | _controller.complete(webViewController);
53 | },
54 | ));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/view/drawer.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DrawerMenu extends StatelessWidget {
4 | const DrawerMenu({ Key? key }) : super(key: key);
5 |
6 | @override
7 | Widget build(BuildContext context) {
8 | return Drawer(
9 | child: ListView(
10 | children: [
11 | UserAccountsDrawerHeader(
12 | currentAccountPicture: Container(
13 | child: Image.asset('images/icon_user.png'),
14 | ),
15 | accountName: Text('Muhammad Zaim Maulana'),
16 | accountEmail: Text('19650058@student.uin-malang.ac.id')),
17 | ListTile(
18 | leading: Icon(Icons.home),
19 | title: Text('Beranda'),
20 | onTap: (){
21 | },
22 | ),
23 | ListTile(
24 | leading: Icon(Icons.devices),
25 | title: Text('Technology'),
26 | onTap: (){
27 |
28 | },
29 | ),
30 | ListTile(
31 | leading: Icon(Icons.business),
32 | title: Text('Business'),
33 | onTap: (){
34 |
35 | },
36 | ),
37 | ListTile(
38 | leading: Icon(Icons.health_and_safety),
39 | title: Text('Healthy'),
40 | onTap: (){
41 |
42 | },
43 | ),
44 | ListTile(
45 | leading: Icon(Icons.sports),
46 | title: Text('Sports'),
47 | onTap: (){
48 |
49 | },
50 | ),
51 | ],
52 | ),
53 | );
54 | }
55 | }
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | newsly
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/lib/view/page/sport/sportNews.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hexcolor/hexcolor.dart';
3 | import 'package:newsly/view/page/sport/breakNewsSport.dart';
4 | import 'package:newsly/view/page/sport/topHeadlinesSport.dart';
5 |
6 | class SportNews extends StatelessWidget {
7 | const SportNews({ Key? key }) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Container(
12 | margin: EdgeInsets.only(top: 16),
13 | child: SingleChildScrollView(
14 | child: Column(
15 | mainAxisSize: MainAxisSize.min,
16 | crossAxisAlignment: CrossAxisAlignment.start,
17 | children: [
18 | Container(
19 | margin: EdgeInsets.only(left: 16),
20 | child: Text(
21 | 'Breaking News',
22 | style: TextStyle(
23 | fontSize: 24,
24 | fontWeight: FontWeight.bold,
25 | color: HexColor('#4E3A55')),
26 | ),
27 | ),
28 | SizedBox(
29 | height: 16,
30 | ),
31 | BreakNewsSport(),
32 | SizedBox(
33 | height: 24,
34 | ),
35 | Container(
36 | margin: EdgeInsets.only(left: 16),
37 | child: Text(
38 | 'Top Headlines',
39 | style: TextStyle(
40 | fontSize: 24,
41 | fontWeight: FontWeight.bold,
42 | color: HexColor('#4E3A55')),
43 | ),
44 | ),
45 | SizedBox(
46 | height: 16,
47 | ),
48 | TopHeadlinesSport()
49 | ],
50 | ),
51 | ));
52 | }
53 | }
--------------------------------------------------------------------------------
/lib/view/page/health/healthNews.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hexcolor/hexcolor.dart';
3 | import 'package:newsly/view/page/health/breakNewsHealth.dart';
4 | import 'package:newsly/view/page/health/topHeadlinesHealth.dart';
5 |
6 | class HealthNews extends StatelessWidget {
7 | const HealthNews({ Key? key }) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Container(
12 | margin: EdgeInsets.only(top: 16),
13 | child: SingleChildScrollView(
14 | child: Column(
15 | mainAxisSize: MainAxisSize.min,
16 | crossAxisAlignment: CrossAxisAlignment.start,
17 | children: [
18 | Container(
19 | margin: EdgeInsets.only(left: 16),
20 | child: Text(
21 | 'Breaking News',
22 | style: TextStyle(
23 | fontSize: 24,
24 | fontWeight: FontWeight.bold,
25 | color: HexColor('#4E3A55')),
26 | ),
27 | ),
28 | SizedBox(
29 | height: 16,
30 | ),
31 | BreakNewsHealth(),
32 | SizedBox(
33 | height: 24,
34 | ),
35 | Container(
36 | margin: EdgeInsets.only(left: 16),
37 | child: Text(
38 | 'Top Headlines',
39 | style: TextStyle(
40 | fontSize: 24,
41 | fontWeight: FontWeight.bold,
42 | color: HexColor('#4E3A55')),
43 | ),
44 | ),
45 | SizedBox(
46 | height: 16,
47 | ),
48 | TopHeadlinesHealth()
49 | ],
50 | ),
51 | ));
52 | }
53 | }
--------------------------------------------------------------------------------
/lib/view/page/general/generalNews.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hexcolor/hexcolor.dart';
3 | import 'package:newsly/view/page/general/breakNewsGeneral.dart';
4 | import 'package:newsly/view/page/general/topHeadlineGeneral.dart';
5 |
6 | class GeneralNews extends StatelessWidget {
7 | const GeneralNews({ Key? key }) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Container(
12 | margin: EdgeInsets.only(top: 16),
13 | child: SingleChildScrollView(
14 | child: Column(
15 | mainAxisSize: MainAxisSize.min,
16 | crossAxisAlignment: CrossAxisAlignment.start,
17 | children: [
18 | Container(
19 | margin: EdgeInsets.only(left: 16),
20 | child: Text(
21 | 'Breaking News',
22 | style: TextStyle(
23 | fontSize: 24,
24 | fontWeight: FontWeight.bold,
25 | color: HexColor('#4E3A55')),
26 | ),
27 | ),
28 | SizedBox(
29 | height: 16,
30 | ),
31 | BreakNewsGeneral(),
32 | SizedBox(
33 | height: 24,
34 | ),
35 | Container(
36 | margin: EdgeInsets.only(left: 16),
37 | child: Text(
38 | 'Top Headlines',
39 | style: TextStyle(
40 | fontSize: 24,
41 | fontWeight: FontWeight.bold,
42 | color: HexColor('#4E3A55')),
43 | ),
44 | ),
45 | SizedBox(
46 | height: 16,
47 | ),
48 | TopHeadlinesGeneral()
49 | ],
50 | ),
51 | ));
52 | }
53 | }
--------------------------------------------------------------------------------
/lib/view/page/business/businessNews.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hexcolor/hexcolor.dart';
3 | import 'package:newsly/view/page/business/breakNewsBusiness.dart';
4 | import 'package:newsly/view/page/business/topHeadlinesBusiness.dart';
5 |
6 | class BusinessNews extends StatelessWidget {
7 | const BusinessNews({ Key? key }) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Container(
12 | margin: EdgeInsets.only(top: 16),
13 | child: SingleChildScrollView(
14 | child: Column(
15 | mainAxisSize: MainAxisSize.min,
16 | crossAxisAlignment: CrossAxisAlignment.start,
17 | children: [
18 | Container(
19 | margin: EdgeInsets.only(left: 16),
20 | child: Text(
21 | 'Breaking News',
22 | style: TextStyle(
23 | fontSize: 24,
24 | fontWeight: FontWeight.bold,
25 | color: HexColor('#4E3A55')),
26 | ),
27 | ),
28 | SizedBox(
29 | height: 16,
30 | ),
31 | BreakNewsBusiness(),
32 | SizedBox(
33 | height: 24,
34 | ),
35 | Container(
36 | margin: EdgeInsets.only(left: 16),
37 | child: Text(
38 | 'Top Headlines',
39 | style: TextStyle(
40 | fontSize: 24,
41 | fontWeight: FontWeight.bold,
42 | color: HexColor('#4E3A55')),
43 | ),
44 | ),
45 | SizedBox(
46 | height: 16,
47 | ),
48 | TopHeadlinesBusiness()
49 | ],
50 | ),
51 | ));
52 | }
53 | }
--------------------------------------------------------------------------------
/lib/view/page/technology/technologyNews.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hexcolor/hexcolor.dart';
3 | import 'package:newsly/view/page/technology/breakNewsTechnology.dart';
4 | import 'package:newsly/view/page/technology/topHeadlinesTechnology.dart';
5 |
6 | class TechnologyNews extends StatelessWidget {
7 | const TechnologyNews({ Key? key }) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Container(
12 | margin: EdgeInsets.only(top: 16),
13 | child: SingleChildScrollView(
14 | child: Column(
15 | mainAxisSize: MainAxisSize.min,
16 | crossAxisAlignment: CrossAxisAlignment.start,
17 | children: [
18 | Container(
19 | margin: EdgeInsets.only(left: 16),
20 | child: Text(
21 | 'Breaking News',
22 | style: TextStyle(
23 | fontSize: 24,
24 | fontWeight: FontWeight.bold,
25 | color: HexColor('#4E3A55')),
26 | ),
27 | ),
28 | SizedBox(
29 | height: 16,
30 | ),
31 | BreakNewsTechnology(),
32 | SizedBox(
33 | height: 24,
34 | ),
35 | Container(
36 | margin: EdgeInsets.only(left: 16),
37 | child: Text(
38 | 'Top Headlines',
39 | style: TextStyle(
40 | fontSize: 24,
41 | fontWeight: FontWeight.bold,
42 | color: HexColor('#4E3A55')),
43 | ),
44 | ),
45 | SizedBox(
46 | height: 16,
47 | ),
48 | TopHeadlinesTechnology()
49 | ],
50 | ),
51 | ));
52 | }
53 | }
--------------------------------------------------------------------------------
/lib/viewmodel/service/api_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:http/http.dart' as http;
4 | import 'package:newsly/model/news.dart';
5 |
6 | class ApiService{
7 | late String _category;
8 | String _country = "id";
9 | String _apiKey2 = "2321d66b033643c59f2179c5a077da24";
10 | String _baseUrl = "https://newsapi.org/v2/";
11 |
12 | List parseNews(String responseBody){
13 | final parsed = jsonDecode(responseBody);
14 | final jsonObject = (parsed as Map)["articles"];
15 | return jsonObject.map((json) => News.fromJson(json)).toList();
16 | }
17 |
18 | // Fetch News General
19 | Future> fetchNewsGeneral(http.Client client) async {
20 | _category = "general";
21 | final response = await client.get(
22 | Uri.parse('${_baseUrl}top-headlines?country=$_country&category=$_category&apiKey=$_apiKey2')
23 | );
24 | return parseNews(response.body);
25 | }
26 | Future> fetchNewsSport(http.Client client) async {
27 | _category = "sport";
28 | final response = await client.get(
29 | Uri.parse('${_baseUrl}top-headlines?country=$_country&category=$_category&apiKey=$_apiKey2')
30 | );
31 | return parseNews(response.body);
32 | }
33 | Future> fetchNewsHealth(http.Client client) async {
34 | _category = "health";
35 | final response = await client.get(
36 | Uri.parse('${_baseUrl}top-headlines?country=$_country&category=$_category&apiKey=$_apiKey2')
37 | );
38 | return parseNews(response.body);
39 | }
40 | Future> fetchNewsBusiness(http.Client client) async {
41 | _category = "business";
42 | final response = await client.get(
43 | Uri.parse('${_baseUrl}top-headlines?country=$_country&category=$_category&apiKey=$_apiKey2')
44 | );
45 | return parseNews(response.body);
46 | }
47 | Future> fetchNewsTechnology(http.Client client) async {
48 | _category = "technology";
49 | final response = await client.get(
50 | Uri.parse('${_baseUrl}top-headlines?country=$_country&category=$_category&apiKey=$_apiKey2')
51 | );
52 | return parseNews(response.body);
53 | }
54 |
55 |
56 | }
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
9 |
16 |
20 |
24 |
29 |
33 |
34 |
35 |
36 |
37 |
38 |
40 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/lib/viewmodel/service/firestore_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:cloud_firestore/cloud_firestore.dart';
2 | import 'package:firebase_core/firebase_core.dart';
3 |
4 | final FirebaseFirestore _firestore = FirebaseFirestore.instance;
5 | final CollectionReference _reference = _firestore.collection('articles');
6 |
7 | class FirestoreService {
8 | static Future addItem(
9 | {required String title,
10 | required String author,
11 | required String published,
12 | required String urlArticle,
13 | required String description,
14 | required String image,
15 | required String id}) async {
16 | DocumentReference documentReferencer = _reference.doc();
17 |
18 | Map data = {
19 | "title": title,
20 | "author": author,
21 | "published": published,
22 | "url": urlArticle,
23 | "description": description,
24 | "image": image,
25 | "id" : id
26 | };
27 |
28 | await documentReferencer
29 | .set(data)
30 | .whenComplete(() => print("Data Artikel berhasil Ditambahkan"))
31 | .catchError((e) => print(e));
32 | }
33 |
34 | static Stream readItems() {
35 | CollectionReference readReference = _reference;
36 | return readReference.snapshots();
37 | }
38 |
39 | static Future updateItem(
40 | {required String title,
41 | required String author,
42 | required String published,
43 | required String urlArticle,
44 | required String description,
45 | required String id, required String image}) async {
46 | await Firebase.initializeApp();
47 | DocumentReference documentReferencer = _reference.doc(id);
48 |
49 | Map data = {
50 | "title": title,
51 | "author": author,
52 | "published": published,
53 | "url": urlArticle,
54 | "description": description,
55 | "image" : image
56 | };
57 |
58 | await documentReferencer
59 | .update(data)
60 | .whenComplete(() => print("Data Artikel berhasil Diupdate"))
61 | .catchError((e) => print(e));
62 | }
63 |
64 | static Future deleteItem({required String id}) async {
65 | DocumentReference documentReference = _reference.doc(id);
66 |
67 | await documentReference
68 | .delete()
69 | .whenComplete(() => print("Data berhasil dihapus"))
70 | .catchError((e) => print("Data gagal dihapus"));
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | def keystoreProperties = new Properties()
29 | def keystorePropertiesFile = rootProject.file('key.properties')
30 | if (keystorePropertiesFile.exists()) {
31 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
32 | }
33 |
34 | android {
35 | compileSdkVersion 30
36 |
37 | sourceSets {
38 | main.java.srcDirs += 'src/main/kotlin'
39 | }
40 |
41 | defaultConfig {
42 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
43 | applicationId "com.example.newsly"
44 | minSdkVersion 19
45 | targetSdkVersion 30
46 | multiDexEnabled true
47 | versionCode flutterVersionCode.toInteger()
48 | versionName flutterVersionName
49 | }
50 |
51 | signingConfigs {
52 | release {
53 | keyAlias keystoreProperties['keyAlias']
54 | keyPassword keystoreProperties['keyPassword']
55 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
56 | storePassword keystoreProperties['storePassword']
57 | }
58 | }
59 |
60 | buildTypes {
61 | release {
62 | // TODO: Add your own signing config for the release build.
63 | // Signing with the debug keys for now, so `flutter run --release` works.
64 | // signingConfig signingConfigs.debug
65 | signingConfig signingConfigs.release
66 | }
67 | }
68 | }
69 |
70 | flutter {
71 | source '../..'
72 | }
73 |
74 | dependencies {
75 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
76 | implementation platform('com.google.firebase:firebase-bom:29.0.0')
77 | implementation 'com.google.firebase:firebase-analytics'
78 | implementation "androidx.multidex:multidex:2.0.1"
79 | }
80 |
81 | apply plugin: 'com.google.gms.google-services'
82 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: newsly
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.12.0 <3.0.0"
22 |
23 | dependencies:
24 | animated_splash_screen: ^1.1.0
25 | cloud_firestore: ^3.1.0
26 | cupertino_icons: ^1.0.2
27 | date_field: ^2.1.2
28 | firebase_core: ^1.10.0
29 | firebase_storage: ^10.1.0
30 | flutter:
31 | sdk: flutter
32 | flutter_svg: ^0.22.0
33 | hexcolor: ^2.0.5
34 | http: ^0.13.3
35 | image_picker: ^0.8.4+4
36 | shimmer: ^2.0.0
37 | webview_flutter: ^2.0.13
38 |
39 | dev_dependencies:
40 | flutter_test:
41 | sdk: flutter
42 |
43 | # For information on the generic Dart part of this file, see the
44 | # following page: https://dart.dev/tools/pub/pubspec
45 | # The following section is specific to Flutter.
46 | flutter:
47 |
48 | # The following line ensures that the Material Icons font is
49 | # included with your application, so that you can use the icons in
50 | # the material Icons class.
51 | uses-material-design: true
52 |
53 | # To add assets to your application, add an assets section, like this:
54 | assets:
55 | - images/
56 | # An image asset can refer to one or more resolution-specific "variants", see
57 | # https://flutter.dev/assets-and-images/#resolution-aware.
58 | # For details regarding adding assets from package dependencies, see
59 | # https://flutter.dev/assets-and-images/#from-packages
60 | # To add custom fonts to your application, add a fonts section here,
61 | # in this "flutter" section. Each entry in this list should have a
62 | # "family" key with the font family name, and a "fonts" key with a
63 | # list giving the asset and other descriptors for the font. For
64 | # example:
65 | # fonts:
66 | # - family: Schyler
67 | # fonts:
68 | # - asset: fonts/Schyler-Regular.ttf
69 | # - asset: fonts/Schyler-Italic.ttf
70 | # style: italic
71 | # - family: Trajan Pro
72 | # fonts:
73 | # - asset: fonts/TrajanPro.ttf
74 | # - asset: fonts/TrajanPro_Bold.ttf
75 | # weight: 700
76 | #
77 | # For details regarding fonts from package dependencies,
78 | # see https://flutter.dev/custom-fonts/#from-packages
79 |
--------------------------------------------------------------------------------
/lib/view/widget/shimmerLoading.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:shimmer/shimmer.dart';
3 |
4 | class ShimmerLoadingBreakNews extends StatelessWidget {
5 | const ShimmerLoadingBreakNews({ Key? key }) : super(key: key);
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return Shimmer.fromColors(
10 | baseColor: Colors.grey,
11 | highlightColor: Colors.white70,
12 | child: ListView.builder(
13 | itemCount: 10,
14 | shrinkWrap: true,
15 | scrollDirection: Axis.horizontal,
16 | itemBuilder: (_, __){
17 | return Container(
18 | width: 304,
19 | child: Padding(
20 | padding: const EdgeInsets.only(left: 16),
21 | child: Card(
22 | shape: RoundedRectangleBorder(
23 | borderRadius: BorderRadius.circular(20),
24 | ),
25 | child: Container(
26 | child: Column(
27 | crossAxisAlignment: CrossAxisAlignment.start,
28 | children: [
29 | Container(
30 | height: 144,
31 | margin:
32 | EdgeInsets.only(top: 16, left: 16, right: 16),
33 |
34 | ),
35 | SizedBox(
36 | height: 12,
37 | ),
38 | Container(
39 | height: 70,
40 | margin: EdgeInsets.only(left: 16, right: 16),
41 |
42 | )
43 | ],
44 | ))),
45 | ),
46 | );
47 | },
48 | ),
49 | );
50 | }
51 | }
52 |
53 | class ShimmerLoadingTopHead extends StatelessWidget {
54 | const ShimmerLoadingTopHead({ Key? key }) : super(key: key);
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | return Shimmer.fromColors(
59 | baseColor: Colors.grey,
60 | highlightColor: Colors.white70,
61 | child: ListView.builder(
62 | physics: NeverScrollableScrollPhysics(),
63 | shrinkWrap: true,
64 | itemCount: 10,
65 | reverse: true,
66 | itemBuilder: (context, index) {
67 | return Container(
68 | margin: EdgeInsets.only(left: 16, right: 16, bottom: 12),
69 | height: 120,
70 | child: Card(
71 | child: Row(
72 | children: [
73 | Container(
74 | width: 73,
75 | height: 77,
76 | margin:
77 | EdgeInsets.only(left: 16, top: 16, bottom: 16),
78 |
79 | ),
80 | SizedBox(
81 | width: 16,
82 | ),
83 | Container(
84 | margin: EdgeInsets.only(top: 16, bottom: 16),
85 | width: 206,
86 | )
87 | ],
88 | ),
89 | ),
90 | );
91 | }),
92 | );
93 | }
94 | }
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/lib/view/beranda.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter/material.dart';
3 | import 'package:newsly/view/home.dart';
4 | import 'package:newsly/view/page/articles/articles_page.dart';
5 | import 'package:newsly/view/page/articles/formAddArticle.dart';
6 |
7 | class Beranda extends StatefulWidget {
8 | const Beranda({ Key? key }) : super(key: key);
9 |
10 | @override
11 | _BerandaState createState() => _BerandaState();
12 | }
13 |
14 | class _BerandaState extends State {
15 | int currentTab = 0;
16 | final PageStorageBucket bucket = PageStorageBucket();
17 | Widget currentScreen = Home();
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Scaffold(
22 | body: PageStorage(bucket: bucket,child: currentScreen,),
23 | floatingActionButton: FloatingActionButton(
24 | onPressed: () {
25 | Navigator.push(context, MaterialPageRoute(builder: (context)=> FormAddArticle()));
26 | },
27 | child: Icon(Icons.note_add),
28 | ),
29 | floatingActionButtonLocation:
30 | FloatingActionButtonLocation.centerDocked,
31 | bottomNavigationBar: BottomAppBar(
32 | elevation: 16,
33 | shape: CircularNotchedRectangle(),
34 | notchMargin: 5,
35 | child: Container(
36 | height: 60,
37 | child: Row(
38 | mainAxisAlignment: MainAxisAlignment.spaceAround,
39 | children: [
40 | MaterialButton(
41 | onPressed: () {
42 | setState(
43 | () {
44 | currentScreen = Home();
45 | currentTab = 0;
46 | },
47 | );
48 | },
49 | child: Column(
50 | mainAxisAlignment: MainAxisAlignment.center,
51 | children: [
52 | Icon(
53 | Icons.home,
54 | color: currentTab == 0 ? Colors.blue : Colors.grey,
55 | ),
56 | Text(
57 | "Home",
58 | style: TextStyle(
59 | color:
60 | currentTab == 0 ? Colors.blue : Colors.grey),
61 | )
62 | ],
63 | ),
64 | ),
65 | MaterialButton(
66 | onPressed: () {
67 | setState(() {
68 | currentScreen = ArticlesPage();
69 | currentTab = 1;
70 | });
71 | },
72 | child: Column(
73 | mainAxisAlignment: MainAxisAlignment.center,
74 | children: [
75 | Icon(
76 | Icons.article,
77 | color: currentTab == 1
78 | ? Colors.blue
79 | : Colors.grey,
80 | ),
81 | Text(
82 | "Articles",
83 | style: TextStyle(
84 | color: currentTab == 1
85 | ? Colors.blue
86 | : Colors.grey),
87 | )
88 | ],
89 | ),
90 | )
91 | ],
92 | ),
93 | ),
94 | ),
95 | );
96 | }
97 | }
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | newsly
27 |
28 |
29 |
30 |
33 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/lib/view/widget/card_widget.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:hexcolor/hexcolor.dart';
5 | import 'package:newsly/view/detailNews.dart';
6 | import 'package:newsly/view/widget/dialog_widget.dart';
7 |
8 | class ItemCard extends StatelessWidget {
9 | String title;
10 | String published;
11 | String author;
12 | String urlArtikel;
13 | String description;
14 | String image;
15 | String id;
16 |
17 | ItemCard(
18 | {Key? key,
19 | required this.author,
20 | required this.title,
21 | required this.published,
22 | required this.description,
23 | required this.image,
24 | required this.urlArtikel,
25 | required this.id})
26 | : super(key: key);
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return GestureDetector(
31 | onTap: () {
32 | Navigator.push(
33 | context,
34 | MaterialPageRoute(
35 | builder: (contex) => DetailNews(
36 | source: author,
37 | url: urlArtikel,
38 | )));
39 | },
40 | onLongPress: () {
41 | showDialog(
42 | context: context,
43 | builder: (context) {
44 | return DetailDialog(
45 | image: image,
46 | author: author,
47 | published: published,
48 | title: title,
49 | description: description,
50 | id: id,
51 | urlArtikel: urlArtikel,
52 | );
53 | });
54 | },
55 | child: Container(
56 | width: double.infinity,
57 | child: Padding(
58 | padding: const EdgeInsets.only(left: 8.0, right: 8.0),
59 | child: Card(
60 | elevation: 1,
61 | shadowColor: Colors.blue,
62 | shape: RoundedRectangleBorder(
63 | borderRadius: BorderRadius.circular(8.0),
64 | ),
65 | child: Container(
66 | child: Column(
67 | crossAxisAlignment: CrossAxisAlignment.start,
68 | children: [
69 | Container(
70 | height: 160,
71 | width: double.infinity,
72 | margin: EdgeInsets.only(top: 16, left: 16, right: 16),
73 | child: ClipRRect(
74 | borderRadius: BorderRadius.circular(12.0),
75 | child: Image.network(
76 | image,
77 | fit: BoxFit.cover,
78 | )),
79 | ),
80 | SizedBox(
81 | height: 12,
82 | ),
83 | Container(
84 | height: 70,
85 | margin: EdgeInsets.only(left: 16, right: 16),
86 | child: Column(
87 | crossAxisAlignment: CrossAxisAlignment.start,
88 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
89 | children: [
90 | Text(
91 | title,
92 | maxLines: 3,
93 | overflow: TextOverflow.ellipsis,
94 | style: TextStyle(
95 | fontSize: 14,
96 | fontWeight: FontWeight.bold,
97 | color: HexColor('#4E3A55')),
98 | ),
99 | Padding(
100 | padding: const EdgeInsets.only(bottom: 12.0),
101 | child: Text(
102 | published,
103 | style: TextStyle(
104 | fontSize: 14, color: HexColor('#999CA0')),
105 | ),
106 | )
107 | ],
108 | ),
109 | )
110 | ],
111 | ))),
112 | ),
113 | ),
114 | );
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/lib/view/home.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:newsly/view/page/business/businessNews.dart';
5 | import 'package:newsly/view/drawer.dart';
6 | import 'package:newsly/view/page/general/generalNews.dart';
7 | import 'package:newsly/view/page/health/healthNews.dart';
8 | import 'package:newsly/view/page/sport/sportNews.dart';
9 | import 'package:newsly/view/page/technology/technologyNews.dart';
10 |
11 | class Home extends StatefulWidget {
12 | Home({Key? key}) : super(key: key);
13 |
14 | @override
15 | State createState() => _HomeState();
16 | }
17 |
18 | class _HomeState extends State {
19 | @override
20 | Widget build(BuildContext context) {
21 | // NewsList news = NewsList();
22 | // NewsHeadlines newsHeadlines = NewsHeadlines();
23 | Widget _bagianTabBar = TabBar(
24 | isScrollable: true,
25 | unselectedLabelColor: Colors.blue,
26 | indicatorSize: TabBarIndicatorSize.tab,
27 | indicator: BoxDecoration(
28 | borderRadius: BorderRadius.circular(50), color: Colors.blue),
29 | tabs: [
30 | Tab(
31 | child: Container(
32 | decoration: BoxDecoration(
33 | borderRadius: BorderRadius.circular(50),
34 | //border: Border.all(color: Colors.blue)
35 | ),
36 | child: Align(
37 | alignment: Alignment.center,
38 | child: Padding(
39 | padding: const EdgeInsets.only(left: 12, right: 12),
40 | child: Text("General"),
41 | ),
42 | ),
43 | ),
44 | ),
45 | Tab(
46 | child: Container(
47 | decoration: BoxDecoration(
48 | borderRadius: BorderRadius.circular(50),
49 | //border: Border.all(color: Colors.blue)
50 | ),
51 | child: Align(
52 | alignment: Alignment.center,
53 | child: Padding(
54 | padding: const EdgeInsets.only(left: 12, right: 12),
55 | child: Text("Technology"),
56 | ),
57 | ),
58 | ),
59 | ),
60 | Tab(
61 | child: Container(
62 | decoration: BoxDecoration(
63 | borderRadius: BorderRadius.circular(50),
64 | //border: Border.all(color: Colors.blue)
65 | ),
66 | child: Align(
67 | alignment: Alignment.center,
68 | child: Padding(
69 | padding: const EdgeInsets.only(left: 12, right: 12),
70 | child: Text("Business"),
71 | ),
72 | ),
73 | ),
74 | ),
75 | Tab(
76 | child: Container(
77 | decoration: BoxDecoration(
78 | borderRadius: BorderRadius.circular(50),
79 | //border: Border.all(color: Colors.blue)
80 | ),
81 | child: Align(
82 | alignment: Alignment.center,
83 | child: Padding(
84 | padding: const EdgeInsets.only(left: 12, right: 12),
85 | child: Text("Health"),
86 | ),
87 | ),
88 | ),
89 | ),
90 | Tab(
91 | child: Container(
92 | decoration: BoxDecoration(
93 | borderRadius: BorderRadius.circular(50),
94 | //border: Border.all(color: Colors.blue)
95 | ),
96 | child: Align(
97 | alignment: Alignment.center,
98 | child: Padding(
99 | padding: const EdgeInsets.only(left: 12, right: 12),
100 | child: Text("Sport"),
101 | ),
102 | ),
103 | ),
104 | ),
105 | ]);
106 |
107 | return DefaultTabController(
108 | length: 5,
109 | child: Scaffold(
110 | appBar: AppBar(
111 | title: Center(
112 | child: Text(
113 | 'Newsly',
114 | style: TextStyle(
115 | fontWeight: FontWeight.bold, color: Colors.blue[700]),
116 | )),
117 | backgroundColor: Colors.white,
118 | iconTheme: IconThemeData(color: Colors.black),
119 | elevation: 0,
120 | bottom: PreferredSize(
121 | preferredSize: new Size(200.0, 52),
122 | child: Container(
123 | margin: EdgeInsets.only(left: 16, right: 16),
124 | child: _bagianTabBar),
125 | ),
126 | actions: [
127 | Container(
128 | margin: EdgeInsets.only(right: 0),
129 | child: IconButton(
130 | onPressed: () {},
131 | icon: Image.asset('images/icon_user.png')),
132 | )
133 | ],
134 | ),
135 | backgroundColor: Colors.white,
136 | drawer: DrawerMenu(),
137 | body: TabBarView(
138 | children: [
139 | GeneralNews(),
140 | TechnologyNews(),
141 | BusinessNews(),
142 | HealthNews(),
143 | SportNews()
144 | ],
145 | )));
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/lib/view/widget/dialog_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:newsly/view/page/articles/articles_page.dart';
3 | import 'package:newsly/view/page/articles/formUpdateArticle.dart';
4 | import 'package:newsly/viewmodel/service/firestore_service.dart';
5 |
6 | class DetailDialog extends StatelessWidget {
7 | String? image;
8 | String? title;
9 | String? author;
10 | String? published;
11 | String? description;
12 | String? id;
13 | String? urlArtikel;
14 |
15 | DetailDialog(
16 | {Key? key,
17 | this.image,
18 | this.title,
19 | this.author,
20 | this.published,
21 | this.description,
22 | this.id,
23 | this.urlArtikel})
24 | : super(key: key);
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return SimpleDialog(
29 | elevation: 4,
30 | shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
31 | children: [
32 | Container(
33 | margin: EdgeInsets.only(right: 16, left: 16, top: 6),
34 | child: Column(
35 | crossAxisAlignment: CrossAxisAlignment.start,
36 | children: [
37 | Container(
38 | height: 180,
39 | width: double.infinity,
40 | child: ClipRRect(
41 | borderRadius: BorderRadius.circular(8.0),
42 | child: Image.network(
43 | image!,
44 | fit: BoxFit.cover,
45 | ),
46 | ),
47 | ),
48 | SizedBox(
49 | height: 16,
50 | ),
51 | Text(
52 | title!,
53 | style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
54 | ),
55 | SizedBox(
56 | height: 8.0,
57 | ),
58 | Row(
59 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
60 | children: [
61 | Row(
62 | children: [
63 | Image.asset(
64 | 'images/icon_user.png',
65 | height: 24,
66 | width: 24,
67 | ),
68 | SizedBox(
69 | width: 12,
70 | ),
71 | Text(
72 | author!,
73 | style: TextStyle(color: Colors.grey),
74 | )
75 | ],
76 | ),
77 | Text(published!, style: TextStyle(color: Colors.grey)),
78 | ],
79 | ),
80 | SizedBox(
81 | height: 16,
82 | ),
83 | Text(description!),
84 | SizedBox(
85 | height: 16,
86 | ),
87 | Row(
88 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
89 | children: [
90 | Row(
91 | children: [
92 | TextButton(
93 | onPressed: () {
94 | Navigator.pushReplacement(
95 | context,
96 | MaterialPageRoute(
97 | builder: (_) => FormUpdateArticle(
98 | id: id!,
99 | author: author!,
100 | date: published!,
101 | deskripsi: description!,
102 | image: image!,
103 | title: title!,
104 | urlArtikel: urlArtikel!)));
105 | },
106 | child: Text(
107 | "Update",
108 | style: TextStyle(color: Colors.green),
109 | )),
110 | SizedBox(
111 | width: 4.0,
112 | ),
113 | TextButton(
114 | onPressed: () {
115 | Navigator.of(context).pop();
116 | FirestoreService.deleteItem(id: id!)
117 | .then((value) => showDialog(
118 | context: context,
119 | builder: (context) {
120 | return AlertDialog(
121 | title: Text("Data Berhasil Dihapus"),
122 | actions: [
123 | TextButton(
124 | onPressed: () {
125 | Navigator.pushReplacement(
126 | context,
127 | MaterialPageRoute(
128 | builder: (context) =>
129 | ArticlesPage()));
130 | },
131 | child: Text("OK"))
132 | ],
133 | );
134 | }));
135 | },
136 | child: Text(
137 | "Delete",
138 | style: TextStyle(color: Colors.red),
139 | )),
140 | ],
141 | ),
142 | TextButton(
143 | onPressed: () {},
144 | child: Text(
145 | "Close",
146 | style: TextStyle(color: Colors.grey),
147 | )),
148 | ],
149 | )
150 | ],
151 | ),
152 | ),
153 | ]);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/lib/view/widget/newsList.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hexcolor/hexcolor.dart';
3 | import 'package:newsly/model/news.dart';
4 | import 'package:newsly/view/detailNews.dart';
5 |
6 | class BreakNewsList extends StatelessWidget {
7 | const BreakNewsList({ Key? key, required this.news }) : super(key: key);
8 |
9 | final List news;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return ListView.builder(
14 | itemCount: news.length,
15 | shrinkWrap: true,
16 | scrollDirection: Axis.horizontal,
17 | itemBuilder: (context, index){
18 | return GestureDetector(
19 | onTap: () {
20 | Navigator.push(
21 | context,
22 | MaterialPageRoute(
23 | builder: (contex) => DetailNews(
24 | author: news[index].author,
25 | title: news[index].title,
26 | image: news[index].image,
27 | published: news[index].published,
28 | content: news[index].content,
29 | url: news[index].url,
30 | source: news[index].source,
31 | )));
32 | },
33 | child: Container(
34 | width: 304,
35 | child: Padding(
36 | padding: const EdgeInsets.only(left: 16),
37 | child: Card(
38 | shape: RoundedRectangleBorder(
39 | borderRadius: BorderRadius.circular(20),
40 | ),
41 | child: Container(
42 | child: Column(
43 | crossAxisAlignment: CrossAxisAlignment.start,
44 | children: [
45 | Container(
46 | height: 144,
47 | margin:
48 | EdgeInsets.only(top: 16, left: 16, right: 16),
49 | child: ClipRRect(
50 | borderRadius: BorderRadius.circular(12.0),
51 | child: Image.network(
52 | news[index].image,
53 | fit: BoxFit.cover,
54 | )),
55 | ),
56 | SizedBox(
57 | height: 12,
58 | ),
59 | Container(
60 | height: 70,
61 | margin: EdgeInsets.only(left: 16, right: 16),
62 | child: Column(
63 | crossAxisAlignment: CrossAxisAlignment.start,
64 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
65 | children: [
66 | Text(
67 | news[index].title,
68 | maxLines: 3,
69 | overflow: TextOverflow.ellipsis,
70 | style: TextStyle(
71 | fontSize: 14,
72 | fontWeight: FontWeight.bold,
73 | color: HexColor('#4E3A55')),
74 | ),
75 |
76 | Text(
77 | news[index].published,
78 | style: TextStyle(
79 | fontSize: 14, color: HexColor('#999CA0')),
80 | )
81 | ],
82 | ),
83 | )
84 | ],
85 | ))),
86 | ),
87 | ),
88 | );
89 | },
90 | );
91 | }
92 | }
93 |
94 | class TopHeadlinesList extends StatelessWidget {
95 | const TopHeadlinesList({ Key? key, required this.news }) : super(key: key);
96 |
97 | final List news;
98 |
99 |
100 | @override
101 | Widget build(BuildContext context) {
102 |
103 | return Flexible(
104 | child: ListView.builder(
105 | physics: NeverScrollableScrollPhysics(),
106 | shrinkWrap: true,
107 | itemCount: news.length,
108 | reverse: true,
109 | itemBuilder: (context, index) {
110 | return GestureDetector(
111 | onTap: () {
112 | Navigator.push(
113 | context,
114 | MaterialPageRoute(
115 | builder: (contex) => DetailNews(
116 | author: news[index].author,
117 | title: news[index].title,
118 | image: news[index].image,
119 | published: news[index].published,
120 | content: news[index].content,
121 | url: news[index].url,
122 | source: news[index].source,
123 | )));
124 | },
125 | child: Container(
126 | margin: EdgeInsets.only(left: 16, right: 16, bottom: 12),
127 | height: 120,
128 | child: Card(
129 | child: Row(
130 | children: [
131 | Container(
132 | width: 73,
133 | height: 77,
134 | margin:
135 | EdgeInsets.only(left: 16, top: 16, bottom: 16),
136 | child: ClipRRect(
137 | borderRadius: BorderRadius.circular(4.0),
138 | child: Image.network(
139 | news[index].image,
140 | fit: BoxFit.cover,
141 | ),
142 | ),
143 | ),
144 | SizedBox(
145 | width: 16,
146 | ),
147 | Container(
148 | margin: EdgeInsets.only(top: 16, bottom: 16),
149 | width: 206,
150 | child: Column(
151 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
152 | crossAxisAlignment: CrossAxisAlignment.start,
153 | children: [
154 | Text(
155 | news[index].title,
156 | maxLines: 3,
157 | overflow: TextOverflow.ellipsis,
158 | style: TextStyle(
159 | fontWeight: FontWeight.bold,
160 | color: HexColor('#4E3A55')),
161 | ),
162 |
163 | Text(
164 | news[index].content,
165 | maxLines: 2,
166 | overflow: TextOverflow.ellipsis,
167 | style: TextStyle(
168 | color: HexColor('#999CA0'),
169 | fontSize: 12
170 | ),
171 | )
172 | ],
173 | ))
174 | ],
175 | ),
176 | ),
177 | ),
178 | );
179 | }),
180 | );
181 | }
182 | }
--------------------------------------------------------------------------------
/lib/view/page/articles/articles_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:cloud_firestore/cloud_firestore.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:newsly/view/drawer.dart';
4 | import 'package:newsly/view/widget/card_widget.dart';
5 | import 'package:shimmer/shimmer.dart';
6 |
7 | class ArticlesPage extends StatelessWidget {
8 | ArticlesPage({
9 | Key? key,
10 | }) : super(key: key);
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | FirebaseFirestore _firestore = FirebaseFirestore.instance;
15 | CollectionReference _articles = _firestore.collection('articles');
16 |
17 | return Scaffold(
18 | appBar: AppBar(
19 | title: Text(
20 | "Articles",
21 | style:
22 | TextStyle(color: Colors.blue[700], fontWeight: FontWeight.bold),
23 | ),
24 | centerTitle: true,
25 | elevation: 0,
26 | iconTheme: IconThemeData(color: Colors.black),
27 | backgroundColor: Colors.white,
28 | actions: [
29 | Container(
30 | margin: EdgeInsets.only(right: 0),
31 | child: IconButton(
32 | onPressed: () {}, icon: Image.asset('images/icon_user.png')),
33 | )
34 | ],
35 | ),
36 | backgroundColor: Colors.white,
37 | body: Container(
38 | child: ListView(
39 | children: [
40 | StreamBuilder(
41 | stream: _articles.snapshots(),
42 | builder: (_, snapshot) {
43 | if (snapshot.hasData) {
44 | return Column(
45 | children: snapshot.data!.docs
46 | .map((DocumentSnapshot document) {
47 | Map data =
48 | document.data() as Map;
49 | return ItemCard(
50 | author: data['author'],
51 | title: data['title'],
52 | published: data['published'],
53 | description: data['description'],
54 | image: data['image'],
55 | urlArtikel: data['url'],
56 | id: document.id,
57 | );
58 | }).toList());
59 | } else {
60 | return Shimmer.fromColors(
61 | baseColor: Colors.grey,
62 | highlightColor: Colors.white70,
63 | child: Column(
64 | children: [
65 | Container(
66 | width: double.infinity,
67 | child: Padding(
68 | padding:
69 | const EdgeInsets.only(left: 8.0, right: 8.0),
70 | child: Card(
71 | elevation: 1,
72 | shadowColor: Colors.blue,
73 | shape: RoundedRectangleBorder(
74 | borderRadius: BorderRadius.circular(8.0),
75 | ),
76 | child: Container(
77 | child: Column(
78 | crossAxisAlignment:
79 | CrossAxisAlignment.start,
80 | children: [
81 | Container(
82 | height: 160,
83 | width: double.infinity,
84 | margin: EdgeInsets.only(
85 | top: 16, left: 16, right: 16),
86 | ),
87 | SizedBox(
88 | height: 12,
89 | ),
90 | Container(
91 | height: 70,
92 | margin: EdgeInsets.only(
93 | left: 16, right: 16),
94 | )
95 | ],
96 | ))),
97 | ),
98 | ),
99 | Container(
100 | width: double.infinity,
101 | child: Padding(
102 | padding:
103 | const EdgeInsets.only(left: 8.0, right: 8.0),
104 | child: Card(
105 | elevation: 1,
106 | shadowColor: Colors.blue,
107 | shape: RoundedRectangleBorder(
108 | borderRadius: BorderRadius.circular(8.0),
109 | ),
110 | child: Container(
111 | child: Column(
112 | crossAxisAlignment:
113 | CrossAxisAlignment.start,
114 | children: [
115 | Container(
116 | height: 160,
117 | width: double.infinity,
118 | margin: EdgeInsets.only(
119 | top: 16, left: 16, right: 16),
120 | ),
121 | SizedBox(
122 | height: 12,
123 | ),
124 | Container(
125 | height: 70,
126 | margin: EdgeInsets.only(
127 | left: 16, right: 16),
128 | )
129 | ],
130 | ))),
131 | ),
132 | ),
133 | Container(
134 | width: double.infinity,
135 | child: Padding(
136 | padding:
137 | const EdgeInsets.only(left: 8.0, right: 8.0),
138 | child: Card(
139 | elevation: 1,
140 | shadowColor: Colors.blue,
141 | shape: RoundedRectangleBorder(
142 | borderRadius: BorderRadius.circular(8.0),
143 | ),
144 | child: Container(
145 | child: Column(
146 | crossAxisAlignment:
147 | CrossAxisAlignment.start,
148 | children: [
149 | Container(
150 | height: 160,
151 | width: double.infinity,
152 | margin: EdgeInsets.only(
153 | top: 16, left: 16, right: 16),
154 | ),
155 | SizedBox(
156 | height: 12,
157 | ),
158 | Container(
159 | height: 70,
160 | margin: EdgeInsets.only(
161 | left: 16, right: 16),
162 | )
163 | ],
164 | ))),
165 | ),
166 | )
167 | ]
168 | ));
169 | }
170 | })
171 | ],
172 | ),
173 | ),
174 | drawer: DrawerMenu(),
175 | );
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/lib/view/page/articles/formAddArticle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:cloud_firestore/cloud_firestore.dart';
4 | import 'package:firebase_storage/firebase_storage.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:hexcolor/hexcolor.dart';
7 | import 'package:image_picker/image_picker.dart';
8 | import 'package:date_field/date_field.dart';
9 | import 'package:intl/intl.dart';
10 | import 'package:newsly/viewmodel/service/firestore_service.dart';
11 |
12 | class FormAddArticle extends StatefulWidget {
13 | FormAddArticle({Key? key}) : super(key: key);
14 |
15 | @override
16 | State createState() => _FormAddArticleState();
17 | }
18 |
19 | class _FormAddArticleState extends State {
20 | TextEditingController _controllerTitle = new TextEditingController();
21 | TextEditingController _controllerAuthor = new TextEditingController();
22 | TextEditingController _controllerUrl = new TextEditingController();
23 | TextEditingController _controllerDeskripsi = new TextEditingController();
24 |
25 | String _title = '';
26 | String _date = '';
27 | String _author = '';
28 | String _urlArtikel = '';
29 | String _deskripsi = '';
30 |
31 | XFile? image;
32 | String? namaGamber;
33 | final ImagePicker _picker = ImagePicker();
34 |
35 | Future chooseImage() async {
36 | XFile? selectedImage = await _picker.pickImage(source: ImageSource.gallery);
37 | setState(() {
38 | image = selectedImage;
39 | namaGamber = image!.name;
40 | });
41 | }
42 |
43 | Widget showImage() {
44 | return image == null
45 | ? Container(
46 | width: double.infinity,
47 | height: 150,
48 | decoration: BoxDecoration(
49 | color: HexColor("#F5F5F5"),
50 | borderRadius: BorderRadius.circular(8.0)),
51 | child: Center(
52 | child: Icon(
53 | Icons.add_photo_alternate_outlined,
54 | size: 40,
55 | color: Colors.grey,
56 | )))
57 | : uploadArea();
58 | }
59 |
60 | Future uploadItemImage() async {
61 | Reference ref = FirebaseStorage.instance.ref().child(namaGamber!);
62 |
63 | UploadTask uploadTask = ref.putFile(File(image!.path));
64 |
65 | var downUrl = await uploadTask.then((res) => res.ref.getDownloadURL());
66 | var url = downUrl.toString();
67 |
68 | print("Download URL : " + url);
69 |
70 | tambahItem(url);
71 |
72 | return url != null ? "upload sukses" : "Upload gagal";
73 | }
74 |
75 | @override
76 | Widget build(BuildContext context) {
77 | return Scaffold(
78 | appBar: AppBar(
79 | title: Text(
80 | "Add Article",
81 | style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
82 | ),
83 | centerTitle: true,
84 | backgroundColor: Colors.white,
85 | iconTheme: IconThemeData(color: Colors.black),
86 | elevation: 0,
87 | ),
88 | backgroundColor: Colors.white,
89 | body: Container(
90 | padding: EdgeInsets.all(20.0),
91 | child: ListView(
92 | children: [
93 | GestureDetector(
94 | onTap: () {
95 | chooseImage();
96 | },
97 | child: showImage(),
98 | ),
99 | SizedBox(
100 | height: 20,
101 | ),
102 | TextField(
103 | controller: _controllerTitle,
104 | decoration: InputDecoration(
105 | hintText: "Judul Artikel",
106 | labelText: "Judul Artikel",
107 | border: OutlineInputBorder(
108 | borderRadius: BorderRadius.circular(8.0))),
109 | ),
110 | SizedBox(
111 | height: 16,
112 | ),
113 | TextField(
114 | controller: _controllerAuthor,
115 | decoration: InputDecoration(
116 | hintText: "Author",
117 | labelText: "Author",
118 | border: OutlineInputBorder(
119 | borderRadius: BorderRadius.circular(8.0))),
120 | ),
121 | SizedBox(
122 | height: 16,
123 | ),
124 | DateTimeFormField(
125 | decoration: InputDecoration(
126 | hintText: "Date",
127 | labelText: "Date",
128 | prefixIcon: Icon(Icons.date_range_outlined),
129 | border: OutlineInputBorder(
130 | borderRadius: BorderRadius.circular(8.0))),
131 | mode: DateTimeFieldPickerMode.date,
132 | dateFormat: DateFormat("yyyy-MM-dd"),
133 | onDateSelected: (DateTime value) {
134 | setState(() {
135 | String formatDate = DateFormat("yyyy-MM-dd").format(value);
136 | _date = formatDate;
137 | });
138 | },
139 | ),
140 | SizedBox(
141 | height: 16,
142 | ),
143 | TextField(
144 | controller: _controllerUrl,
145 | decoration: InputDecoration(
146 | hintText: "Url Artikel",
147 | labelText: "Url Artikel",
148 | border: OutlineInputBorder(
149 | borderRadius: BorderRadius.circular(8.0))),
150 | ),
151 | SizedBox(
152 | height: 16,
153 | ),
154 | TextField(
155 | maxLines: 8,
156 | controller: _controllerDeskripsi,
157 | decoration: InputDecoration(
158 | hintText: "Deskripsi",
159 | labelText: "Deskripsi",
160 | border: OutlineInputBorder(
161 | borderRadius: BorderRadius.circular(8.0))),
162 | ),
163 | SizedBox(
164 | height: 16,
165 | ),
166 | MaterialButton(
167 | onPressed: () {
168 | _title = _controllerTitle.text;
169 | _author = _controllerAuthor.text;
170 | _urlArtikel = _controllerUrl.text;
171 | _deskripsi = _controllerDeskripsi.text;
172 |
173 | uploadItemImage();
174 |
175 | setState(() {
176 | _controllerTitle.clear();
177 | _controllerAuthor.clear();
178 | _controllerDeskripsi.clear();
179 | _controllerUrl.clear();
180 | image = null;
181 | });
182 | },
183 | color: Colors.blue,
184 | textColor: Colors.white,
185 | child: Text("Submit"),
186 | minWidth: double.infinity,
187 | padding: EdgeInsets.only(top: 14, bottom: 14),
188 | shape: RoundedRectangleBorder(
189 | borderRadius: BorderRadius.circular(8)),
190 | )
191 | ],
192 | )),
193 | );
194 | }
195 |
196 | Future tambahItem(String url) {
197 | FirebaseFirestore _firestore = FirebaseFirestore.instance;
198 | CollectionReference _articles = _firestore.collection('articles');
199 |
200 | return FirestoreService.addItem(
201 | title: _title,
202 | author: _author,
203 | published: _date,
204 | urlArticle: _urlArtikel,
205 | description: _deskripsi,
206 | image: url,
207 | id: _articles.doc().id)
208 | .then((value) => showDialog(
209 | context: context,
210 | builder: (context) {
211 | return AlertDialog(
212 | title: Text("Data Berhasil Ditambahkan"),
213 | actions: [
214 | TextButton(
215 | onPressed: () {
216 | Navigator.of(context).pop();
217 | },
218 | child: Text("OK"))
219 | ],
220 | );
221 | }));
222 | }
223 |
224 | Widget uploadArea() {
225 | return Container(
226 | height: 150,
227 | child: ClipRRect(
228 | child: Image.file(
229 | File(image!.path),
230 | fit: BoxFit.cover,
231 | ),
232 | borderRadius: BorderRadius.circular(8.0),
233 | ),
234 | decoration: BoxDecoration(borderRadius: BorderRadius.circular(8.0)),
235 | );
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/lib/view/page/articles/formUpdateArticle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:date_field/date_field.dart';
4 | import 'package:firebase_storage/firebase_storage.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:image_picker/image_picker.dart';
7 | import 'package:newsly/view/page/articles/articles_page.dart';
8 | import 'package:newsly/viewmodel/service/firestore_service.dart';
9 | import 'package:intl/intl.dart';
10 |
11 | class FormUpdateArticle extends StatefulWidget {
12 | String id;
13 | String title = '';
14 | String date = '';
15 | String author = '';
16 | String urlArtikel = '';
17 | String deskripsi = '';
18 | String image = '';
19 |
20 | FormUpdateArticle(
21 | {Key? key,
22 | required this.id,
23 | required this.author,
24 | required this.date,
25 | required this.deskripsi,
26 | required this.image,
27 | required this.title,
28 | required this.urlArtikel})
29 | : super(key: key);
30 |
31 | @override
32 | _FormUpdateArticleState createState() => _FormUpdateArticleState(
33 | id: id,
34 | date: date,
35 | author: author,
36 | gambar: image,
37 | deskripsi: deskripsi,
38 | title: title,
39 | urlArtikel: urlArtikel);
40 | }
41 |
42 | class _FormUpdateArticleState extends State {
43 | String title;
44 | String date;
45 | String author;
46 | String urlArtikel;
47 | String deskripsi;
48 | String id;
49 | String gambar;
50 |
51 | _FormUpdateArticleState(
52 | {required this.id,
53 | required this.date,
54 | required this.author,
55 | required this.gambar,
56 | required this.deskripsi,
57 | required this.title,
58 | required this.urlArtikel});
59 |
60 | DateTime? tgl;
61 | TextEditingController? _controllerTitle;
62 | TextEditingController? _controllerAuthor;
63 | TextEditingController? _controllerUrl;
64 | TextEditingController? _controllerDeskripsi;
65 |
66 | void initState() {
67 | super.initState();
68 | _controllerTitle = new TextEditingController()..text = title;
69 | _controllerAuthor = new TextEditingController()..text = author;
70 | _controllerDeskripsi = new TextEditingController()..text = deskripsi;
71 | _controllerUrl = new TextEditingController()..text = urlArtikel;
72 | tgl = DateTime.parse(date);
73 | }
74 |
75 | XFile? image;
76 | String? namaGambar;
77 | final ImagePicker _picker = ImagePicker();
78 |
79 | Future chooseImage() async {
80 | XFile? selectedImage = await _picker.pickImage(source: ImageSource.gallery);
81 | setState(() {
82 | image = selectedImage;
83 | namaGambar = image!.name;
84 | });
85 | }
86 |
87 | Future uploadItemImage() async {
88 | var url;
89 | if (image == null) {
90 | url = gambar;
91 | } else {
92 | Reference ref = FirebaseStorage.instance.ref().child(namaGambar!);
93 |
94 | UploadTask uploadTask = ref.putFile(File(image!.path));
95 |
96 | var downUrl = await uploadTask.then((res) => res.ref.getDownloadURL());
97 | url = downUrl.toString();
98 | }
99 | print("Download URL : " + url);
100 |
101 | updateItem(url);
102 |
103 | return url != null ? "upload sukses" : "Upload gagal";
104 | }
105 |
106 | Widget showImage() {
107 | return image == null ? uploadAreaID() : uploadArea();
108 | }
109 |
110 | @override
111 | Widget build(BuildContext context) {
112 | return Scaffold(
113 | appBar: AppBar(
114 | title: Text(
115 | "Update Article",
116 | style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
117 | ),
118 | centerTitle: true,
119 | backgroundColor: Colors.white,
120 | iconTheme: IconThemeData(color: Colors.black),
121 | elevation: 0,
122 | ),
123 | backgroundColor: Colors.white,
124 | body: Container(
125 | padding: EdgeInsets.all(20.0),
126 | child: ListView(
127 | children: [
128 | GestureDetector(
129 | onTap: () {
130 | chooseImage();
131 | },
132 | child: showImage(),
133 | ),
134 | SizedBox(
135 | height: 20,
136 | ),
137 | TextField(
138 | controller: _controllerTitle,
139 | decoration: InputDecoration(
140 | hintText: "Judul Artikel",
141 | labelText: "Judul Artikel",
142 | border: OutlineInputBorder(
143 | borderRadius: BorderRadius.circular(8.0))),
144 | ),
145 | SizedBox(
146 | height: 16,
147 | ),
148 | TextField(
149 | controller: _controllerAuthor,
150 | decoration: InputDecoration(
151 | hintText: "Author",
152 | labelText: "Author",
153 | border: OutlineInputBorder(
154 | borderRadius: BorderRadius.circular(8.0))),
155 | ),
156 | SizedBox(
157 | height: 16,
158 | ),
159 | DateTimeFormField(
160 | decoration: InputDecoration(
161 | hintText: "Date",
162 | labelText: "Date",
163 | prefixIcon: Icon(Icons.date_range_outlined),
164 | border: OutlineInputBorder(
165 | borderRadius: BorderRadius.circular(8.0))),
166 | mode: DateTimeFieldPickerMode.date,
167 | dateFormat: DateFormat("yyyy-MM-dd"),
168 | initialValue: tgl,
169 | onDateSelected: (DateTime value) {
170 | setState(() {
171 | String formatDate = DateFormat("yyyy-MM-dd").format(value);
172 | date = formatDate;
173 | });
174 | },
175 | ),
176 | SizedBox(
177 | height: 16,
178 | ),
179 | TextField(
180 | controller: _controllerUrl,
181 | decoration: InputDecoration(
182 | hintText: "Url Artikel",
183 | labelText: "Url Artikel",
184 | border: OutlineInputBorder(
185 | borderRadius: BorderRadius.circular(8.0))),
186 | ),
187 | SizedBox(
188 | height: 16
189 | ),
190 | TextField(
191 | maxLines: 8,
192 | controller: _controllerDeskripsi,
193 | decoration: InputDecoration(
194 | hintText: "Deskripsi",
195 | labelText: "Deskripsi",
196 | border: OutlineInputBorder(
197 | borderRadius: BorderRadius.circular(8.0))),
198 | ),
199 | SizedBox(
200 | height: 16,
201 | ),
202 | MaterialButton(
203 | onPressed: () {
204 | title = _controllerTitle!.text;
205 | author = _controllerAuthor!.text;
206 | urlArtikel = _controllerUrl!.text;
207 | deskripsi = _controllerDeskripsi!.text;
208 |
209 | Navigator.pushReplacement(context,
210 | MaterialPageRoute(builder: (context) => ArticlesPage()));
211 |
212 | uploadItemImage().then((value) => showDialog(
213 | context: context,
214 | builder: (context) {
215 | return AlertDialog(
216 | title: Text("Data Berhasil Diupdate"),
217 | actions: [
218 | TextButton(
219 | onPressed: () {
220 | Navigator.pop(context, 'OK');
221 | },
222 | child: Text("OK"))
223 | ],
224 | );
225 | }));
226 |
227 |
228 | setState(() {
229 | _controllerTitle!.clear();
230 | _controllerAuthor!.clear();
231 | _controllerDeskripsi!.clear();
232 | _controllerUrl!.clear();
233 | image = null;
234 | });
235 | },
236 | color: Colors.blue,
237 | textColor: Colors.white,
238 | child: Text("Update"),
239 | minWidth: double.infinity,
240 | padding: EdgeInsets.only(top: 14, bottom: 14),
241 | shape: RoundedRectangleBorder(
242 | borderRadius: BorderRadius.circular(8)),
243 | )
244 | ],
245 | )),
246 | );
247 | }
248 |
249 | Future updateItem(String url) {
250 | return FirestoreService.updateItem(
251 | title: title,
252 | author: author,
253 | published: date,
254 | urlArticle: urlArtikel,
255 | description: deskripsi,
256 | image: url,
257 | id: id);
258 | }
259 |
260 | Widget uploadArea() {
261 | return Container(
262 | height: 150,
263 | child: ClipRRect(
264 | child: Image.file(
265 | File(image!.path),
266 | fit: BoxFit.cover,
267 | ),
268 | borderRadius: BorderRadius.circular(8.0),
269 | ),
270 | decoration: BoxDecoration(borderRadius: BorderRadius.circular(8.0)),
271 | );
272 | }
273 |
274 | Widget uploadAreaID() {
275 | return Container(
276 | height: 150,
277 | child: ClipRRect(
278 | child: Image.network(
279 | gambar,
280 | fit: BoxFit.cover,
281 | ),
282 | borderRadius: BorderRadius.circular(8.0),
283 | ),
284 | decoration: BoxDecoration(borderRadius: BorderRadius.circular(8.0)),
285 | );
286 | }
287 | }
288 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | animated_splash_screen:
5 | dependency: "direct main"
6 | description:
7 | name: animated_splash_screen
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "1.1.0"
11 | async:
12 | dependency: transitive
13 | description:
14 | name: async
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "2.8.1"
18 | boolean_selector:
19 | dependency: transitive
20 | description:
21 | name: boolean_selector
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.1.0"
25 | characters:
26 | dependency: transitive
27 | description:
28 | name: characters
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.1.0"
32 | charcode:
33 | dependency: transitive
34 | description:
35 | name: charcode
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.3.1"
39 | clock:
40 | dependency: transitive
41 | description:
42 | name: clock
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.1.0"
46 | cloud_firestore:
47 | dependency: "direct main"
48 | description:
49 | name: cloud_firestore
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "3.1.0"
53 | cloud_firestore_platform_interface:
54 | dependency: transitive
55 | description:
56 | name: cloud_firestore_platform_interface
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "5.4.5"
60 | cloud_firestore_web:
61 | dependency: transitive
62 | description:
63 | name: cloud_firestore_web
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "2.5.0"
67 | collection:
68 | dependency: transitive
69 | description:
70 | name: collection
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "1.15.0"
74 | cross_file:
75 | dependency: transitive
76 | description:
77 | name: cross_file
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "0.3.2"
81 | cupertino_icons:
82 | dependency: "direct main"
83 | description:
84 | name: cupertino_icons
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "1.0.4"
88 | date_field:
89 | dependency: "direct main"
90 | description:
91 | name: date_field
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "2.1.2"
95 | fake_async:
96 | dependency: transitive
97 | description:
98 | name: fake_async
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "1.2.0"
102 | firebase_core:
103 | dependency: "direct main"
104 | description:
105 | name: firebase_core
106 | url: "https://pub.dartlang.org"
107 | source: hosted
108 | version: "1.10.0"
109 | firebase_core_platform_interface:
110 | dependency: transitive
111 | description:
112 | name: firebase_core_platform_interface
113 | url: "https://pub.dartlang.org"
114 | source: hosted
115 | version: "4.1.0"
116 | firebase_core_web:
117 | dependency: transitive
118 | description:
119 | name: firebase_core_web
120 | url: "https://pub.dartlang.org"
121 | source: hosted
122 | version: "1.2.0"
123 | firebase_storage:
124 | dependency: "direct main"
125 | description:
126 | name: firebase_storage
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "10.1.0"
130 | firebase_storage_platform_interface:
131 | dependency: transitive
132 | description:
133 | name: firebase_storage_platform_interface
134 | url: "https://pub.dartlang.org"
135 | source: hosted
136 | version: "4.0.6"
137 | firebase_storage_web:
138 | dependency: transitive
139 | description:
140 | name: firebase_storage_web
141 | url: "https://pub.dartlang.org"
142 | source: hosted
143 | version: "3.1.0"
144 | flutter:
145 | dependency: "direct main"
146 | description: flutter
147 | source: sdk
148 | version: "0.0.0"
149 | flutter_plugin_android_lifecycle:
150 | dependency: transitive
151 | description:
152 | name: flutter_plugin_android_lifecycle
153 | url: "https://pub.dartlang.org"
154 | source: hosted
155 | version: "2.0.4"
156 | flutter_svg:
157 | dependency: "direct main"
158 | description:
159 | name: flutter_svg
160 | url: "https://pub.dartlang.org"
161 | source: hosted
162 | version: "0.22.0"
163 | flutter_test:
164 | dependency: "direct dev"
165 | description: flutter
166 | source: sdk
167 | version: "0.0.0"
168 | flutter_web_plugins:
169 | dependency: transitive
170 | description: flutter
171 | source: sdk
172 | version: "0.0.0"
173 | hexcolor:
174 | dependency: "direct main"
175 | description:
176 | name: hexcolor
177 | url: "https://pub.dartlang.org"
178 | source: hosted
179 | version: "2.0.5"
180 | http:
181 | dependency: "direct main"
182 | description:
183 | name: http
184 | url: "https://pub.dartlang.org"
185 | source: hosted
186 | version: "0.13.3"
187 | http_parser:
188 | dependency: transitive
189 | description:
190 | name: http_parser
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "4.0.0"
194 | image_picker:
195 | dependency: "direct main"
196 | description:
197 | name: image_picker
198 | url: "https://pub.dartlang.org"
199 | source: hosted
200 | version: "0.8.4+4"
201 | image_picker_for_web:
202 | dependency: transitive
203 | description:
204 | name: image_picker_for_web
205 | url: "https://pub.dartlang.org"
206 | source: hosted
207 | version: "2.1.4"
208 | image_picker_platform_interface:
209 | dependency: transitive
210 | description:
211 | name: image_picker_platform_interface
212 | url: "https://pub.dartlang.org"
213 | source: hosted
214 | version: "2.4.1"
215 | intl:
216 | dependency: transitive
217 | description:
218 | name: intl
219 | url: "https://pub.dartlang.org"
220 | source: hosted
221 | version: "0.17.0"
222 | js:
223 | dependency: transitive
224 | description:
225 | name: js
226 | url: "https://pub.dartlang.org"
227 | source: hosted
228 | version: "0.6.3"
229 | matcher:
230 | dependency: transitive
231 | description:
232 | name: matcher
233 | url: "https://pub.dartlang.org"
234 | source: hosted
235 | version: "0.12.10"
236 | meta:
237 | dependency: transitive
238 | description:
239 | name: meta
240 | url: "https://pub.dartlang.org"
241 | source: hosted
242 | version: "1.7.0"
243 | page_transition:
244 | dependency: transitive
245 | description:
246 | name: page_transition
247 | url: "https://pub.dartlang.org"
248 | source: hosted
249 | version: "2.0.1-nullsafety.0"
250 | path:
251 | dependency: transitive
252 | description:
253 | name: path
254 | url: "https://pub.dartlang.org"
255 | source: hosted
256 | version: "1.8.0"
257 | path_drawing:
258 | dependency: transitive
259 | description:
260 | name: path_drawing
261 | url: "https://pub.dartlang.org"
262 | source: hosted
263 | version: "0.5.1+1"
264 | path_parsing:
265 | dependency: transitive
266 | description:
267 | name: path_parsing
268 | url: "https://pub.dartlang.org"
269 | source: hosted
270 | version: "0.2.1"
271 | pedantic:
272 | dependency: transitive
273 | description:
274 | name: pedantic
275 | url: "https://pub.dartlang.org"
276 | source: hosted
277 | version: "1.11.1"
278 | petitparser:
279 | dependency: transitive
280 | description:
281 | name: petitparser
282 | url: "https://pub.dartlang.org"
283 | source: hosted
284 | version: "4.1.0"
285 | plugin_platform_interface:
286 | dependency: transitive
287 | description:
288 | name: plugin_platform_interface
289 | url: "https://pub.dartlang.org"
290 | source: hosted
291 | version: "2.0.2"
292 | shimmer:
293 | dependency: "direct main"
294 | description:
295 | name: shimmer
296 | url: "https://pub.dartlang.org"
297 | source: hosted
298 | version: "2.0.0"
299 | sky_engine:
300 | dependency: transitive
301 | description: flutter
302 | source: sdk
303 | version: "0.0.99"
304 | source_span:
305 | dependency: transitive
306 | description:
307 | name: source_span
308 | url: "https://pub.dartlang.org"
309 | source: hosted
310 | version: "1.8.1"
311 | stack_trace:
312 | dependency: transitive
313 | description:
314 | name: stack_trace
315 | url: "https://pub.dartlang.org"
316 | source: hosted
317 | version: "1.10.0"
318 | stream_channel:
319 | dependency: transitive
320 | description:
321 | name: stream_channel
322 | url: "https://pub.dartlang.org"
323 | source: hosted
324 | version: "2.1.0"
325 | string_scanner:
326 | dependency: transitive
327 | description:
328 | name: string_scanner
329 | url: "https://pub.dartlang.org"
330 | source: hosted
331 | version: "1.1.0"
332 | term_glyph:
333 | dependency: transitive
334 | description:
335 | name: term_glyph
336 | url: "https://pub.dartlang.org"
337 | source: hosted
338 | version: "1.2.0"
339 | test_api:
340 | dependency: transitive
341 | description:
342 | name: test_api
343 | url: "https://pub.dartlang.org"
344 | source: hosted
345 | version: "0.4.2"
346 | typed_data:
347 | dependency: transitive
348 | description:
349 | name: typed_data
350 | url: "https://pub.dartlang.org"
351 | source: hosted
352 | version: "1.3.0"
353 | vector_math:
354 | dependency: transitive
355 | description:
356 | name: vector_math
357 | url: "https://pub.dartlang.org"
358 | source: hosted
359 | version: "2.1.0"
360 | webview_flutter:
361 | dependency: "direct main"
362 | description:
363 | name: webview_flutter
364 | url: "https://pub.dartlang.org"
365 | source: hosted
366 | version: "2.0.13"
367 | xml:
368 | dependency: transitive
369 | description:
370 | name: xml
371 | url: "https://pub.dartlang.org"
372 | source: hosted
373 | version: "5.1.2"
374 | sdks:
375 | dart: ">=2.14.0 <3.0.0"
376 | flutter: ">=2.5.0"
377 |
--------------------------------------------------------------------------------
/lib/model/news.dart:
--------------------------------------------------------------------------------
1 | class News {
2 | String author;
3 | String title;
4 | String image;
5 | String published;
6 | String content;
7 | String url;
8 | String source;
9 |
10 | News(
11 | {
12 | required this.author,
13 | required this.title,
14 | required this.image,
15 | required this.published,
16 | required this.content,
17 | required this.url,
18 | required this.source
19 | }
20 | );
21 |
22 | factory News.fromJson(Map json) {
23 | var imageUrl = "https://idtechsolusi.co.id/assets/img/no-image.png";
24 | return News(
25 | author : json['author'] == null ? "" : json['author'],
26 | title : json['title'] == null ? "" : json['title'],
27 | image : json['urlToImage'] == null ? imageUrl : json['urlToImage'],
28 | published : json['publishedAt'] == null ? "" : json['publishedAt'],
29 | content : json['content'] == null ? "" : json['content'],
30 | url: json['url'] == null ? "" : json['url'],
31 | source: json['source']['name']
32 | );
33 | }
34 | }
35 |
36 | // class NewsList {
37 | // List newsL=[
38 | // News(
39 | // author: 'Yuni Riadi',
40 | // title: 'Bocor di Tenaa Xiaomi CC11 Pro Punya Layar 4K - Selular.ID',
41 | // image: 'https://selular.id/wp-content/uploads/2021/07/Berita-Ke-3-Xiaomi-CC.jpg',
42 | // published: '2021-10-01',
43 | // content: 'Jakarta, Selular.ID – Pada Juli lalu informasi mengenai seri CC yang akan dirilis Xiaomi beredar. Melalui Wei Siqi, manajer produk dan juru bicara merek Xiaomi dengan jelas menyatakan bahwa model ser… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
44 | // ),
45 | // News(
46 | // author: 'M.Risman Noor',
47 | // title: 'Ponsel Android dan iPhone Tak Dapat Lagi Gunakan WhatsApp',
48 | // image: 'https://cdn-2.tstatic.net/banjarmasin/foto/bank/images/whatsapp-bakal-meluncurkan-5-fitur-baru-di-2021-ini.jpg',
49 | // published: '2021-10-01',
50 | // content: 'BANJARMASINPOST.CO.ID - Satu bulan lagi memasuki 1 November 2021 pengguna ponsel android maupun iOs bakal tak bisa lagi menggunakan WhatsApp.\r\nPonsel mana saja yang nantinya tak bisa menggunakan apli… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
51 | // ),
52 | // News(
53 | // author: 'Sahrul Sidiq',
54 | // title: 'HP Harga Rp1 Jutaan Terbaru 2021 Ada Oppo A31, Vivo S1 serta Samsung Galaxy M02',
55 | // image: 'https://cdn-2.tstatic.net/tribunnews/foto/bank/images/samsung-galaxy-a32-samsung-galaxy-a52-dan-samsung-galaxy-a52.jpg',
56 | // published: '2021-10-01',
57 | // content: 'MANTRA SUKABUMI - Berikut kami rangkum daftar HP android Rp.1 Jutaan dari berbagai merk ada dari Oppo A31, Vivo S1 hingga Samsung Galaxy M02.\r\nWalau dengan harga yang kisaran Rp.1 Jutaan, baik Oppo, … \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
58 | // ),
59 | // News(
60 | // author: 'Intan Rakhmayanti Dewi',
61 | // title: 'Bos Microsoft Beberkan Kisah di Balik Gagalnya Akuisisi TikTok',
62 | // image: 'https://img.inews.co.id/media/600/files/inews_new/2021/10/01/Aplikasi_TikTok.jpg',
63 | // published: '2021-10-01',
64 | // content: 'JAKARTA, iNews.id - Microsoft sempat ingin meminang TikTok tahun lalu. Namun, upaya untuk mengakuisisi perusahaan video pendek itu pada akhirnya tidak terlaksana. Bagaimana kisahnya?\r\nSelang setahun… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
65 | // ),
66 | // News(
67 | // author: 'Estu Suryowati',
68 | // title: 'Monitor Gaming LG UltraGear Ditopang Nvidia G-Sync dan Nano IPS',
69 | // image: 'https://images.soco.id/521-tips-mata-nyaman1.jpg.jpeg',
70 | // published: '2021-10-01',
71 | // content: 'JawaPos.com – Buat gamers yang bermain di perangkat PC, salah satu yang menunjang performa adalah monitor dengan kemampuan tinggi dalam menampilkan grafis. Di pasaran, cukup banyak tersedia monitor g… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
72 | // ),
73 |
74 | // ];
75 | // }
76 |
77 | // class NewsHeadlines{
78 | // List newsH=[
79 | // News(
80 | // author: 'Fahri Zulfikar',
81 | // title: 'Sering Pakai Gadget untuk Sekolah Online? Awas Ada 200 Aplikasi Berbahaya',
82 | // image: 'https://awsimages.detik.net.id/api/wm/2021/02/21/begini-cara-belajar-asyik-sambil-bermain-untuk-anak-1_169.jpeg?wid=54&w=650&v=1&t=jpeg',
83 | // published: '2021-10-01',
84 | // content: 'Jakarta - Belum seluruh daerah menjalankan PTM Terbatas membuat siswa masih harus menjalani sekolah daring atau online dari rumah. Namun, siswa perlu hati-hati dalam menggunakan gadget karena terdapa… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
85 | // ),
86 | // News(
87 | // author: 'Kontan',
88 | // title: 'Tiga Pembalap Muda Bersaing Ketat di Puncak Klasemen Kelas Rising Star HRSC 2',
89 | // image: 'https://photo.kontan.co.id/photo/2021/10/01/1683201524p.jpg',
90 | // published: '2021-10-01',
91 | // content: 'Jakarta, 1 Oktober 2021 Seri keempat dari Honda Racing Simulator Championship (HRSC) musim kedua akan diselenggarakan akhir pekan ini, 2 Oktober 2021 dengan menggunakan sirkuit virtual Road Atlanta, … \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
92 | // ),
93 | // News(
94 | // author: 'Agustinus Mario Damar',
95 | // title: 'Dell Perkenalkan 2 Laptop Gaming Terbaru dari Seri Alienware dan G-Series',
96 | // image: 'https://cdn0-production-images-kly.akamaized.net/1eA_BYbPWXYxtJaj98V095Xdd3U=/673x379/smart/filters:quality(75):strip_icc():format(jpeg)/kly-media-production/medias/3589310/original/065936600_1633063271-Dell_G15_family_photo_2.jpg',
97 | // published: '2021-10-01',
98 | // content: 'Liputan6.com, Jakarta - Dell Technologies baru saja meluncurkan laptop terbarunya, yakni Alienware M-Series dan Dell G-Series di Asia Selatan dan pasar berkembang Asia lainnya, termasuk di Indonesia.… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
99 | // ),
100 | // News(
101 | // author: 'Dommara Hadi S',
102 | // title: 'Pengguna iPhone enggan upgrade ke iOS 15',
103 | // image: 'https://img.tek.id/share/content/2021/10/01/45495/duh-pengguna-iphone-enggan-upgrade-ke-ios-15-GTH8isKZtR.jpg',
104 | // published: '2021-10-01',
105 | // content: 'Sepekan sudah setelah Apple menggulirkan secara resmi OS terbaru mereka untuk iPhone dan iPad. Para pengguna pengguna pun diharapkan untuk segera melakukan pembaruan ke iOS 15 dari OS lama mereka.\r\nT… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
106 | // ),
107 | // News(
108 | // author: 'Khoirunnisa',
109 | // title: 'Cristiano Amon: Snapdragon Insiders Hadir di Indonesia',
110 | // image: 'https://selular.id/wp-content/uploads/2021/10/Christiano-Amon.png',
111 | // published: '2021-10-01',
112 | // content: 'Jakarta, Selular.ID – Setelah diluncurkan secara global pada Maret 2021, Qualcomm hari ini secara resmi meluncurkan program Snapdragon Insiders di Indonesia. Program ini dibuat untuk mengumumkan beri… \n Ligula amet, morbi risus, blandit turpis turpis habitant odio. Sem pharetra accumsan pulvinar mauris eget quis. Donec orci, vitae quisque a velit tristique consectetur malesuada. Scelerisque id mi dui ullamcorper. \n Vulputate ut arcu nulla dui, elementum condimentum. Amet donec purus hendrerit pharetra, mauris amet pharetra nibh. Eget sit vestibulum nibh semper neque nisi, purus. Tortor adipiscing dictum vel et sodales donec velit. Arcu senectus posuere sit adipiscing proin et nisi placerat vitae.'
113 | // ),
114 |
115 | // ];
116 | // }
117 |
118 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXCopyFilesBuildPhase section */
19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
20 | isa = PBXCopyFilesBuildPhase;
21 | buildActionMask = 2147483647;
22 | dstPath = "";
23 | dstSubfolderSpec = 10;
24 | files = (
25 | );
26 | name = "Embed Frameworks";
27 | runOnlyForDeploymentPostprocessing = 0;
28 | };
29 | /* End PBXCopyFilesBuildPhase section */
30 |
31 | /* Begin PBXFileReference section */
32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | 9740EEB11CF90186004384FC /* Flutter */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
65 | );
66 | name = Flutter;
67 | sourceTree = "";
68 | };
69 | 97C146E51CF9000F007C117D = {
70 | isa = PBXGroup;
71 | children = (
72 | 9740EEB11CF90186004384FC /* Flutter */,
73 | 97C146F01CF9000F007C117D /* Runner */,
74 | 97C146EF1CF9000F007C117D /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | 97C146EF1CF9000F007C117D /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 97C146EE1CF9000F007C117D /* Runner.app */,
82 | );
83 | name = Products;
84 | sourceTree = "";
85 | };
86 | 97C146F01CF9000F007C117D /* Runner */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
92 | 97C147021CF9000F007C117D /* Info.plist */,
93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
97 | );
98 | path = Runner;
99 | sourceTree = "";
100 | };
101 | /* End PBXGroup section */
102 |
103 | /* Begin PBXNativeTarget section */
104 | 97C146ED1CF9000F007C117D /* Runner */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
107 | buildPhases = (
108 | 9740EEB61CF901F6004384FC /* Run Script */,
109 | 97C146EA1CF9000F007C117D /* Sources */,
110 | 97C146EB1CF9000F007C117D /* Frameworks */,
111 | 97C146EC1CF9000F007C117D /* Resources */,
112 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | );
119 | name = Runner;
120 | productName = Runner;
121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
122 | productType = "com.apple.product-type.application";
123 | };
124 | /* End PBXNativeTarget section */
125 |
126 | /* Begin PBXProject section */
127 | 97C146E61CF9000F007C117D /* Project object */ = {
128 | isa = PBXProject;
129 | attributes = {
130 | LastUpgradeCheck = 1020;
131 | ORGANIZATIONNAME = "";
132 | TargetAttributes = {
133 | 97C146ED1CF9000F007C117D = {
134 | CreatedOnToolsVersion = 7.3.1;
135 | LastSwiftMigration = 1100;
136 | };
137 | };
138 | };
139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
140 | compatibilityVersion = "Xcode 9.3";
141 | developmentRegion = en;
142 | hasScannedForEncodings = 0;
143 | knownRegions = (
144 | en,
145 | Base,
146 | );
147 | mainGroup = 97C146E51CF9000F007C117D;
148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
149 | projectDirPath = "";
150 | projectRoot = "";
151 | targets = (
152 | 97C146ED1CF9000F007C117D /* Runner */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXResourcesBuildPhase section */
158 | 97C146EC1CF9000F007C117D /* Resources */ = {
159 | isa = PBXResourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXShellScriptBuildPhase section */
172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
173 | isa = PBXShellScriptBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | );
177 | inputPaths = (
178 | );
179 | name = "Thin Binary";
180 | outputPaths = (
181 | );
182 | runOnlyForDeploymentPostprocessing = 0;
183 | shellPath = /bin/sh;
184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
185 | };
186 | 9740EEB61CF901F6004384FC /* Run Script */ = {
187 | isa = PBXShellScriptBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | );
191 | inputPaths = (
192 | );
193 | name = "Run Script";
194 | outputPaths = (
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | shellPath = /bin/sh;
198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
199 | };
200 | /* End PBXShellScriptBuildPhase section */
201 |
202 | /* Begin PBXSourcesBuildPhase section */
203 | 97C146EA1CF9000F007C117D /* Sources */ = {
204 | isa = PBXSourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXSourcesBuildPhase section */
213 |
214 | /* Begin PBXVariantGroup section */
215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
216 | isa = PBXVariantGroup;
217 | children = (
218 | 97C146FB1CF9000F007C117D /* Base */,
219 | );
220 | name = Main.storyboard;
221 | sourceTree = "";
222 | };
223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
224 | isa = PBXVariantGroup;
225 | children = (
226 | 97C147001CF9000F007C117D /* Base */,
227 | );
228 | name = LaunchScreen.storyboard;
229 | sourceTree = "";
230 | };
231 | /* End PBXVariantGroup section */
232 |
233 | /* Begin XCBuildConfiguration section */
234 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | ALWAYS_SEARCH_USER_PATHS = NO;
238 | CLANG_ANALYZER_NONNULL = YES;
239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
240 | CLANG_CXX_LIBRARY = "libc++";
241 | CLANG_ENABLE_MODULES = YES;
242 | CLANG_ENABLE_OBJC_ARC = YES;
243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
244 | CLANG_WARN_BOOL_CONVERSION = YES;
245 | CLANG_WARN_COMMA = YES;
246 | CLANG_WARN_CONSTANT_CONVERSION = YES;
247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
249 | CLANG_WARN_EMPTY_BODY = YES;
250 | CLANG_WARN_ENUM_CONVERSION = YES;
251 | CLANG_WARN_INFINITE_RECURSION = YES;
252 | CLANG_WARN_INT_CONVERSION = YES;
253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
258 | CLANG_WARN_STRICT_PROTOTYPES = YES;
259 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
260 | CLANG_WARN_UNREACHABLE_CODE = YES;
261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
263 | COPY_PHASE_STRIP = NO;
264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
265 | ENABLE_NS_ASSERTIONS = NO;
266 | ENABLE_STRICT_OBJC_MSGSEND = YES;
267 | GCC_C_LANGUAGE_STANDARD = gnu99;
268 | GCC_NO_COMMON_BLOCKS = YES;
269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
271 | GCC_WARN_UNDECLARED_SELECTOR = YES;
272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 | GCC_WARN_UNUSED_FUNCTION = YES;
274 | GCC_WARN_UNUSED_VARIABLE = YES;
275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
276 | MTL_ENABLE_DEBUG_INFO = NO;
277 | SDKROOT = iphoneos;
278 | SUPPORTED_PLATFORMS = iphoneos;
279 | TARGETED_DEVICE_FAMILY = "1,2";
280 | VALIDATE_PRODUCT = YES;
281 | };
282 | name = Profile;
283 | };
284 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
285 | isa = XCBuildConfiguration;
286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
287 | buildSettings = {
288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
289 | CLANG_ENABLE_MODULES = YES;
290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
291 | ENABLE_BITCODE = NO;
292 | INFOPLIST_FILE = Runner/Info.plist;
293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
294 | PRODUCT_BUNDLE_IDENTIFIER = com.example.newsly;
295 | PRODUCT_NAME = "$(TARGET_NAME)";
296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
297 | SWIFT_VERSION = 5.0;
298 | VERSIONING_SYSTEM = "apple-generic";
299 | };
300 | name = Profile;
301 | };
302 | 97C147031CF9000F007C117D /* Debug */ = {
303 | isa = XCBuildConfiguration;
304 | buildSettings = {
305 | ALWAYS_SEARCH_USER_PATHS = NO;
306 | CLANG_ANALYZER_NONNULL = YES;
307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
308 | CLANG_CXX_LIBRARY = "libc++";
309 | CLANG_ENABLE_MODULES = YES;
310 | CLANG_ENABLE_OBJC_ARC = YES;
311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
312 | CLANG_WARN_BOOL_CONVERSION = YES;
313 | CLANG_WARN_COMMA = YES;
314 | CLANG_WARN_CONSTANT_CONVERSION = YES;
315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
317 | CLANG_WARN_EMPTY_BODY = YES;
318 | CLANG_WARN_ENUM_CONVERSION = YES;
319 | CLANG_WARN_INFINITE_RECURSION = YES;
320 | CLANG_WARN_INT_CONVERSION = YES;
321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
326 | CLANG_WARN_STRICT_PROTOTYPES = YES;
327 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
328 | CLANG_WARN_UNREACHABLE_CODE = YES;
329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
331 | COPY_PHASE_STRIP = NO;
332 | DEBUG_INFORMATION_FORMAT = dwarf;
333 | ENABLE_STRICT_OBJC_MSGSEND = YES;
334 | ENABLE_TESTABILITY = YES;
335 | GCC_C_LANGUAGE_STANDARD = gnu99;
336 | GCC_DYNAMIC_NO_PIC = NO;
337 | GCC_NO_COMMON_BLOCKS = YES;
338 | GCC_OPTIMIZATION_LEVEL = 0;
339 | GCC_PREPROCESSOR_DEFINITIONS = (
340 | "DEBUG=1",
341 | "$(inherited)",
342 | );
343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
345 | GCC_WARN_UNDECLARED_SELECTOR = YES;
346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
347 | GCC_WARN_UNUSED_FUNCTION = YES;
348 | GCC_WARN_UNUSED_VARIABLE = YES;
349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
350 | MTL_ENABLE_DEBUG_INFO = YES;
351 | ONLY_ACTIVE_ARCH = YES;
352 | SDKROOT = iphoneos;
353 | TARGETED_DEVICE_FAMILY = "1,2";
354 | };
355 | name = Debug;
356 | };
357 | 97C147041CF9000F007C117D /* Release */ = {
358 | isa = XCBuildConfiguration;
359 | buildSettings = {
360 | ALWAYS_SEARCH_USER_PATHS = NO;
361 | CLANG_ANALYZER_NONNULL = YES;
362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
363 | CLANG_CXX_LIBRARY = "libc++";
364 | CLANG_ENABLE_MODULES = YES;
365 | CLANG_ENABLE_OBJC_ARC = YES;
366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
367 | CLANG_WARN_BOOL_CONVERSION = YES;
368 | CLANG_WARN_COMMA = YES;
369 | CLANG_WARN_CONSTANT_CONVERSION = YES;
370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
372 | CLANG_WARN_EMPTY_BODY = YES;
373 | CLANG_WARN_ENUM_CONVERSION = YES;
374 | CLANG_WARN_INFINITE_RECURSION = YES;
375 | CLANG_WARN_INT_CONVERSION = YES;
376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
381 | CLANG_WARN_STRICT_PROTOTYPES = YES;
382 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
383 | CLANG_WARN_UNREACHABLE_CODE = YES;
384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
386 | COPY_PHASE_STRIP = NO;
387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
388 | ENABLE_NS_ASSERTIONS = NO;
389 | ENABLE_STRICT_OBJC_MSGSEND = YES;
390 | GCC_C_LANGUAGE_STANDARD = gnu99;
391 | GCC_NO_COMMON_BLOCKS = YES;
392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
394 | GCC_WARN_UNDECLARED_SELECTOR = YES;
395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
396 | GCC_WARN_UNUSED_FUNCTION = YES;
397 | GCC_WARN_UNUSED_VARIABLE = YES;
398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
399 | MTL_ENABLE_DEBUG_INFO = NO;
400 | SDKROOT = iphoneos;
401 | SUPPORTED_PLATFORMS = iphoneos;
402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
403 | TARGETED_DEVICE_FAMILY = "1,2";
404 | VALIDATE_PRODUCT = YES;
405 | };
406 | name = Release;
407 | };
408 | 97C147061CF9000F007C117D /* Debug */ = {
409 | isa = XCBuildConfiguration;
410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
411 | buildSettings = {
412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
413 | CLANG_ENABLE_MODULES = YES;
414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
415 | ENABLE_BITCODE = NO;
416 | INFOPLIST_FILE = Runner/Info.plist;
417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
418 | PRODUCT_BUNDLE_IDENTIFIER = com.example.newsly;
419 | PRODUCT_NAME = "$(TARGET_NAME)";
420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
422 | SWIFT_VERSION = 5.0;
423 | VERSIONING_SYSTEM = "apple-generic";
424 | };
425 | name = Debug;
426 | };
427 | 97C147071CF9000F007C117D /* Release */ = {
428 | isa = XCBuildConfiguration;
429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
430 | buildSettings = {
431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
432 | CLANG_ENABLE_MODULES = YES;
433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
434 | ENABLE_BITCODE = NO;
435 | INFOPLIST_FILE = Runner/Info.plist;
436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
437 | PRODUCT_BUNDLE_IDENTIFIER = com.example.newsly;
438 | PRODUCT_NAME = "$(TARGET_NAME)";
439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
440 | SWIFT_VERSION = 5.0;
441 | VERSIONING_SYSTEM = "apple-generic";
442 | };
443 | name = Release;
444 | };
445 | /* End XCBuildConfiguration section */
446 |
447 | /* Begin XCConfigurationList section */
448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
449 | isa = XCConfigurationList;
450 | buildConfigurations = (
451 | 97C147031CF9000F007C117D /* Debug */,
452 | 97C147041CF9000F007C117D /* Release */,
453 | 249021D3217E4FDB00AE95B9 /* Profile */,
454 | );
455 | defaultConfigurationIsVisible = 0;
456 | defaultConfigurationName = Release;
457 | };
458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
459 | isa = XCConfigurationList;
460 | buildConfigurations = (
461 | 97C147061CF9000F007C117D /* Debug */,
462 | 97C147071CF9000F007C117D /* Release */,
463 | 249021D4217E4FDB00AE95B9 /* Profile */,
464 | );
465 | defaultConfigurationIsVisible = 0;
466 | defaultConfigurationName = Release;
467 | };
468 | /* End XCConfigurationList section */
469 | };
470 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
471 | }
472 |
--------------------------------------------------------------------------------