29-02-1403 / Rhmn / Widget Android Created.
This commit is contained in:
parent
d4afdeb688
commit
e609feab7b
|
|
@ -75,6 +75,9 @@ android {
|
|||
disable 'InvalidPackage'
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
|
@ -84,4 +87,7 @@ flutter {
|
|||
dependencies {
|
||||
implementation platform('com.google.firebase:firebase-bom:29.1.0')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
// implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||
implementation 'com.squareup.picasso:picasso:2.8'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.didvan.didvanapp">
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
|
||||
|
||||
<application
|
||||
android:label="Didvan"
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:label="Didvan"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:usesCleartextTraffic="true">
|
||||
<receiver
|
||||
android:name=".FavWidget"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/favourite_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="es.antonborri.home_widget.HomeWidgetBackgroundReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="es.antonborri.home_widget.action.BACKGROUND" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<service android:name="es.antonborri.home_widget.HomeWidgetBackgroundService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true"/>
|
||||
|
||||
android:requestLegacyExternalStorage="true">
|
||||
|
||||
|
||||
<activity
|
||||
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:showOnLockScreen="true"
|
||||
android:showWhenLocked="true"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:turnScreenOn="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
|
||||
<!--
|
||||
Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
to determine the Window background behind the Flutter UI.
|
||||
-->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
|
||||
<!-- Displays an Android View that continues showing the launch screen
|
||||
<!--
|
||||
Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame. -->
|
||||
Flutter's first frame.
|
||||
-->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
|
||||
<service
|
||||
android:name=".MyFirebaseMessagingService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.messaging.RECEIVE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<service
|
||||
android:name=".MyFirebaseMessagingService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.messaging.RECEIVE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
package com.didvan.didvanapp
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.widget.RemoteViews
|
||||
import com.squareup.picasso.Picasso
|
||||
import com.squareup.picasso.Transformation
|
||||
import es.antonborri.home_widget.HomeWidgetBackgroundIntent
|
||||
import es.antonborri.home_widget.HomeWidgetLaunchIntent
|
||||
import es.antonborri.home_widget.HomeWidgetProvider
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of App Widget functionality.
|
||||
*/
|
||||
class FavWidget : HomeWidgetProvider() {
|
||||
|
||||
@SuppressLint("RemoteViewLayout")
|
||||
override fun onUpdate(
|
||||
context: Context,
|
||||
appWidgetManager: AppWidgetManager,
|
||||
appWidgetIds: IntArray,
|
||||
widgetData: SharedPreferences
|
||||
) {
|
||||
appWidgetIds.forEach { widgetId ->
|
||||
val views = RemoteViews(context.packageName, R.layout.favourite_widget).apply {
|
||||
|
||||
// Open App on Widget Click
|
||||
val pendingIntent = HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java
|
||||
)
|
||||
setOnClickPendingIntent(R.id.logo_btn, pendingIntent)
|
||||
|
||||
val responses: ArrayList<WidgetResponse> = ArrayList();
|
||||
val token = widgetData.getString("token", "").toString()
|
||||
|
||||
for (i in 0..2) {
|
||||
responses.add(
|
||||
WidgetResponse(
|
||||
id = widgetData.getString("id${i + 1}", "")?.toInt() ?: 0,
|
||||
title = widgetData.getString("title${i + 1}", "").toString(),
|
||||
createdAt = widgetData.getString("createdAt${i + 1}", "").toString(),
|
||||
type = widgetData.getString("type${i + 1}", "").toString(),
|
||||
link = widgetData.getString("link${i + 1}", "").toString(),
|
||||
category = widgetData.getString("category${i + 1}", "").toString(),
|
||||
image = widgetData.getString("image${i + 1}", "").toString(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
setTextViewText(R.id.first_title, responses[0].title.toString())
|
||||
setTextViewText(R.id.middle_title, responses[1].title.toString())
|
||||
setTextViewText(R.id.last_title, responses[2].title.toString())
|
||||
//
|
||||
setTextViewText(R.id.first_tag, responses[0].category)
|
||||
setTextViewText(R.id.middle_tag, responses[1].category)
|
||||
setTextViewText(R.id.last_tag, responses[2].category)
|
||||
|
||||
setTextViewText(R.id.first_duration, responses[0].createdAt)
|
||||
setTextViewText(R.id.middle_duration, responses[1].createdAt)
|
||||
setTextViewText(R.id.last_duration, responses[2].createdAt)
|
||||
|
||||
Picasso.get()
|
||||
.load("https://api.didvan.app${responses[0].image}?accessToken=${token}")
|
||||
.transform(RoundedTransformation(50, 0))
|
||||
.into(this, R.id.first_image, appWidgetIds);
|
||||
Picasso.get()
|
||||
.load("https://api.didvan.app${responses[1].image}?accessToken=${token}")
|
||||
.transform(RoundedTransformation(50, 0))
|
||||
.into(this, R.id.middle_image, appWidgetIds);
|
||||
Picasso.get()
|
||||
.load("https://api.didvan.app${responses[2].image}?accessToken=${token}")
|
||||
.transform(RoundedTransformation(50, 0))
|
||||
.into(this, R.id.last_image, appWidgetIds);
|
||||
|
||||
|
||||
// Pending intent to update counter on button click
|
||||
val settingIntent = HomeWidgetBackgroundIntent.getBroadcast(
|
||||
context,
|
||||
Uri.parse("myAppWidget://setting"),
|
||||
|
||||
)
|
||||
setOnClickPendingIntent(R.id.setting_btn, settingIntent)
|
||||
|
||||
val rowFirst = HomeWidgetBackgroundIntent.getBroadcast(
|
||||
context,
|
||||
Uri.parse("myAppWidget://rowFirst"),
|
||||
|
||||
)
|
||||
setOnClickPendingIntent(R.id.first_row, settingIntent)
|
||||
val rowMiddle = HomeWidgetBackgroundIntent.getBroadcast(
|
||||
context,
|
||||
Uri.parse("myAppWidget://rowMiddle"),
|
||||
|
||||
)
|
||||
setOnClickPendingIntent(R.id.middle_row, settingIntent)
|
||||
val rowLast = HomeWidgetBackgroundIntent.getBroadcast(
|
||||
context,
|
||||
Uri.parse("myAppWidget://rowLast"),
|
||||
|
||||
)
|
||||
setOnClickPendingIntent(R.id.last_row, settingIntent)
|
||||
|
||||
}
|
||||
appWidgetManager.updateAppWidget(widgetId, views)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.didvan.didvanapp
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapShader
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.RectF
|
||||
import android.graphics.Shader
|
||||
import com.squareup.picasso.Transformation
|
||||
|
||||
|
||||
class RoundedTransformation(private val radius: Int, private val margin: Int) : Transformation {
|
||||
override fun transform(source: Bitmap): Bitmap {
|
||||
val paint = Paint()
|
||||
paint.isAntiAlias = true
|
||||
paint.setShader(
|
||||
BitmapShader(
|
||||
source, Shader.TileMode.CLAMP,
|
||||
Shader.TileMode.CLAMP
|
||||
)
|
||||
)
|
||||
val output = Bitmap.createBitmap(
|
||||
source.getWidth(), source.getHeight(),
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
val canvas = Canvas(output)
|
||||
canvas.drawRoundRect(
|
||||
RectF(
|
||||
margin.toFloat(), margin.toFloat(), (source.getWidth() - margin).toFloat(),
|
||||
(
|
||||
source.getHeight() - margin).toFloat()
|
||||
), radius.toFloat(), radius.toFloat(), paint
|
||||
)
|
||||
if (source != output) {
|
||||
source.recycle()
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
override fun key(): String {
|
||||
return "rounded(r=$radius, m=$margin)"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.didvan.didvanapp
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class WidgetResponse(
|
||||
@SerializedName("id")
|
||||
var id: Int = 0,
|
||||
@SerializedName("title")
|
||||
var title: String = "",
|
||||
@SerializedName("createdAt")
|
||||
var createdAt: String = "",
|
||||
@SerializedName("type")
|
||||
var type: String = "",
|
||||
@SerializedName("link")
|
||||
var link: String = "",
|
||||
@SerializedName("category")
|
||||
var category: String = "",
|
||||
@SerializedName("image")
|
||||
var image: String = "",
|
||||
|
||||
)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Background for widgets to make the rounded corners based on the
|
||||
appWidgetRadius attribute value
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="?attr/appWidgetRadius" />
|
||||
<solid android:color="?android:attr/colorBackground" />
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Background for views inside widgets to make the rounded corners based on the
|
||||
appWidgetInnerRadius attribute value
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="?attr/appWidgetInnerRadius" />
|
||||
<solid android:color="?android:attr/colorAccent" />
|
||||
</shape>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 773 B |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
|
@ -0,0 +1,300 @@
|
|||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/Widget.Android.AppWidget.Container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#ffffff"
|
||||
android:theme="@style/Theme.Android.AppWidgetContainer">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/root_lay"
|
||||
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/setting_btn"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:src="@drawable/setting_logo" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="32dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/logo_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/logo" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/first_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="78dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="horizontal"
|
||||
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/first_image"
|
||||
android:layout_width="74dp"
|
||||
android:layout_height="74dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/test" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_toLeftOf="@id/first_image"
|
||||
android:orientation="vertical"
|
||||
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/first_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:text=" تحلیل شکاف فناوری صنعت فولاد ایران تحلیل شکاف فناوری صنعت فولاد ایران"
|
||||
android:textColor="#012348"
|
||||
android:textSize="13dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/first_duration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="3"
|
||||
android:gravity="center_vertical"
|
||||
android:text="۳ دقیقه مطالعه"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12dp" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/first_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="4"
|
||||
android:gravity="center_vertical"
|
||||
android:text="رادار فناوری"
|
||||
android:textColor="#292929"
|
||||
android:textSize="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/middle_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="78dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/middle_image"
|
||||
android:layout_width="74dp"
|
||||
android:layout_height="74dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/test" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_toLeftOf="@id/middle_image"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/middle_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:text=" تحلیل شکاف فناوری صنعت فولاد ایران تحلیل شکاف فناوری صنعت فولاد ایران"
|
||||
android:textColor="#012348"
|
||||
android:textSize="13dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/middle_duration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="3"
|
||||
android:gravity="center_vertical"
|
||||
android:text="۳ دقیقه مطالعه"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12dp"
|
||||
|
||||
/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/middle_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="4"
|
||||
android:gravity="center_vertical"
|
||||
android:text="رادار فناوری"
|
||||
android:textColor="#292929"
|
||||
android:textSize="12dp"
|
||||
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/last_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="78dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/last_image"
|
||||
android:layout_width="74dp"
|
||||
android:layout_height="74dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/test" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_toLeftOf="@id/last_image"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:text=" تحلیل شکاف فناوری صنعت فولاد ایران تحلیل شکاف فناوری صنعت فولاد ایران"
|
||||
android:textColor="#012348"
|
||||
android:textSize="13dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_duration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="3"
|
||||
android:gravity="center_vertical"
|
||||
android:text="۳ دقیقه مطالعه"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12dp"
|
||||
|
||||
/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="4"
|
||||
android:gravity="center_vertical"
|
||||
android:text="رادار فناوری"
|
||||
android:textColor="#292929"
|
||||
android:textSize="12dp"
|
||||
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<resources>
|
||||
|
||||
<style name="Widget.Android.AppWidget.Container" parent="android:Widget">
|
||||
<item name="android:id">@android:id/background</item>
|
||||
<item name="android:padding">?attr/appWidgetPadding</item>
|
||||
<item name="android:background">@drawable/app_widget_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Android.AppWidget.InnerView" parent="android:Widget">
|
||||
<item name="android:padding">?attr/appWidgetPadding</item>
|
||||
<item name="android:background">@drawable/app_widget_inner_view_background</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<resources>
|
||||
<declare-styleable name="AppWidgetAttrs">
|
||||
<attr name="appWidgetPadding" format="dimension" />
|
||||
<attr name="appWidgetInnerRadius" format="dimension" />
|
||||
<attr name="appWidgetRadius" format="dimension" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<resources>
|
||||
<color name="light_blue_50">#FFE1F5FE</color>
|
||||
<color name="light_blue_200">#FF81D4FA</color>
|
||||
<color name="light_blue_600">#FF039BE5</color>
|
||||
<color name="light_blue_900">#FF01579B</color>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Refer to App Widget Documentation for margin information
|
||||
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
|
||||
-->
|
||||
<dimen name="widget_margin">0dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="appwidget_text">EXAMPLE</string>
|
||||
<string name="add_widget">Add widget</string>
|
||||
<string name="app_widget_description">This is an app widget description</string>
|
||||
</resources>
|
||||
|
|
@ -15,4 +15,14 @@
|
|||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Android.AppWidget.Container" parent="android:Widget">
|
||||
<item name="android:id">@android:id/background</item>
|
||||
<item name="android:background">?android:attr/colorBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Android.AppWidget.InnerView" parent="android:Widget">
|
||||
<item name="android:background">?android:attr/colorBackground</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<resources>
|
||||
|
||||
<style name="Theme.Android.AppWidgetContainerParent" parent="@android:style/Theme.DeviceDefault">
|
||||
<!-- Radius of the outer bound of widgets to make the rounded corners -->
|
||||
<item name="appWidgetRadius">16dp</item>
|
||||
<!--
|
||||
Radius of the inner view's bound of widgets to make the rounded corners.
|
||||
It needs to be 8dp or less than the value of appWidgetRadius
|
||||
-->
|
||||
<item name="appWidgetInnerRadius">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Android.AppWidgetContainer" parent="Theme.Android.AppWidgetContainerParent">
|
||||
<!-- Apply padding to avoid the content of the widget colliding with the rounded corners -->
|
||||
<item name="appWidgetPadding">16dp</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:description="@string/app_widget_description"
|
||||
android:initialKeyguardLayout="@layout/favourite_widget"
|
||||
android:initialLayout="@layout/favourite_widget"
|
||||
android:minWidth="250dp"
|
||||
android:minHeight="180dp"
|
||||
android:previewImage="@drawable/favwidg"
|
||||
android:targetCellWidth="4"
|
||||
android:targetCellHeight="3"
|
||||
android:updatePeriodMillis="86400000"
|
||||
android:widgetCategory="home_screen" />
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
151
lib/main.dart
151
lib/main.dart
|
|
@ -1,25 +1,25 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:android_intent_plus/android_intent.dart';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/providers/media.dart';
|
||||
import 'package:didvan/providers/theme.dart';
|
||||
import 'package:didvan/providers/user.dart';
|
||||
import 'package:didvan/routes/route_generator.dart';
|
||||
import 'package:didvan/services/app_initalizer.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/services/notification/awsome/awsome_notification_handler.dart';
|
||||
import 'package:didvan/services/notification/fcm/firebase_notification_handler.dart';
|
||||
import 'package:didvan/views/podcasts/podcasts_state.dart';
|
||||
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
||||
import 'package:didvan/services/notification/lc/local_notification_service.dart';
|
||||
import 'package:didvan/services/notification/lc/show_notification_handler.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:home_widget/home_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
// If you're going to use other Firebase services in the background, such as Firestore,
|
||||
|
|
@ -46,28 +46,98 @@ Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
|||
// LocalNotificationService.initialize();
|
||||
// LocalNotificationService.display(message);
|
||||
// LocalNotificationService.showBigPictureNotification();
|
||||
AwsomeNotificationHandler().main();
|
||||
AwsomeNotificationHandler().alarm();
|
||||
AwsomeNotificationHandler().show(message);
|
||||
|
||||
print("Handling a background message: ${message.messageId}");
|
||||
}
|
||||
|
||||
void main() async {
|
||||
try {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
||||
HomeWidget.registerBackgroundCallback(backgroundCallback);
|
||||
// HomeWidget.registerInteractivityCallback(backgroundCallback);
|
||||
HomeWidget.widgetClicked.listen((Uri? uri) {});
|
||||
FirebaseNotificationHandler().initial();
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
|
||||
runApp(const Didvan());
|
||||
}
|
||||
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
Future<void> backgroundCallback(Uri? uri) async {
|
||||
AndroidIntent intent = const AndroidIntent(
|
||||
action: 'android.intent.action.RUN',
|
||||
package: 'com.didvan.didvanapp',
|
||||
componentName: 'com.didvan.didvanapp.MainActivity',
|
||||
);
|
||||
|
||||
class Didvan extends StatelessWidget {
|
||||
await intent.launch();
|
||||
switch (uri!.host) {
|
||||
case 'setting':
|
||||
HomeWidget.saveWidgetData("r", Routes.notificationStatusStep);
|
||||
|
||||
break;
|
||||
|
||||
case 'rowFirst':
|
||||
HomeWidget.saveWidgetData("r", Routes.generalSettings);
|
||||
|
||||
break;
|
||||
|
||||
case 'rowMiddle':
|
||||
HomeWidget.saveWidgetData("r", Routes.generalSettings);
|
||||
|
||||
break;
|
||||
|
||||
case 'rowLast':
|
||||
HomeWidget.saveWidgetData("r", Routes.generalSettings);
|
||||
|
||||
break;
|
||||
|
||||
// Add more cases for other routes as needed
|
||||
}
|
||||
}
|
||||
|
||||
String r = "";
|
||||
|
||||
class Didvan extends StatefulWidget {
|
||||
const Didvan({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<Didvan> createState() => _DidvanState();
|
||||
}
|
||||
|
||||
class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance?.addObserver(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance?.removeObserver(this);
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) async {
|
||||
var v = context;
|
||||
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
await HomeWidget.getWidgetData<String>('r', defaultValue: "")
|
||||
.then((value) {
|
||||
if (value!.isNotEmpty) {
|
||||
navigatorKey.currentState?.pushNamed(
|
||||
value);
|
||||
}
|
||||
});
|
||||
HomeWidget.saveWidgetData("r", "");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiProvider(
|
||||
|
|
@ -92,37 +162,36 @@ class Didvan extends StatelessWidget {
|
|||
builder: (context, themeProvider, child) => Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: SafeArea(
|
||||
child: MaterialApp(
|
||||
navigatorKey: navigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Didvan',
|
||||
theme: LightThemeConfig.themeData.copyWith(
|
||||
textTheme: LightThemeConfig.themeData.textTheme.apply(
|
||||
fontFamily: themeProvider.fontFamily,
|
||||
)),
|
||||
darkTheme: DarkThemeConfig.themeData.copyWith(
|
||||
textTheme: DarkThemeConfig.themeData.textTheme.apply(
|
||||
fontFamily: themeProvider.fontFamily,
|
||||
)),
|
||||
color: LightThemeConfig.themeData.primaryColor,
|
||||
themeMode: themeProvider.themeMode,
|
||||
onGenerateRoute: (settings) =>
|
||||
RouteGenerator.generateRoute(settings),
|
||||
builder: BotToastInit(),
|
||||
//1. call BotToastInit
|
||||
navigatorObservers: [BotToastNavigatorObserver()],
|
||||
initialRoute: '/',
|
||||
localizationsDelegates: const [
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [
|
||||
Locale("fa", "IR"),
|
||||
],
|
||||
locale: const Locale("fa", "IR"),
|
||||
),
|
||||
),
|
||||
child: MaterialApp(
|
||||
navigatorKey: navigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Didvan',
|
||||
theme: LightThemeConfig.themeData.copyWith(
|
||||
textTheme: LightThemeConfig.themeData.textTheme.apply(
|
||||
fontFamily: themeProvider.fontFamily,
|
||||
)),
|
||||
darkTheme: DarkThemeConfig.themeData.copyWith(
|
||||
textTheme: DarkThemeConfig.themeData.textTheme.apply(
|
||||
fontFamily: themeProvider.fontFamily,
|
||||
)),
|
||||
color: LightThemeConfig.themeData.primaryColor,
|
||||
themeMode: themeProvider.themeMode,
|
||||
onGenerateRoute: (settings) =>
|
||||
RouteGenerator.generateRoute(settings),
|
||||
builder: BotToastInit(),
|
||||
//1. call BotToastInit
|
||||
navigatorObservers: [BotToastNavigatorObserver()],
|
||||
initialRoute: "/",
|
||||
localizationsDelegates: const [
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [
|
||||
Locale("fa", "IR"),
|
||||
],
|
||||
locale: const Locale("fa", "IR"),
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,26 @@ import '../views/notification_time/notification_time.dart';
|
|||
class RouteGenerator {
|
||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
switch (settings.name) {
|
||||
case Routes.widgetSetting:
|
||||
_createRoute(
|
||||
const Splash(),
|
||||
);
|
||||
_createRoute(
|
||||
const ProfilePage(),
|
||||
);
|
||||
_createRoute(
|
||||
ChangeNotifierProvider<GeneralSettingsState>(
|
||||
create: (context) => GeneralSettingsState(),
|
||||
child: const GeneralSettings(),
|
||||
),
|
||||
);
|
||||
|
||||
return _createRoute(
|
||||
ChangeNotifierProvider<CustomizeCategoryState>(
|
||||
create: (context) => CustomizeCategoryState(),
|
||||
child: FavoritesStep()),
|
||||
);
|
||||
|
||||
case Routes.splash:
|
||||
return _createRoute(
|
||||
const Splash(),
|
||||
|
|
@ -64,7 +84,7 @@ class RouteGenerator {
|
|||
return _createRoute(
|
||||
ChangeNotifierProvider<NotificationTimeState>(
|
||||
create: (context) => NotificationTimeState(),
|
||||
child: NotificationTime(
|
||||
child: NotificationTime(
|
||||
pageData: settings.arguments as Map<String, dynamic>,
|
||||
)),
|
||||
);
|
||||
|
|
@ -73,14 +93,14 @@ class RouteGenerator {
|
|||
return _createRoute(
|
||||
ChangeNotifierProvider<CustomizeCategoryState>(
|
||||
create: (context) => CustomizeCategoryState(),
|
||||
child: FavoritesStep()),
|
||||
child: FavoritesStep()),
|
||||
);
|
||||
|
||||
case Routes.notificationStatusStep:
|
||||
return _createRoute(
|
||||
ChangeNotifierProvider<CustomizeCategoryState>(
|
||||
create: (context) => CustomizeCategoryState(),
|
||||
child: NotificationStatusStep()),
|
||||
child: NotificationStatusStep()),
|
||||
);
|
||||
case Routes.authenticaion:
|
||||
return _createRoute(
|
||||
|
|
|
|||
|
|
@ -28,4 +28,5 @@ class Routes {
|
|||
static const String favouritesStep = '/favourites-step';
|
||||
static const String notificationStatusStep = '/notification-status-step';
|
||||
static const String notificationTime = '/notification-time';
|
||||
static const String widgetSetting = '/widget-setting';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ class RequestService {
|
|||
}) {
|
||||
if (body != null) _requestBody = body;
|
||||
if (requestHeaders != null) _headers.addAll(requestHeaders);
|
||||
if (useAutherization) _headers.addAll({'Authorization': 'Bearer $token'});
|
||||
// _headers.addAll({
|
||||
// 'Authorization':
|
||||
// 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwicm9sZUlkIjo0LCJhcHBJZCI6MCwiaWF0IjoxNzEzOTM1NzkwfQ.i-SO9tLy0M9j-_C2Wh8tdp01vtYGlDZIBFPygglHQF0'
|
||||
// });
|
||||
// if (useAutherization) _headers.addAll({'Authorization': 'Bearer $token'});
|
||||
_headers.addAll({
|
||||
'Authorization':
|
||||
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwicm9sZUlkIjo0LCJhcHBJZCI6MCwiaWF0IjoxNzEzOTM1NzkwfQ.i-SO9tLy0M9j-_C2Wh8tdp01vtYGlDZIBFPygglHQF0'
|
||||
});
|
||||
if (body != null) _requestBody = body;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ class RequestHelper {
|
|||
'$baseUrl/$type/$id/comments/add';
|
||||
static String deleteComment(int id) => '$baseUrl/comment/$id/v2';
|
||||
static String reportComment(int id) => '$baseUrl/comment/$id/report';
|
||||
static String widgetNews() => '$baseUrl/user/widget';
|
||||
|
||||
static String _urlConcatGenerator(List<MapEntry<String, dynamic>> additions) {
|
||||
String result = '';
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
|
||||
import 'package:awesome_notifications/awesome_notifications.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../models/notification_message.dart';
|
||||
import '../../network/request.dart';
|
||||
import '../../network/request_helper.dart';
|
||||
import 'awsome_notification_controller.dart';
|
||||
|
||||
class AwsomeNotificationHandler {
|
||||
main() async {
|
||||
alarm() async {
|
||||
late ReceivedAction? initialAction;
|
||||
|
||||
AwesomeNotifications().initialize(
|
||||
|
|
@ -83,6 +85,11 @@ class AwsomeNotificationHandler {
|
|||
case "3":
|
||||
await showNotificationTypeEmoji(notificationMessage);
|
||||
|
||||
break;
|
||||
|
||||
case "4":
|
||||
await showNotificationScheduled(notificationMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -146,4 +153,49 @@ class AwsomeNotificationHandler {
|
|||
'largeImage': 'path/to/largeImage.png', // Path to large image
|
||||
}));
|
||||
}
|
||||
|
||||
Future<DateTime> _getTime() async {
|
||||
final service = RequestService(
|
||||
RequestHelper.notificationTime(),
|
||||
);
|
||||
await service.httpGet();
|
||||
if (service.isSuccess) {
|
||||
final time = service.data('time');
|
||||
DateFormat format = DateFormat("HH:mm");
|
||||
DateTime dateTime = format.parse(time);
|
||||
DateTime result = DateTime.now()
|
||||
.copyWith(hour: dateTime.hour, minute: dateTime.minute);
|
||||
return result;
|
||||
} else {
|
||||
return DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
showNotificationScheduled(NotificationMessage message) async {
|
||||
DateTime time = await _getTime();
|
||||
AwesomeNotifications().createNotification(
|
||||
content: NotificationContent(
|
||||
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
channelKey: 'alerts',
|
||||
title: 'Emojis are awes'
|
||||
'ome too! ${Emojis.animals_lady_beetle}${Emojis.activites_balloon}${Emojis.emotion_red_heart}',
|
||||
body:
|
||||
'Simple body with a bunch of Emojis! ${Emojis.transport_police_car} ${Emojis.animals_dog} ${Emojis.flag_UnitedStates} ${Emojis.person_baby}',
|
||||
largeIcon:
|
||||
'https://cdn.britannica.com/72/232772-050-4E3D86CC/mind-blown-emoji-head-exploding-emoticon.jpg',
|
||||
notificationLayout: NotificationLayout.BigPicture,
|
||||
wakeUpScreen: true,
|
||||
category: NotificationCategory.Alarm,
|
||||
payload: {
|
||||
'title': 'Notification Title',
|
||||
'body': 'Notification Body',
|
||||
'image': 'path/to/smallImage.png', // Path to small image
|
||||
'largeImage': 'path/to/largeImage.png', // Path to large image
|
||||
}),
|
||||
schedule: NotificationCalendar(
|
||||
hour: time.hour,
|
||||
minute: time.minute,
|
||||
// timezone: await AwesomeNotifications().getLocalTimeZoneIdentifier()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class FirebaseNotificationHandler {
|
|||
// LocalNotificationService.initialize();
|
||||
// LocalNotificationService.showBigPictureNotification();
|
||||
// LocalNotificationService.display(message);
|
||||
AwsomeNotificationHandler().main();
|
||||
AwsomeNotificationHandler().alarm();
|
||||
AwsomeNotificationHandler().show(message);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@ import 'package:didvan/config/design_config.dart';
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/models/widget_response.dart';
|
||||
import 'package:didvan/providers/theme.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/services/app_initalizer.dart';
|
||||
import 'package:didvan/services/network/request.dart';
|
||||
import 'package:didvan/services/network/request_helper.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/views/home/bookmarks/bookmarks.dart';
|
||||
import 'package:didvan/views/home/categories/categories_page.dart';
|
||||
|
|
@ -17,6 +20,8 @@ import 'package:didvan/views/widgets/ink_wrapper.dart';
|
|||
import 'package:didvan/views/widgets/logo_app_bar.dart';
|
||||
import 'package:didvan/views/widgets/didvan/bnb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:home_widget/home_widget.dart';
|
||||
import 'package:persian_number_utility/persian_number_utility.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
|
|
@ -26,7 +31,8 @@ class Home extends StatefulWidget {
|
|||
State<Home> createState() => _HomeState();
|
||||
}
|
||||
|
||||
class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
|
||||
class _HomeState extends State<Home>
|
||||
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
|
||||
late final TabController _tabController;
|
||||
|
||||
@override
|
||||
|
|
@ -49,10 +55,47 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
|
|||
super.initState();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<void> _fetchWidget() async {
|
||||
final service = RequestService(
|
||||
RequestHelper.widgetNews(),
|
||||
);
|
||||
await service.httpGet();
|
||||
List<WidgetResponse> responseList = [];
|
||||
if (service.isSuccess) {
|
||||
final favourites = service.data('content');
|
||||
HomeWidget.saveWidgetData("token",
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwicm9sZUlkIjo0LCJhcHBJZCI6MCwiaWF0IjoxNzEzOTM1NzkwfQ.i-SO9tLy0M9j-_C2Wh8tdp01vtYGlDZIBFPygglHQF0");
|
||||
for (var i = 0; i < favourites.length; i++) {
|
||||
HomeWidget.saveWidgetData(
|
||||
"id${i + 1}", WidgetResponse.fromJson(favourites[i]).id.toString());
|
||||
HomeWidget.saveWidgetData("title${i + 1}",
|
||||
WidgetResponse.fromJson(favourites[i]).title.toString());
|
||||
HomeWidget.saveWidgetData(
|
||||
"createdAt${i + 1}",
|
||||
DateTime.parse(
|
||||
WidgetResponse.fromJson(favourites[i]).createdAt.toString())
|
||||
.toPersianDateStr());
|
||||
HomeWidget.saveWidgetData("type${i + 1}",
|
||||
WidgetResponse.fromJson(favourites[i]).type.toString());
|
||||
HomeWidget.saveWidgetData("link${i + 1}",
|
||||
WidgetResponse.fromJson(favourites[i]).link.toString());
|
||||
HomeWidget.saveWidgetData("category${i + 1}",
|
||||
WidgetResponse.fromJson(favourites[i]).category.toString());
|
||||
HomeWidget.saveWidgetData("image${i + 1}",
|
||||
WidgetResponse.fromJson(favourites[i]).image.toString());
|
||||
}
|
||||
|
||||
HomeWidget.updateWidget(
|
||||
androidName: "FavWidget",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_fetchWidget();
|
||||
|
||||
return Scaffold(
|
||||
appBar: const LogoAppBar(),
|
||||
body: Consumer<HomeState>(
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ class _SplashState extends State<Splash> {
|
|||
|
||||
Future<void> _initialize() async {
|
||||
try {
|
||||
var v = navigatorKey.currentContext;
|
||||
ActionSheetUtils.context = navigatorKey.currentContext!;
|
||||
if (kIsWeb) {
|
||||
html.window.onBeforeUnload.listen((event) {
|
||||
|
|
|
|||
24
pubspec.lock
24
pubspec.lock
|
|
@ -9,6 +9,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.33"
|
||||
android_intent_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: android_intent_plus
|
||||
sha256: "2bfdbee8d65e7c26f88b66f0a91f2863da4d3596d8a658b4162c8de5cf04b074"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
animated_custom_dropdown:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -510,6 +518,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.23.8"
|
||||
get:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: get
|
||||
sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.6"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -518,6 +534,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
home_widget:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: home_widget
|
||||
sha256: "29565bfee4b32eaf9e7e8b998d504618b779a74b2b1ac62dd4dac7468e66f1a3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ dependencies:
|
|||
flutter_local_notifications: ^17.1.2
|
||||
awesome_notifications_core: ^0.9.0
|
||||
awesome_notifications: any
|
||||
home_widget: ^0.5.0
|
||||
android_intent_plus: ^5.0.2
|
||||
get: ^4.6.6
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue