style: make better style

This commit is contained in:
2026-06-05 01:36:57 +03:30
parent 1ba6062c86
commit 43427ae420
7 changed files with 348 additions and 118 deletions
+157
View File
@@ -0,0 +1,157 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="true" />
<package name="androidx" withSubpackages="true" static="true" />
<package name="com" withSubpackages="true" static="true" />
<package name="junit" withSubpackages="true" static="true" />
<package name="net" withSubpackages="true" static="true" />
<package name="org" withSubpackages="true" static="true" />
<package name="java" withSubpackages="true" static="true" />
<package name="javax" withSubpackages="true" static="true" />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="androidx" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>
+5
View File
@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" /> <bytecodeTargetLevel target="21" />
</component> </component>
</project> </project>
+2 -1
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">
Generated
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>
@@ -1,4 +1,5 @@
package com.approagency.drug.data.remote package com.approagency.drug.data.remote
import com.approagency.drug.domain.model.PharmacyItem import com.approagency.drug.domain.model.PharmacyItem
import org.jsoup.Jsoup import org.jsoup.Jsoup
@@ -7,31 +8,48 @@ object PharmacyHtmlParser {
fun parse(html: String): List<PharmacyItem> { fun parse(html: String): List<PharmacyItem> {
val items = mutableListOf<PharmacyItem>() val items = mutableListOf<PharmacyItem>()
val doc = Jsoup.parse(html) val doc = Jsoup.parse(html)
val rows = doc.select("table#TBL_patientReferral tbody tr") val table = doc.select("table#TBL_patientReferral").first() ?: return emptyList()
// تشخیص ساختار بر اساس سربرگ جدول (یک بار برای کل جدول)
val hasGuaranteeColumn = hasGuaranteeColumnInHeader(table)
val rows = table.select("tbody tr")
for (row in rows) { for (row in rows) {
val cells = row.select("td") val cells = row.select("td")
if (cells.size < 3) continue if (cells.size < 3) continue
// ستون 0: اطلاعات برند // ایندکس ستون‌ها بر اساس وجود ستون تضمین
val brandCell = cells[0] val brandIndex = if (hasGuaranteeColumn) 1 else 0
val pharmacyIndex = if (hasGuaranteeColumn) 2 else 1
val locationIndex = if (hasGuaranteeColumn) 3 else 2
// ستون برند
val brandCell = cells[brandIndex]
val brandLink = brandCell.select("a").first() val brandLink = brandCell.select("a").first()
val brandName = brandLink?.text()?.trim() ?: "" val brandName = brandLink?.text()?.trim() ?: ""
val brandUrl = brandLink?.attr("href")?.trim() ?: "" val brandUrl = brandLink?.attr("href")?.trim() ?: ""
val brandId = extractIdFromUrl(brandUrl, "/B-(\\d+)/?") val brandId = extractIdFromUrl(brandUrl, "/B-(\\d+)/?")
// ستون 1: اطلاعات داروخانه // ستون داروخانه
val pharmacyCell = cells[1] val pharmacyCell = cells[pharmacyIndex]
val pharmacyLink = pharmacyCell.select("a").first() val pharmacyLinks = pharmacyCell.select("a")
// پیدا کردن لینک داروخانه (لینکی که "اطلاعات تماس" نباشد)
val pharmacyLink = pharmacyLinks.firstOrNull {
!it.text().contains("اطلاعات تماس")
}
val pharmacyName = pharmacyLink?.text()?.trim() ?: "" val pharmacyName = pharmacyLink?.text()?.trim() ?: ""
val pharmacyUrl = pharmacyLink?.attr("href")?.trim() ?: "" val pharmacyUrl = pharmacyLink?.attr("href")?.trim() ?: ""
val pharmacyId = extractIdFromUrl(pharmacyUrl, "/ph-(\\d+)/?") val pharmacyId = extractIdFromUrl(pharmacyUrl, "/ph-(\\d+)/?")
// ستون 2: موقعیت // ستون موقعیت
val locationText = cells[2].text().trim() val locationCell = cells[locationIndex]
val parts = locationText.split("شهر") val locationText = locationCell.text().trim()
val province = parts.getOrNull(0)?.replace("استان", "")?.trim() ?: ""
val city = parts.getOrNull(1)?.trim() ?: "" // استخراج استان و شهر
val province = extractProvince(locationText)
val city = extractCity(locationText)
if (brandName.isNotBlank() && pharmacyName.isNotBlank()) { if (brandName.isNotBlank() && pharmacyName.isNotBlank()) {
items.add( items.add(
@@ -52,6 +70,32 @@ object PharmacyHtmlParser {
return items return items
} }
/**
* تشخیص وجود ستون تضمین موجودی با بررسی سربرگ جدول
*/
private fun hasGuaranteeColumnInHeader(table: org.jsoup.nodes.Element): Boolean {
val headers = table.select("thead th")
if (headers.isEmpty()) return false
// بررسی می‌کنیم که آیا اولین ستون حاوی متن "تضمین" است
val firstHeaderText = headers.firstOrNull()?.text()?.trim() ?: ""
return firstHeaderText.contains("تضمین") || firstHeaderText.contains("موجودی")
}
private fun extractProvince(locationText: String): String {
// الگو: "استان تهران" یا "استان اصفهان"
val provincePattern = "استان\\s*(\\S+)".toRegex()
val match = provincePattern.find(locationText)
return match?.groupValues?.get(1)?.trim() ?: ""
}
private fun extractCity(locationText: String): String {
// الگو: "شهر تهران" یا "شهر اصفهان" یا "شهر پردیس"
val cityPattern = "شهر\\s*(.+)".toRegex()
val match = cityPattern.find(locationText)
return match?.groupValues?.get(1)?.trim() ?: ""
}
private fun extractIdFromUrl(url: String, pattern: String): String { private fun extractIdFromUrl(url: String, pattern: String): String {
val regex = pattern.toRegex() val regex = pattern.toRegex()
return regex.find(url)?.groupValues?.get(1) ?: "" return regex.find(url)?.groupValues?.get(1) ?: ""
@@ -1,6 +1,7 @@
package com.approagency.drug.presentation.components package com.approagency.drug.presentation.components
import android.annotation.SuppressLint
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -8,6 +9,7 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
@@ -15,12 +17,15 @@ import androidx.compose.ui.unit.dp
import com.approagency.drug.domain.model.PharmacyItem import com.approagency.drug.domain.model.PharmacyItem
import com.approagency.drug.presentation.common.CustomBox import com.approagency.drug.presentation.common.CustomBox
import com.approagency.drug.presentation.common.CustomModalBottomSheet import com.approagency.drug.presentation.common.CustomModalBottomSheet
import com.approagency.drug.presentation.common.Loading
import com.approagency.drug.presentation.viewModel.PharmacyState import com.approagency.drug.presentation.viewModel.PharmacyState
import com.approagency.drug.presentation.viewModel.PharmacyViewModel import com.approagency.drug.presentation.viewModel.PharmacyViewModel
import com.approagency.drug.utils.provinces import com.approagency.drug.utils.provinces
import com.vada.caller.ui.theme.LocalDime import com.vada.caller.ui.theme.LocalDime
import com.vada.caller.ui.theme.dime
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@SuppressLint("ConfigurationScreenWidthHeight")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun PharmacyBottomSheet( fun PharmacyBottomSheet(
@@ -55,20 +60,22 @@ fun PharmacyBottomSheet(
scope = scope scope = scope
) { ) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
Column( LazyColumn(
modifier = Modifier modifier = Modifier.fillMaxHeight()
.fillMaxWidth() .fillMaxWidth().heightIn(min = 400.dp)
.padding(16.dp), .padding(MaterialTheme.dime.md),
verticalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.spacedBy(MaterialTheme.dime.xl)
) { ) {
// عنوان item {
Text( Text(
text = "جستجوی دارو در داروخانه‌ها", text = "جستجوی دارو در داروخانه‌ها",
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
fontSize = MaterialTheme.typography.titleMedium.fontSize fontSize = MaterialTheme.typography.titleMedium.fontSize
) )
}
// عنوان
// انتخاب استان item {
ExposedDropdownMenuBox( ExposedDropdownMenuBox(
expanded = showProvinceDropdown, expanded = showProvinceDropdown,
onExpandedChange = { showProvinceDropdown = it } onExpandedChange = { showProvinceDropdown = it }
@@ -102,23 +109,25 @@ fun PharmacyBottomSheet(
} }
} }
} }
}
// انتخاب استان
Spacer(modifier = Modifier.height(8.dp))
// نمایش نتایج // نمایش نتایج
when (val state = pharmacyState) { when (val state = pharmacyState) {
PharmacyState.Loading -> { PharmacyState.Loading -> {
item {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(200.dp), .height(400.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
CircularProgressIndicator( Loading()
modifier = Modifier.size(32.dp) Spacer(modifier = Modifier.height(MaterialTheme.dime.xl))
)
Spacer(modifier = Modifier.height(8.dp))
Text( Text(
text = "در حال جستجو...", text = "در حال جستجو...",
fontSize = MaterialTheme.typography.bodySmall.fontSize fontSize = MaterialTheme.typography.bodySmall.fontSize
@@ -127,12 +136,15 @@ fun PharmacyBottomSheet(
} }
} }
}
is PharmacyState.Success -> { is PharmacyState.Success -> {
if (state.items.isEmpty()) { if (state.items.isEmpty()) {
item {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(200.dp), .height(400.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Text( Text(
@@ -141,29 +153,38 @@ fun PharmacyBottomSheet(
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f) color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
) )
} }
} else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.weight(1f),
) {
items(state.items) { pharmacy ->
PharmacyResultItem(pharmacy = pharmacy)
} }
} else {
items(state.items)
{ pharmacy ->
PharmacyResultItem(pharmacy = pharmacy)
}
item { item {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(MaterialTheme.dime.md))
Text( Text(
text = "تعداد کل: ${state.items.size} داروخانه", text = "تعداد کل: ${state.items.size} داروخانه",
fontSize = MaterialTheme.typography.bodySmall.fontSize, fontSize = MaterialTheme.typography.bodySmall.fontSize,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f), color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = MaterialTheme.dime.xs)
) )
} }
} // LazyColumn(
// verticalArrangement = Arrangement.spacedBy(8.dp),
// modifier = Modifier,
// ) {
// items(state.items) { pharmacy ->
// PharmacyResultItem(pharmacy = pharmacy)
// }
//
//
// }
} }
} }
is PharmacyState.Error -> { is PharmacyState.Error -> {
item {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -186,6 +207,8 @@ fun PharmacyBottomSheet(
} }
} }
}
PharmacyState.Idle -> {} PharmacyState.Idle -> {}
} }
} }
@@ -201,7 +224,7 @@ fun PharmacyResultItem(
) { ) {
val dime = LocalDime.current val dime = LocalDime.current
CustomBox ( CustomBox(
modifier = modifier.fillMaxWidth(), modifier = modifier.fillMaxWidth(),
) { ) {
Column( Column(