30-02-1403 / Rhmn / release test 1.

This commit is contained in:
OkaykOrhmn 2024-05-20 17:19:28 +03:30
parent 26e9acc178
commit 3c01853118
64 changed files with 386 additions and 1331 deletions

View File

@ -1,94 +0,0 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 34
ndkVersion "25.1.8937393"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.didvan.didvanapp"
minSdkVersion 24
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
lintOptions {
disable 'InvalidPackage'
checkReleaseBuilds false
}
buildFeatures {
viewBinding true
}
}
flutter {
source '../..'
}
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'
implementation 'com.android.support:cardview-v7:28.0.0'
}

View File

@ -1,39 +0,0 @@
{
"project_info": {
"project_number": "935017686266",
"project_id": "didvan-9b7da",
"storage_bucket": "didvan-9b7da.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:935017686266:android:f9cbc9aba8e3d65ed2d543",
"android_client_info": {
"package_name": "com.didvan.didvanapp"
}
},
"oauth_client": [
{
"client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "935017686266-lebnol7rb05oi9h0mripb41c892d2gij.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

View File

@ -1,7 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.didvan.didvanapp">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -1,94 +0,0 @@
<?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.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
<application
android:icon="@mipmap/ic_launcher"
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"/>
<activity
android:name=".MainActivity"
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
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" />
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<!--
Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame.
-->
<intent-filter>
<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" />
<service
android:name=".MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.messaging.RECEIVE" />
</intent-filter>
</service>
</application>
</manifest>

View File

@ -1,144 +0,0 @@
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.MemoryPolicy
import com.squareup.picasso.NetworkPolicy
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
import java.lang.Exception
/**
* 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)
try {
Picasso.get()
.load("https://api.didvan.app${responses[0].image}?accessToken=${token}")
.transform(RoundedTransformation(10, 0))
.networkPolicy(NetworkPolicy.NO_STORE)
.memoryPolicy(MemoryPolicy.NO_STORE)
.error(R.drawable.test)
.resize(100,100)
.into(this, R.id.first_image, appWidgetIds);
} catch (e: Exception) {
}
try {
Picasso.get()
.load("https://api.didvan.app${responses[1].image}?accessToken=${token}")
.transform(RoundedTransformation(10, 0))
.networkPolicy(NetworkPolicy.NO_STORE)
.memoryPolicy(MemoryPolicy.NO_STORE)
.error(R.drawable.test)
.resize(100,100)
.into(this, R.id.middle_image, appWidgetIds);
} catch (e: Exception) {
}
try {
Picasso.get()
.load("https://api.didvan.app${responses[2].image}?accessToken=${token}")
.transform(RoundedTransformation(10, 0))
.networkPolicy(NetworkPolicy.NO_STORE)
.memoryPolicy(MemoryPolicy.NO_STORE)
.error(R.drawable.test)
.resize(100,100)
.into(this, R.id.last_image, appWidgetIds);
} catch (e: Exception) {
}
// 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, rowFirst)
val rowMiddle = HomeWidgetBackgroundIntent.getBroadcast(
context,
Uri.parse("myAppWidget://rowMiddle"),
)
setOnClickPendingIntent(R.id.middle_row, rowMiddle)
val rowLast = HomeWidgetBackgroundIntent.getBroadcast(
context,
Uri.parse("myAppWidget://rowLast"),
)
setOnClickPendingIntent(R.id.last_row, rowLast)
}
appWidgetManager.updateAppWidget(widgetId, views)
}
}
}

View File

@ -1,43 +0,0 @@
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)"
}
}

View File

@ -1,21 +0,0 @@
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 = "",
)

View File

@ -1,6 +0,0 @@
package com.didvan.didvanapp
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,10 +0,0 @@
<?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>

View File

@ -1,10 +0,0 @@
<?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>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="19dp"
android:viewportWidth="18"
android:viewportHeight="19">
<path
android:pathData="M0.281,11.359C0.281,12.309 2.109,15.894 3.305,15.894C3.445,15.894 3.586,15.859 3.727,15.754L4.887,15.086C5.273,15.367 5.66,15.613 6.082,15.789V17.125C6.082,17.512 6.328,17.863 6.715,17.969C7.488,18.18 8.262,18.25 9.035,18.25C9.809,18.25 10.582,18.18 11.356,17.934C11.707,17.828 11.988,17.477 11.988,17.09V15.754C12.41,15.578 12.797,15.332 13.184,15.051L14.344,15.719C14.484,15.824 14.625,15.859 14.766,15.859C15.996,15.859 17.754,12.098 17.754,11.359C17.754,11.078 17.578,10.797 17.297,10.621L16.137,9.953C16.172,9.742 16.172,9.496 16.172,9.25C16.172,9.039 16.172,8.793 16.137,8.582L17.297,7.914C17.578,7.738 17.754,7.457 17.754,7.176C17.754,6.227 15.926,2.641 14.766,2.641C14.625,2.641 14.484,2.676 14.344,2.781L13.184,3.449C12.797,3.168 12.41,2.922 11.988,2.746V1.41C11.988,1.023 11.707,0.672 11.356,0.566C10.582,0.355 9.809,0.25 9,0.25C8.227,0.25 7.453,0.355 6.68,0.566C6.328,0.672 6.047,1.023 6.047,1.41V2.746C5.625,2.922 5.238,3.168 4.852,3.449L3.691,2.781C3.551,2.676 3.41,2.641 3.27,2.641C2.039,2.641 0.281,6.402 0.281,7.176C0.281,7.457 0.457,7.738 0.738,7.914L1.898,8.582C1.863,8.793 1.863,9.039 1.863,9.25C1.863,9.496 1.863,9.742 1.898,9.918L0.738,10.586C0.457,10.762 0.281,11.043 0.281,11.359ZM3.41,13.961C2.883,13.328 2.426,12.555 2.145,11.746L3.656,10.867C3.586,9.988 3.551,9.602 3.551,9.25C3.551,8.898 3.586,8.547 3.656,7.668L2.145,6.789C2.426,5.98 2.883,5.207 3.41,4.574L4.957,5.453C6.434,4.363 6.082,4.574 7.734,3.836V2.078C8.051,2.008 8.473,1.938 9,1.938C9.387,1.938 9.844,1.973 10.301,2.078V3.836C11.953,4.574 11.602,4.363 13.078,5.453L14.625,4.539C15.152,5.207 15.609,5.98 15.891,6.789L14.379,7.668C14.449,8.547 14.484,8.898 14.484,9.25C14.484,9.637 14.449,9.988 14.379,10.867L15.891,11.711C15.609,12.555 15.152,13.293 14.625,13.961L13.078,13.047C11.602,14.137 11.953,13.926 10.301,14.664V16.422C10.019,16.492 9.563,16.563 9.035,16.563C8.648,16.563 8.191,16.527 7.734,16.422V14.664C6.082,13.926 6.434,14.137 4.957,13.047L3.41,13.961ZM9,5.875C7.172,5.875 5.625,7.387 5.625,9.25C5.625,11.078 7.172,12.625 9,12.625C10.863,12.625 12.375,11.078 12.375,9.25C12.375,7.387 10.863,5.875 9,5.875ZM9,10.938C8.086,10.938 7.313,10.199 7.313,9.25C7.313,8.336 8.086,7.563 9,7.563C9.949,7.563 10.688,8.336 10.688,9.25C10.688,10.199 9.949,10.938 9,10.938Z"
android:fillColor="#195D80"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,320 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Widget.Android.AppWidget.Container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:theme="@style/Theme.Android.AppWidgetContainer">
<LinearLayout
android:id="@+id/root_lay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:orientation="vertical"
>
<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="24dp"
android:layout_height="24dp"
android:layout_alignParentLeft="true"
android:src="@drawable/setting" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
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:scaleType="fitXY"
android:src="@drawable/logo_v3" />
</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="wrap_content"
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:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/test" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
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="wrap_content"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:ellipsize="end"
android:fontFamily="@font/d"
android:maxLines="2"
android:text=" تحلیل شکاف فناوری صنعت فولاد ایران تحلیل شکاف فناوری صنعت فولاد ایران"
android:textColor="#012348"
android:textSize="14sp"
android:textStyle="bold" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2">
<TextView
android:id="@+id/first_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_gravity="center_vertical"
android:layout_weight="3"
android:fontFamily="@font/d"
android:gravity="center_vertical"
android:text="۳ دقیقه مطالعه"
android:textColor="#666666"
android:textSize="12dp" />
<TextView
android:id="@+id/first_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:layout_weight="4"
android:fontFamily="@font/d"
android:gravity="center_vertical"
android:text="رادار فناوری"
android:textColor="#292929"
android:textSize="12dp" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="12dp"
android:background="#E0E0E0" />
<RelativeLayout
android:id="@+id/middle_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/test" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
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="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:layout_marginBottom="8dp"
android:fontFamily="@font/d"
android:maxLines="2"
android:text=" تحلیل شکاف فناوری صنعت فولاد ایران تحلیل شکاف فناوری صنعت فولاد ایران"
android:textColor="#012348"
android:textSize="14sp"
android:textStyle="bold" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2">
<TextView
android:id="@+id/middle_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_gravity="center_vertical"
android:fontFamily="@font/d"
android:gravity="center_vertical"
android:text="۳ دقیقه مطالعه"
android:textColor="#666666"
android:textSize="12dp"
/>
<TextView
android:id="@+id/middle_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:fontFamily="@font/d"
android:gravity="center_vertical"
android:text="رادار فناوری"
android:textColor="#292929"
android:textSize="12dp" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="12dp"
android:background="#E0E0E0" />
<RelativeLayout
android:id="@+id/last_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/test" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/last_image"
android:layout_centerInParent="true"
android:orientation="vertical">
<TextView
android:id="@+id/last_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginBottom="8dp"
android:ellipsize="end"
android:fontFamily="@font/d"
android:maxLines="2"
android:text=" تحلیل شکاف فناوری صنعت فولاد ایران تحلیل شکاف فناوری صنعت فولاد ایران"
android:textColor="#012348"
android:textSize="14sp"
android:textStyle="bold" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
>
<TextView
android:id="@+id/last_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_gravity="center_vertical"
android:fontFamily="@font/d"
android:gravity="center_vertical"
android:text="۳ دقیقه مطالعه"
android:textColor="#666666"
android:textSize="12dp" />
<TextView
android:id="@+id/last_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:fontFamily="@font/d"
android:gravity="center_vertical"
android:text="رادار فناوری"
android:textColor="#292929"
android:textSize="12dp"
/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</FrameLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,13 +0,0 @@
<?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="targetCellWidth">4</dimen>
<dimen name="targetCellHeight">3</dimen>
<dimen name="minWidth">250dp</dimen>
<dimen name="minHeight">180dp</dimen>
</resources>

View File

@ -1,13 +0,0 @@
<?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="targetCellWidth">4</dimen>
<dimen name="targetCellHeight">3</dimen>
<dimen name="minWidth">250dp</dimen>
<dimen name="minHeight">250dp</dimen>
</resources>

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -1,14 +0,0 @@
<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>

View File

@ -1,13 +0,0 @@
<?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="targetCellWidth">4</dimen>
<dimen name="targetCellHeight">4</dimen>
<dimen name="minWidth">250dp</dimen>
<dimen name="minHeight">250dp</dimen>
</resources>

View File

@ -1,13 +0,0 @@
<?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="targetCellWidth">4</dimen>
<dimen name="targetCellHeight">4</dimen>
<dimen name="minWidth">250dp</dimen>
<dimen name="minHeight">250dp</dimen>
</resources>

View File

@ -1,14 +0,0 @@
<?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="targetCellWidth">4</dimen>
<dimen name="targetCellHeight">4</dimen>
<dimen name="minWidth">300dp</dimen>
<dimen name="minHeight">300dp</dimen>
</resources>

View File

@ -1,7 +0,0 @@
<resources>
<declare-styleable name="AppWidgetAttrs">
<attr name="appWidgetPadding" format="dimension" />
<attr name="appWidgetInnerRadius" format="dimension" />
<attr name="appWidgetRadius" format="dimension" />
</declare-styleable>
</resources>

View File

@ -1,6 +0,0 @@
<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>

View File

@ -1,14 +0,0 @@
<?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="targetCellWidth">4</dimen>
<dimen name="targetCellHeight">4</dimen>
<dimen name="minWidth">250dp</dimen>
<dimen name="minHeight">180dp</dimen>
</resources>

View File

@ -1,6 +0,0 @@
<?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>

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
<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>

View File

@ -1,17 +0,0 @@
<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>

View File

@ -1,13 +0,0 @@
<?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="@dimen/minWidth"
android:minHeight="@dimen/minHeight"
android:previewImage="@drawable/favwidg"
android:resizeMode="horizontal|vertical"
android:targetCellWidth="4"
android:targetCellHeight="4"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen" />

View File

@ -1,7 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.didvan.didvanapp">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

BIN
lib/assets/icons/prof.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -148,8 +148,8 @@ class _TextThemeData {
extension DidvanColorScheme on ColorScheme {
// Secondary colors
Color get secondaryDisabled => brightness == Brightness.dark
? const Color(0xFF703848)
: const Color(0xFFFFC8D7);
? const Color(0xFFFFC8D7)
: const Color(0xFF703848);
Color get white => const Color(0xFFFFFFFF);
Color get focused => brightness == Brightness.dark
@ -161,6 +161,9 @@ extension DidvanColorScheme on ColorScheme {
Color get focusedBorder => brightness == Brightness.dark
? const Color(0xFF9FB2C2)
: const Color(0xFF195D80);
Color get checkFav => brightness == Brightness.dark
? const Color(0xFF007EA7)
: const Color(0xFF1B3C59);
Color get title => brightness == Brightness.dark
? const Color(0xFFD6D6D6)
: const Color(0xFF1B3C59);
@ -189,7 +192,7 @@ extension DidvanColorScheme on ColorScheme {
? const Color(0xFF333333)
: const Color(0xFFE0E0E0);
Color get secondCTA => brightness == Brightness.dark
? const Color(0xFF474747)
? const Color(0xFF202224)
: const Color(0xFFF5F5F5);
Color get splash => brightness == Brightness.dark
? const Color(0xFF333333)
@ -200,6 +203,9 @@ extension DidvanColorScheme on ColorScheme {
Color get overlay => brightness == Brightness.dark
? const Color(0xFF0F1011)
: const Color(0xFF292929);
Color get surface => brightness == Brightness.dark
? const Color(0xFF191919)
: const Color(0xFFffffff);
Color get yellow => const Color(0XFFEAA92A);
// Error and success colors

View File

@ -126,6 +126,7 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
switch (value) {
case 'setting':
route = Routes.favouritesStep;
args = {"toTimer":false};
break;
case 'rowfirst':
row = 1;

View File

@ -6,6 +6,7 @@ class NotificationMessage {
String? type;
String? link;
String? image;
String? photo;
NotificationMessage(
{this.notificationType,
@ -14,7 +15,9 @@ class NotificationMessage {
this.id,
this.type,
this.link,
this.image});
this.image,
this.photo,
});
NotificationMessage.fromJson(Map<String, dynamic> json) {
notificationType = json['notificationType'];
@ -24,6 +27,7 @@ class NotificationMessage {
type = json['type'];
link = json['link'];
image = json['image'];
photo = json['photo'];
}
Map<String, dynamic> toJson() {
@ -35,6 +39,7 @@ class NotificationMessage {
data['type'] = this.type;
data['link'] = this.link;
data['image'] = this.image;
data['photo'] = this.photo;
return data;
}
Map<String, String> toPayload() {
@ -46,6 +51,7 @@ class NotificationMessage {
data['type'] = this.type!;
data['link'] = this.link!;
data['image'] = this.image!;
data['photo'] = this.photo!;
return data;
}
}

View File

@ -56,25 +56,6 @@ 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(
@ -93,14 +74,18 @@ class RouteGenerator {
return _createRoute(
ChangeNotifierProvider<CustomizeCategoryState>(
create: (context) => CustomizeCategoryState(),
child: FavoritesStep()),
child: FavoritesStep(
pageData: settings.arguments as Map<String, dynamic>,
)),
);
case Routes.notificationStatusStep:
return _createRoute(
ChangeNotifierProvider<CustomizeCategoryState>(
create: (context) => CustomizeCategoryState(),
child: NotificationStatusStep()),
child: NotificationStatusStep(
pageData: settings.arguments as Map<String, dynamic>,
)),
);
case Routes.authenticaion:
return _createRoute(

View File

@ -43,11 +43,12 @@ 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'});
// print('Authorization : Bearer $token');
// _headers.addAll({
// 'Authorization':
// 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwicm9sZUlkIjo0LCJhcHBJZCI6MCwiaWF0IjoxNzEzOTM1NzkwfQ.i-SO9tLy0M9j-_C2Wh8tdp01vtYGlDZIBFPygglHQF0'
// });
if (body != null) _requestBody = body;
}

View File

@ -59,8 +59,7 @@ class NotificationController {
'id': int.parse(data.id.toString()),
'args': const InfographyRequestArgs(page: 0),
'hasUnmarkConfirmation': false,
'goToComment':openComments
'goToComment': openComments
};
break;
case "news":
@ -71,8 +70,7 @@ class NotificationController {
'id': int.parse(data.id.toString()),
'args': const NewsRequestArgs(page: 0),
'hasUnmarkConfirmation': false,
'goToComment':openComments
'goToComment': openComments
};
break;
case "radar":
@ -83,8 +81,7 @@ class NotificationController {
'id': int.parse(data.id.toString()),
'args': const RadarRequestArgs(page: 0),
'hasUnmarkConfirmation': false,
'goToComment':openComments
'goToComment': openComments
};
break;
case "video":
@ -92,7 +89,7 @@ class NotificationController {
args = {
'type': 'podcast',
'id': int.parse(data.id.toString()),
'goToComment':openComments
'goToComment': openComments
};
break;
}
@ -105,13 +102,7 @@ class NotificationController {
}
}
if (route.isNotEmpty) {
if (data.notificationType.toString() == "1") {
navigatorKey.currentState!
.pushNamedIfNotCurrent(route, arguments: args);
} else {
navigatorKey.currentState!.pushNamedIfNotCurrent(route, arguments: args);
}
navigatorKey.currentState!.pushNamedIfNotCurrent(route, arguments: args);
}
// MyApp.navigatorKey.currentState?.pushNamedAndRemoveUntil('/notification-page',

View File

@ -96,46 +96,62 @@ class AwsomeNotificationHandler {
}
showNotificationTypeNews(NotificationMessage message) async {
DateTime time = await _getTime();
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
title: "\u200f ${message.title} \u200f",
// body: message.body.toString(),
notificationLayout: NotificationLayout.Default,
largeIcon: message.image.toString(),
payload: message.toPayload(),
color: const Color(0xFF007EA7)),
);
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
title: "\u200f ${message.title} \u200f",
// body: message.body.toString(),
notificationLayout: NotificationLayout.Default,
largeIcon: message.image.toString(),
payload: message.toPayload(),
color: const Color(0xFF007EA7)),
schedule: time.year != null
? null
: NotificationCalendar(
hour: time.hour,
minute: time.minute,
));
}
showNotificationTypeMessage(NotificationMessage message) async {
DateTime time = await _getTime();
AwesomeNotifications().createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
title: message.title.toString(),
body: "<b>${message.body.toString()}</b>",
largeIcon: message.image.toString(),
roundedLargeIcon: true,
payload: message.toPayload(),
notificationLayout: NotificationLayout.Inbox,
color: const Color(0xFF007EA7)),
// actionButtons: [
// NotificationActionButton(
// key: 'REPLY',
// label: 'جواب دادن',
// requireInputText: true,
// actionType: ActionType.SilentAction),
// NotificationActionButton(
// key: 'DISMISS',
// label: 'خوانده شده',
// actionType: ActionType.DismissAction,
// isDangerousOption: true)
// ]
);
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
channelKey: 'alerts',
actionType: ActionType.Default,
body:
"<b>${message.title.toString()}</b> ${message.body.toString()}",
largeIcon: message.photo.toString(),
roundedLargeIcon: true,
bigPicture: message.image.toString(),
payload: message.toPayload(),
notificationLayout: NotificationLayout.BigPicture,
color: const Color(0xFF007EA7)),
schedule: time.year != null
? null
: NotificationCalendar(
hour: time.hour,
minute: time.minute,
)
// actionButtons: [
// NotificationActionButton(
// key: 'REPLY',
// label: 'جواب دادن',
// requireInputText: true,
// actionType: ActionType.SilentAction),
// NotificationActionButton(
// key: 'DISMISS',
// label: 'خوانده شده',
// actionType: ActionType.DismissAction,
// isDangerousOption: true)
// ]
);
}
showNotificationTypeEmoji(NotificationMessage message) async {
@ -165,10 +181,14 @@ class AwsomeNotificationHandler {
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);
DateTime result = DateTime.now();
if (time.toString().isNotEmpty) {
DateFormat format = DateFormat("HH:mm");
DateTime dateTime = format.parse(time);
result = DateTime.now()
.copyWith(hour: dateTime.hour, minute: dateTime.minute);
}
return result;
} else {
return DateTime.now();

View File

@ -51,6 +51,8 @@ class FirebaseNotificationHandler {
debugPrint(
'User granted notifications permission: ${settings.authorizationStatus}');
// String? token = await FirebaseMessaging.instance.getToken();
// print("Firebase Token : ${token.toString()}");
// Handling background messages using the specified handler
// FirebaseMessaging.onBackgroundMessage(

View File

@ -11,6 +11,7 @@ class AuthenticationState extends CoreProvier {
String username = '';
String password = '';
String _verificationCode = '';
bool isShowCustomDialog = true;
set currentPageIndex(int value) {
_currentPageIndex = value;

View File

@ -82,14 +82,12 @@ class _PasswordInputState extends State<PasswordInput> {
if (mounted) {
Navigator.of(context).pushReplacementNamed(Routes.home);
}
_showCustomizeDialog();
_showResetPasswordDialog();
}
}
void _showResetPasswordDialog() {
ActionSheetUtils.openDialog(
data: ActionSheetData(
content: const DidvanText(
'خوش آمدید!\nبرای امنیت بیشتر، رمز عبور خود را تغییر دهید.',
@ -104,34 +102,37 @@ class _PasswordInputState extends State<PasswordInput> {
dismissTitle: 'بعدا',
),
);
_showCustomizeDialog();
}
void _showCustomizeDialog() {
void _showCustomizeDialog() {
ActionSheetUtils.openDialog(
data: ActionSheetData(
backgroundColor: Colors.white,
isBackgroundDropBlur: true,
backgroundColor: Theme.of(context).colorScheme.background,
isBackgroundDropBlur: true,
content: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWrapper(
onPressed: () => Navigator.of(ActionSheetUtils.context).pop,
child: const Icon(
onPressed:Navigator.of(ActionSheetUtils.context).pop,
child: Icon(
DidvanIcons.close_solid,
size: 24,
),
),
DidvanText(
'شخصی سازی برنامه',
'شخصی سازی محتوا',
style: Theme.of(context).textTheme.displaySmall,
color: Theme.of(context).colorScheme.title,
color: Theme.of(context).colorScheme.text,
),
const Icon(
DidvanIcons.close_regular,
size: 24,
color: Colors.transparent,
InkWrapper(
child: const Icon(
DidvanIcons.close_regular,
size: 24,
color: Colors.transparent,
),
),
],
),
@ -145,11 +146,11 @@ class _PasswordInputState extends State<PasswordInput> {
hasDismissButton: false,
onConfirmed: () => Navigator.of(ActionSheetUtils.context).pushNamed(
Routes.favouritesStep,
arguments: true,
arguments: {"toTimer":true},
),
confrimTitle: 'تایید',
),
);
}
}

View File

@ -115,6 +115,13 @@ class _CommentsState extends State<Comments> {
),
DidvanTitleDivider(
title: "نظرات پنهان شده",
color: Theme.of(context).colorScheme.primary,
icon: Icon(
commentsState.showPrivates
? DidvanIcons.angle_up_regular
: DidvanIcons.angle_down_regular,
color: Theme.of(context).colorScheme.primary,
),
onClick: () {
commentsState.showPrivates =
!commentsState.showPrivates;
@ -332,12 +339,12 @@ class _MessageBoxState extends State<_MessageBox> {
children: [
DidvanText(
"اشاره به",
color: Theme.of(context).colorScheme.inputText,
color: Theme.of(context).colorScheme.text,
style: Theme.of(context).textTheme.labelSmall,
),
DidvanText(
state.usersMentioned.name.toString(),
color: Theme.of(context).colorScheme.navigation,
color: Theme.of(context).colorScheme.text,
style: Theme.of(context).textTheme.bodySmall,
),
],

View File

@ -132,19 +132,22 @@ class CommentState extends State<Comment> {
children: [
Icon(
Icons.circle,
color: Theme.of(context)
.colorScheme
.secondary
.withOpacity(0.3),
color:
Theme.of(context).colorScheme.secondaryDisabled,
size: 18,
),
const SizedBox(width: 4),
DidvanText(
'در انتظار تایید',
color: Theme.of(context)
.colorScheme
.secondary
.withOpacity(0.3),
style: Theme.of(context)
.textTheme
.titleSmall!
.copyWith(
color: Theme.of(context)
.colorScheme
.secondaryDisabled),
color:
Theme.of(context).colorScheme.secondaryDisabled,
),
],
),

View File

@ -2,11 +2,13 @@ import 'package:didvan/models/customize_categories/favorites_response.dart';
import 'package:didvan/models/enums.dart';
import 'package:flutter/cupertino.dart';
import '../../models/view/alert_data.dart';
import '../../providers/core.dart';
import '../../routes/routes.dart';
import '../../services/app_home_widget/home_widget_repository.dart';
import '../../services/network/request.dart';
import '../../services/network/request_helper.dart';
import '../../utils/action_sheet.dart';
class CustomizeCategoryState extends CoreProvier {
CustomizeCategoryState() {
@ -17,6 +19,7 @@ class CustomizeCategoryState extends CoreProvier {
List<int> selectedNotifIds = [];
final List<FavoritesResponse> faves = [];
final List<FavoritesResponse> notifs = [];
bool toTimer = false;
Future<void> getFavourites() async {
appState = AppState.busy;
@ -81,9 +84,8 @@ class CustomizeCategoryState extends CoreProvier {
);
await service.put();
if (service.isSuccess) {
Navigator.of(context).pushNamed(
Routes.notificationStatusStep,
);
Navigator.of(context).pushNamed(Routes.notificationStatusStep,
arguments: {"toTimer": toTimer});
appState = AppState.idle;
await HomeWidgetRepository().fetchWidget();
@ -102,8 +104,17 @@ class CustomizeCategoryState extends CoreProvier {
);
await service.put();
if (service.isSuccess) {
Navigator.of(context).pop();
Navigator.of(context).pop();
if (toTimer) {
Navigator.of(context).pushNamed(Routes.notificationTime,
arguments: {"fromFav": toTimer});
} else {
Navigator.of(context).pop();
Navigator.of(context).pop();
ActionSheetUtils.showAlert(AlertData(
message: "تغییرات شما با موفقیت اعمال شد.",
aLertType: ALertType.success));
}
appState = AppState.idle;
await HomeWidgetRepository().fetchWidget();
return;
@ -112,7 +123,8 @@ class CustomizeCategoryState extends CoreProvier {
appState = AppState.failed;
}
Future<void> changeSelected(int index, List<FavoritesResponse> list,List<int> selectedIds) async {
Future<void> changeSelected(
int index, List<FavoritesResponse> list, List<int> selectedIds) async {
list[index].selected = !list[index].selected!;
selectedIds.clear();
for (var ls in list) {

View File

@ -20,7 +20,9 @@ import '../widgets/state_handlers/sliver_state_handler.dart';
import '../widgets/user_mention.dart';
class FavoritesStep extends StatefulWidget {
const FavoritesStep({super.key});
final Map<String, dynamic> pageData;
const FavoritesStep({super.key, required this.pageData});
@override
State<FavoritesStep> createState() => _FavoritesStepState();
@ -33,6 +35,9 @@ class _FavoritesStepState extends State<FavoritesStep> {
void initState() {
super.initState();
state = context.read<CustomizeCategoryState>();
if (widget.pageData['toTimer'] != null) {
state.toTimer = widget.pageData['toTimer'];
}
Future.delayed(
Duration.zero,
@ -50,7 +55,7 @@ class _FavoritesStepState extends State<FavoritesStep> {
DidvanScaffold(
appBarData: AppBarData(
hasBack: true,
title: 'شخصی‌سازی برنامه',
title: 'شخصی‌سازی محتوا',
),
physics: const BouncingScrollPhysics(),
hidePlayer: true,
@ -93,9 +98,10 @@ class _FavoritesStepState extends State<FavoritesStep> {
child: CustomizeCategoryCheckbox(
title: state.faves[index].name!,
value: state.faves[index].selected,
color: Theme.of(context).colorScheme.title,
checkColor: Theme.of(context).colorScheme.checkFav,
onChanged: (val) {
state.changeSelected(index, state.faves,state.selectedFavIds);
state.changeSelected(
index, state.faves, state.selectedFavIds);
})),
),
),

View File

@ -21,7 +21,9 @@ import '../widgets/state_handlers/sliver_state_handler.dart';
import '../widgets/user_mention.dart';
class NotificationStatusStep extends StatefulWidget {
const NotificationStatusStep({super.key});
final Map<String, dynamic> pageData;
const NotificationStatusStep({super.key, required this.pageData});
@override
State<NotificationStatusStep> createState() => _NotificationStatusStepState();
@ -34,6 +36,9 @@ class _NotificationStatusStepState extends State<NotificationStatusStep> {
void initState() {
super.initState();
state = context.read<CustomizeCategoryState>();
if (widget.pageData['toTimer'] != null) {
state.toTimer = widget.pageData['toTimer'];
}
Future.delayed(
Duration.zero,
@ -85,7 +90,8 @@ class _NotificationStatusStepState extends State<NotificationStatusStep> {
value: state.notifs[index].selected!,
title: state.notifs[index].name!,
onChanged: (val) {
state.changeSelected(index, state.notifs,state.selectedNotifIds);
state.changeSelected(index, state.notifs,
state.selectedNotifIds);
}),
index != state.notifs.length - 1
? Padding(

View File

@ -9,13 +9,14 @@ class CustomizeCategoryCheckbox extends StatefulWidget {
final String title;
final bool? value;
final double size;
final Color? color;
final Color? checkColor;
final Color? textColor;
final void Function(bool value) onChanged;
const CustomizeCategoryCheckbox({
Key? key,
required this.title,
required this.value,
required this.onChanged, this.size = 15, this.color,
required this.onChanged, this.size = 15, this.checkColor, this.textColor,
}) : super(key: key);
@override
@ -35,8 +36,11 @@ class _CustomizeCategoryCheckboxState extends State<CustomizeCategoryCheckbox> {
@override
Widget build(BuildContext context) {
Color? _color = widget.color;
_color ??= Theme.of(context).colorScheme.caption;
Color? _checkColor = widget.checkColor;
_checkColor ??= Theme.of(context).colorScheme.text;
Color? _textColor = widget.textColor;
_textColor ??= Theme.of(context).colorScheme.text;
return GestureDetector(
onTap: () {
@ -57,17 +61,17 @@ class _CustomizeCategoryCheckboxState extends State<CustomizeCategoryCheckbox> {
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(6),
border: Border.all(width: 1.0, color: _value? _color: Theme.of(context).colorScheme.caption),
border: Border.all(width: 1.0, color: _value? _checkColor: Theme.of(context).colorScheme.text),
),
margin: EdgeInsets.all(8),
child: AnimatedVisibility(
isVisible: _value,
duration: DesignConfig.mediumAnimationDuration,
child: Center(child: Icon(Icons.check,size: 12,color: _value? _color: Theme.of(context).colorScheme.caption,))
child: Center(child: Icon(Icons.check,size: 12,color: _value? _checkColor: Theme.of(context).colorScheme.text,))
),
),
), DidvanText(widget.title,fontSize: widget.size,color: _value? _color: Theme.of(context).colorScheme.caption, ),
), DidvanText(widget.title,fontSize: widget.size,color: _value? _textColor: Theme.of(context).colorScheme.text, ),
],
),
),

View File

@ -4,6 +4,7 @@ import 'package:didvan/models/enums.dart';
import 'package:didvan/models/users_mention.dart';
import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/views/customize_category/customize_category_state.dart';
import 'package:didvan/views/customize_category/widgets/customize_category_switch.dart';
import 'package:didvan/views/notification_time/notification_time_state.dart';
import 'package:didvan/views/notification_time/widgets/custom_cupertino_date_picker.dart';
import 'package:didvan/views/customize_category/widgets/customize_category_checkbox.dart';
@ -40,7 +41,14 @@ class _NotificationTimeState extends State<NotificationTime> {
void initState() {
super.initState();
state = context.read<NotificationTimeState>();
state.onTimeChanged = widget.pageData['onTimeChanged'];
if (widget.pageData['onTimeChanged'] != null) {
state.onTimeChanged = widget.pageData['onTimeChanged'];
}
if (widget.pageData['fromFav'] != null) {
state.fromFav = widget.pageData['fromFav'];
}
Future.delayed(
Duration.zero,
() => state.getTime(),
@ -56,7 +64,7 @@ class _NotificationTimeState extends State<NotificationTime> {
DidvanScaffold(
appBarData: AppBarData(
hasBack: true,
title: 'شخصی‌سازی برنامه',
title: 'زمان دریافت اعلان',
),
physics: const BouncingScrollPhysics(),
hidePlayer: true,
@ -66,26 +74,30 @@ class _NotificationTimeState extends State<NotificationTime> {
slivers: [],
children: [
Consumer<NotificationTimeState>(
builder: (context, state, child) => Column(
children: [
DidvanText(
"لطفا زمان دریافت اعلانات خود را مشخص کنید",
style: Theme.of(context).textTheme.bodyMedium,
),
state.appState == AppState.idle
? Container(
builder: (context, state, child) => state.appState ==
AppState.idle
? Column(
children: [
DidvanText(
"لطفا زمان دریافت اعلانات خود را مشخص کنید",
style: Theme.of(context).textTheme.bodyMedium,
),
Container(
margin: EdgeInsets.all(24),
height: 210,
child: CustomCupertinoDatePicker(
disable: state.isAnytime,
itemExtent: 64,
selectedTime: state.selectedTime,
selectedStyle: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(
color: Theme.of(context)
.colorScheme
.white),
color: state.isAnytime
? Color(0xFFC8E0F4)
: Theme.of(context)
.colorScheme
.white),
unselectedStyle:
Theme.of(context).textTheme.titleSmall,
disabledStyle: Theme.of(context)
@ -98,10 +110,30 @@ class _NotificationTimeState extends State<NotificationTime> {
onSelectedItemChanged: (date) {
state.selectedTime = date;
}),
)
: SizedBox(),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
border: Border.all(
color:
Theme.of(context).colorScheme.border,
width: 1),
borderRadius: BorderRadius.circular(18)),
child: DidvanSwitch(
value: state.isAnytime,
title: "دریافت آنی اعلانات",
onChanged: (val) {
state.isAnytime = val;
state.update();
}),
),
),
],
)
: SizedBox(),
)
],
),

View File

@ -1,20 +1,27 @@
import 'package:didvan/main.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../../models/day_time.dart';
import '../../models/view/alert_data.dart';
import '../../routes/routes.dart';
import '../../services/network/request.dart';
import '../../services/network/request_helper.dart';
import '../../utils/action_sheet.dart';
import '../../utils/date_time.dart';
import '../profile/general_settings/settings_state.dart';
class NotificationTimeState extends CoreProvier {
late DayTime selectedTime;
bool isAnytime = false;
bool fromFav = false;
late void Function( ) onTimeChanged;
late void Function() onTimeChanged = (){};
Future<void> getTime() async {
appState = AppState.busy;
@ -24,7 +31,11 @@ class NotificationTimeState extends CoreProvier {
);
await service.httpGet();
if (service.isSuccess) {
final time = service.data('time');
var time = service.data('time');
if (time.toString().isEmpty) {
time = "12:00";
isAnytime = true;
}
selectedTime = DateTimeUtils.handleDayTime(time);
appState = AppState.idle;
@ -39,7 +50,7 @@ class NotificationTimeState extends CoreProvier {
appState = AppState.busy;
final favoritesRequest = {
"time": DateTimeUtils.handleDayTimeReverse(selectedTime)
"time": isAnytime ? "" : DateTimeUtils.handleDayTimeReverse(selectedTime)
};
final service = RequestService(
RequestHelper.notificationTime(),
@ -49,9 +60,15 @@ class NotificationTimeState extends CoreProvier {
if (service.isSuccess) {
onTimeChanged();
// Navigator.of(context).pushNamed(
// Routes.notificationStatusStep,
// );
if (fromFav) {
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
} else {
Navigator.of(context).pop();
}
ActionSheetUtils.showAlert(AlertData(message: "تغییرات شما با موفقیت اعمال شد.",aLertType: ALertType.success));
appState = AppState.idle;
return;
}

View File

@ -16,6 +16,7 @@ class CustomCupertinoDatePicker extends StatefulWidget {
final TextStyle? unselectedStyle; // Text style of disabled item
final TextStyle? disabledStyle; // Minimum selectable date
final DayTime? selectedTime;
final bool disable;
const CustomCupertinoDatePicker({
Key? key,
@ -25,6 +26,7 @@ class CustomCupertinoDatePicker extends StatefulWidget {
this.selectedStyle,
this.unselectedStyle,
this.disabledStyle,
this.disable = false,
}) : super(key: key);
@override
@ -33,7 +35,7 @@ class CustomCupertinoDatePicker extends StatefulWidget {
}
class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
late DayTime selectedTime = DateTimeUtils.handleDayTime(
late DayTime selectedTime = DateTimeUtils.handleDayTime(
"${DateTime.now().hour.toString()}:${DateTime.now().minute.toString()}");
late int _selectedMeridiemIndex;
@ -57,7 +59,6 @@ class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
void initState() {
super.initState();
for (int i = 1; i < 12 + 1; i++) {
String twoDigitNumber = i.toString().padLeft(2, '0');
_timeH.add(twoDigitNumber);
@ -73,9 +74,8 @@ class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
_meridiemScrollController = FixedExtentScrollController();
_hourScrollController = FixedExtentScrollController();
_minuteScrollController = FixedExtentScrollController();
if(widget.selectedTime !=null){
if (widget.selectedTime != null) {
selectedTime = widget.selectedTime!;
}
_initDates();
}
@ -83,16 +83,16 @@ class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
void _initDates() {
_selectedMeridiemIndex = 0;
switch(selectedTime.meridiem){
switch (selectedTime.meridiem) {
case Meridiem.AM:
_selectedMeridiemIndex = 0;
_selectedHourIndex = int.parse(selectedTime.hour)-1;
_selectedHourIndex = int.parse(selectedTime.hour) - 1;
break;
case Meridiem.PM:
_selectedMeridiemIndex = 1;
_selectedHourIndex = (int.parse(selectedTime.hour)+12)-1;
_selectedHourIndex = (int.parse(selectedTime.hour) + 12) - 1;
break;
}
@ -123,7 +123,6 @@ class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
void _onSelectedItemChanged(int index, SelectorType type) {
switch (type) {
case SelectorType.meridiem:
_selectedMeridiemIndex = index; // if month is changed to february &
if (_selectedMeridiemIndex == 0) {
if (_selectedHourIndex > 12 - 1) {
@ -136,16 +135,14 @@ class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
_hourScrollController.jumpToItem(_selectedHourIndex);
}
}
if(index == 0){
if (index == 0) {
selectedTime.meridiem = Meridiem.AM;
}else{
} else {
selectedTime.meridiem = Meridiem.PM;
}
break;
case SelectorType.hour:
_selectedHourIndex = index; // if month is changed to february &
if (_selectedHourIndex > 12 - 1) {
_selectedMeridiemIndex = 1;
@ -171,98 +168,99 @@ class _CustomCupertinoDatePickerState extends State<CustomCupertinoDatePicker> {
/// check if the given day, month or year index is disabled
bool _isDisabled(int index, SelectorType type) {
switch (type) {
case SelectorType.meridiem:
break;
case SelectorType.hour:
break;
case SelectorType.minute:
break;
}
// switch (type) {
// case SelectorType.meridiem:
// break;
//
// case SelectorType.hour:
// break;
//
// case SelectorType.minute:
// break;
// }
return false;
}
@override
Widget build(BuildContext context) {
Color _shadow = Theme.of(context).colorScheme.background;
return Stack(
children: [
Positioned.fill(
child: Center(
child: Container(
height: 64,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(18)),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(),
VerticalDivider(
color: Colors.white,
),
VerticalDivider(
color: Colors.white,
),
SizedBox(),
],
return IgnorePointer(
ignoring: widget.disable,
child: Stack(
children: [
Positioned.fill(
child: Center(
child: Container(
height: 64,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary.withOpacity(widget.disable? 0.2: 1),
borderRadius: BorderRadius.circular(18)),
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(),
VerticalDivider(
color: Colors.white,
),
VerticalDivider(
color: Colors.white,
),
SizedBox(),
],
),
),
),
),
),
),
Row(
children: [
Expanded(child: _meridiemSelector()),
Expanded(child: _minuteSelector()),
Expanded(child: _hourSelector()),
],
),
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
height: 32,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
_shadow.withOpacity(1),
_shadow.withOpacity(0.9),
_shadow.withOpacity(0.8),
_shadow.withOpacity(0.6),
_shadow.withOpacity(0.5),
_shadow.withOpacity(0.4),
])),
)),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
height: 32,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
_shadow.withOpacity(1),
_shadow.withOpacity(0.9),
_shadow.withOpacity(0.8),
_shadow.withOpacity(0.6),
_shadow.withOpacity(0.5),
_shadow.withOpacity(0.4),
])),
)),
],
Row(
children: [
Expanded(child: _meridiemSelector()),
Expanded(child: _minuteSelector()),
Expanded(child: _hourSelector()),
],
),
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
height: 32,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
_shadow.withOpacity(1),
_shadow.withOpacity(0.9),
_shadow.withOpacity(0.8),
_shadow.withOpacity(0.6),
_shadow.withOpacity(0.5),
_shadow.withOpacity(0.4),
])),
)),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
height: 32,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
_shadow.withOpacity(1),
_shadow.withOpacity(0.9),
_shadow.withOpacity(0.8),
_shadow.withOpacity(0.6),
_shadow.withOpacity(0.5),
_shadow.withOpacity(0.4),
])),
)),
],
),
);
}

View File

@ -69,13 +69,14 @@ class _GeneralSettingsState extends State<GeneralSettings> {
onTap: () => Navigator.of(context).pushNamed(
Routes.notificationTime,
arguments: {
"fromFav": false,
'onTimeChanged': () => Future.delayed(
Duration.zero,
() => state.getTime(),
)
},
),
icon: DidvanIcons.notification_regular,
icon: DidvanIcons.notification_solid,
suffix: state.time,
// suffix: 'از${DateTimeUtils.normalizeTimeDuration(
// Duration(minutes: state.notificationTimeRange[0]),
@ -91,9 +92,9 @@ class _GeneralSettingsState extends State<GeneralSettings> {
child: MenuOption(
title: 'شخصی سازی محتوا',
onTap: () => Navigator.of(context).pushNamed(
Routes.favouritesStep,
),
icon: DidvanIcons.notification_regular,
Routes.favouritesStep,
arguments: {"toTimer": false}),
icon: DidvanIcons.note_solid,
// suffix: 'از${DateTimeUtils.normalizeTimeDuration(
// Duration(minutes: state.notificationTimeRange[0]),
// )} تا ${DateTimeUtils.normalizeTimeDuration(

View File

@ -4,12 +4,14 @@ import 'package:flutter/material.dart';
import 'text.dart';
import '../ink_wrapper.dart';
class DidvanTitleDivider extends StatelessWidget{
class DidvanTitleDivider extends StatelessWidget {
final String title;
final Icon? icon;
final Color? color;
final Function()? onClick;
const DidvanTitleDivider({super.key, required this.title, this.onClick});
const DidvanTitleDivider(
{super.key, required this.title, this.onClick, this.icon, this.color});
@override
Widget build(BuildContext context) {
@ -19,26 +21,36 @@ class DidvanTitleDivider extends StatelessWidget{
children: [
Expanded(
child: Divider(
height: 1,
color: Theme.of(context).colorScheme.border,
)),
height: 1,
color: Theme.of(context).colorScheme.border,
)),
Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: DidvanText(
title,
style: Theme.of(context).textTheme.bodySmall,
color: Theme.of(context).colorScheme.inputText,
child: Row(
children: [
DidvanText(
title,
style: Theme.of(context).textTheme.bodySmall,
color: color != null
? color!
: Theme.of(context).colorScheme.inputText,
),
icon != null
? Padding(
padding: const EdgeInsets.only(right: 8),
child: icon!,
)
: const SizedBox(),
],
),
),
Expanded(
child: Divider(
height: 1,
color: Theme.of(context).colorScheme.border,
)),
height: 1,
color: Theme.of(context).colorScheme.border,
)),
],
),
);
}
}
}