-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added webview for articles and athlete search
Jordan Akinpelu (akinpelud)
committed
Apr 10, 2023
1 parent
ec574f3
commit 7bbfc8e
Showing
19 changed files
with
731 additions
and
237 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
319 changes: 319 additions & 0 deletions
319
PowerOf10/app/src/main/java/com/example/powerof10/AthleteSearch.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,319 @@ | ||
package com.example.powerof10 | ||
|
||
import android.annotation.SuppressLint | ||
import android.app.Activity | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.net.Uri | ||
import android.os.Bundle | ||
import android.view.WindowInsetsAnimationController | ||
import android.view.WindowInsetsController | ||
import android.widget.Toast | ||
import androidx.activity.ComponentActivity | ||
import androidx.activity.compose.setContent | ||
import androidx.compose.animation.AnimatedVisibility | ||
import androidx.compose.foundation.* | ||
import androidx.compose.foundation.gestures.scrollable | ||
import androidx.compose.foundation.layout.* | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.material.* | ||
import androidx.compose.material.icons.Icons | ||
import androidx.compose.material.icons.filled.Menu | ||
import androidx.compose.material3.CenterAlignedTopAppBar | ||
import androidx.compose.material3.ExperimentalMaterial3Api | ||
import androidx.compose.material3.TopAppBarDefaults | ||
import androidx.compose.runtime.* | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.layout.ContentScale | ||
import androidx.compose.ui.platform.LocalContext | ||
import androidx.compose.ui.res.painterResource | ||
import androidx.compose.ui.text.font.FontWeight | ||
import androidx.compose.ui.text.style.TextOverflow | ||
import androidx.compose.ui.tooling.preview.Devices | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.unit.sp | ||
import androidx.navigation.NavController | ||
import androidx.navigation.compose.rememberNavController | ||
import com.example.powerof10.ui.theme.PowerOf10Theme | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.launch | ||
import kotlinx.coroutines.withContext | ||
import org.jsoup.Jsoup | ||
import org.jsoup.nodes.Document | ||
import org.jsoup.select.Elements | ||
import tech.devscast.validable.EmailValidable | ||
import tech.devscast.validable.delegates.validableEmail | ||
import tech.devscast.validable.withValidable | ||
import java.io.Serializable | ||
|
||
class AthleteSearch : ComponentActivity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContent { | ||
PowerOf10Theme { | ||
// A surface container using the 'background' color from the theme | ||
Surface( | ||
modifier = Modifier.fillMaxSize(), | ||
color = MaterialTheme.colors.background | ||
) { | ||
|
||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
suspend fun getHTML(firstName: String, lastName: String, club: String): Document { //retrieves the entire HTML page including tags using search parameters | ||
val html= "https://www.thepowerof10.info/athletes/athleteslookup.aspx?surname=$lastName&firstname=$firstName&club=$club" | ||
|
||
return withContext(Dispatchers.IO) { | ||
return@withContext Jsoup.connect(html).get() | ||
} | ||
|
||
} | ||
|
||
fun getAthletes(doc: Document,mContext: Context): Serializable? {//serializable = any data structure. Function converts html to a list of elements | ||
if (doc.getElementsByAttributeValueContaining("class","athleteprofilesubheader").isNotEmpty()){ //Checks if the link returned the athlete profile due to there being only 1 result | ||
val browserIntent = Intent(//opens the browser and takes user to the link | ||
Intent.ACTION_VIEW, | ||
Uri.parse( | ||
"https://www.thepowerof10.info/athletes/" + doc.getElementById("form1")?.attr("action") | ||
) | ||
) | ||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)// Starts browser intent to athlete profile | ||
mContext.startActivity(browserIntent) | ||
//println(doc.getElementById("form1")?.attr("action")) | ||
return "athlete found" | ||
} | ||
else if (doc.getElementsContainingText("Too many athletes found").isEmpty()){//if theres NOT too many records | ||
val table = doc.getElementById("cphBody_dgAthletes") // returns the table of athlete search results (NEEDED as the nav bar has the background colour attribute) | ||
var records = table?.getElementsByAttributeValueContaining("style","background-color:") //returns all records with a background colour within the results table(Line before) | ||
records?.removeAt(0)//removes the heading list(sex,name,etc) | ||
return records | ||
} else { //otherwise return null usually because theres too many athlete records that were returned | ||
return null | ||
} | ||
|
||
|
||
|
||
|
||
} | ||
|
||
|
||
@SuppressLint("UnusedMaterialScaffoldPaddingParameter") | ||
@OptIn(ExperimentalMaterial3Api::class) | ||
@Composable | ||
fun AthleteSearch(navController: NavController) { | ||
val powerOfTen = painterResource(id = R.drawable.powerof10) | ||
var buttonPress by remember { mutableStateOf(0) }//updates the lazy column when the apply button is pressed | ||
val scaffoldState = rememberScaffoldState() | ||
val scope = rememberCoroutineScope() | ||
var firstName by remember { mutableStateOf("") } | ||
var lastName by remember { mutableStateOf("") } | ||
var club by remember { mutableStateOf("") } | ||
var athletesList by remember {mutableStateOf(Elements()) } | ||
var context = LocalContext.current | ||
LaunchedEffect(buttonPress) { //recomposes on button press | ||
if (firstName != ""||lastName != ""){//if the either name fields are not empty | ||
val html = getHTML(firstName,lastName,club)//gets html from the searched page | ||
var athletesElements = getAthletes(html, context)//this is to check if the result is string, null or Elements() | ||
when (athletesElements) { | ||
null -> {//if null make a warning/toast | ||
Toast.makeText(context,"Too many athletes found. Please change the search criteria.\n",Toast.LENGTH_SHORT).show() | ||
} | ||
"athlete found" -> {//if only a single athlete is returned | ||
Toast.makeText(context,"Athlete found opening on browser",Toast.LENGTH_SHORT).show() | ||
|
||
} | ||
else -> {//otherwise just display the records list as usual | ||
athletesList = athletesElements as Elements | ||
println(athletesList.size) | ||
} | ||
} | ||
|
||
|
||
}else{// if both fields are empty | ||
Toast.makeText(context,"Please enter your search values",Toast.LENGTH_SHORT).show() | ||
} | ||
|
||
|
||
|
||
|
||
} | ||
Column { | ||
|
||
Scaffold( | ||
scaffoldState = scaffoldState, | ||
topBar = { | ||
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(), | ||
title = { | ||
Image( | ||
painter = powerOfTen, | ||
contentDescription = "Power of Ten Logo", | ||
modifier = Modifier, | ||
contentScale = ContentScale.FillBounds | ||
) | ||
}, | ||
colors = TopAppBarDefaults.centerAlignedTopAppBarColors( | ||
Color(0xFFE5383B), | ||
navigationIconContentColor = Color.White | ||
), | ||
navigationIcon = { | ||
IconButton(onClick = { scope.launch { scaffoldState.drawerState.open() } }) { | ||
Icon( | ||
Icons.Filled.Menu, contentDescription = null, | ||
tint = Color.White, | ||
modifier = Modifier.size(48.dp) | ||
) | ||
} | ||
} | ||
) | ||
}, | ||
drawerContent = { | ||
NavDrawerBody(items = listOf( | ||
MenuItems(1, "Home",Screen.HomepageRSS.route), | ||
MenuItems(2, "Rankings",Screen.RankingPage.route), | ||
MenuItems(3, "Athlete Search",Screen.AthleteSearch.route) | ||
), onItemClick = { navController.navigate(route =it.route) } | ||
) | ||
}, content = { | ||
|
||
|
||
Column( modifier = Modifier.fillMaxWidth() | ||
){ | ||
|
||
|
||
LazyColumn(content = { | ||
item { | ||
Column(horizontalAlignment = Alignment.CenterHorizontally,modifier = Modifier.fillMaxWidth() | ||
) { | ||
Text( | ||
text = "Athlete Search", | ||
fontWeight = FontWeight.Bold, | ||
fontSize = 24.sp, | ||
modifier = Modifier.padding(10.dp) | ||
) | ||
TextField( | ||
value = firstName, | ||
onValueChange = { firstName = it }, | ||
label = { Text("First Name") }, | ||
modifier = Modifier.padding(0.dp,5.dp) | ||
) | ||
|
||
TextField( | ||
value = lastName, | ||
onValueChange = { lastName = it }, | ||
label = { Text("Last Name") }, | ||
modifier = Modifier.padding(0.dp,5.dp) | ||
) | ||
|
||
TextField( | ||
value = club, | ||
onValueChange = { club = it }, | ||
label = { Text("Club Name") }, | ||
modifier = Modifier.padding(0.dp,5.dp) | ||
) | ||
Button( | ||
onClick = { | ||
if (firstName.length < 3&&lastName.length<3 ){// validates to check fields are atleast 3 chars long | ||
Toast.makeText(context,"Please enter at least 3 characters for either First or Last name",Toast.LENGTH_SHORT).show() | ||
}else { | ||
buttonPress += 1 //recompose view | ||
} | ||
}, modifier = Modifier | ||
.padding(horizontal = 5.dp, vertical = 0.dp) | ||
.fillMaxWidth(0.75F) | ||
|
||
) { | ||
Text("Apply") | ||
|
||
} | ||
} | ||
} | ||
items(athletesList.size) { | ||
|
||
AthleteItem(it,athletesList) | ||
|
||
|
||
} | ||
}) | ||
|
||
} | ||
}) | ||
|
||
} | ||
} | ||
|
||
@Composable | ||
fun AthleteItem(index: Int,athlete:Elements) { | ||
val mContext = LocalContext.current | ||
val background: Color = if (index%2==1){//alternates the colour | ||
Color(0xFFD3D3D3) | ||
} | ||
else { | ||
Color(0xFFF5F3F4) | ||
} //alternates the background colour | ||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier | ||
.background(background) | ||
.fillMaxWidth() | ||
.padding(0.dp, 10.dp) | ||
.clickable { | ||
val browserIntent = Intent( | ||
Intent.ACTION_VIEW, | ||
Uri.parse( | ||
"https://www.thepowerof10.info/athletes/" + athlete[index] | ||
.child(7) | ||
.child(0) | ||
.attr("href") | ||
) | ||
) | ||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)// Starts browser intent to athlete profile | ||
mContext.startActivity(browserIntent) | ||
} | ||
) { | ||
|
||
|
||
Column(verticalArrangement = Arrangement.SpaceBetween,modifier = Modifier | ||
.fillMaxWidth(0.25f) | ||
.padding(start = 5.dp)) { | ||
|
||
Text(text = athlete[index].child(0).text() ,//First Name | ||
maxLines = 1, | ||
overflow = TextOverflow.Ellipsis) | ||
Text(text = athlete[index].child(1).text() ,//Last Name | ||
maxLines = 1, | ||
overflow = TextOverflow.Ellipsis) | ||
} | ||
|
||
Column(verticalArrangement = Arrangement.SpaceBetween,modifier = Modifier.fillMaxWidth(0.5f)) { | ||
Text(text = "Club:" ,//Athlete's club | ||
maxLines = 1, | ||
overflow = TextOverflow.Ellipsis) | ||
Text(text = athlete[index].child(6).text() ,//athletes club | ||
maxLines = 1, | ||
overflow = TextOverflow.Ellipsis) | ||
|
||
} | ||
Column(modifier = Modifier.fillMaxWidth(0.4f)) { | ||
Text(text = athlete[index].child(5).text() ,//Athlete's Gender | ||
maxLines = 1, | ||
overflow = TextOverflow.Ellipsis) | ||
Text(text = athlete[index].child(2).text() ,//Athletes Age Group | ||
maxLines = 1, | ||
overflow = TextOverflow.Ellipsis) | ||
|
||
|
||
} | ||
} | ||
} | ||
@Preview(name = "PIXEL_4", device = Devices.PIXEL_4) | ||
//@Preview(name = "PIXEL_42", device = Devices.PIXEL_4) | ||
@Composable | ||
fun DefaultPreview3() { | ||
PowerOf10Theme { | ||
AthleteSearch(rememberNavController()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
PowerOf10/app/src/main/java/com/example/powerof10/RSSArticle.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.example.powerof10 | ||
|
||
import android.os.Bundle | ||
import android.webkit.WebView | ||
import androidx.activity.ComponentActivity | ||
import androidx.activity.compose.setContent | ||
import androidx.compose.foundation.layout.fillMaxSize | ||
import androidx.compose.material.MaterialTheme | ||
import androidx.compose.material.Surface | ||
import androidx.compose.material.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import androidx.navigation.NavController | ||
import com.example.powerof10.ui.theme.PowerOf10Theme | ||
import com.google.accompanist.web.WebView | ||
import com.google.accompanist.web.rememberWebViewState | ||
|
||
class RSSArticle : ComponentActivity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContent { | ||
PowerOf10Theme { | ||
// A surface container using the 'background' color from the theme | ||
Surface( | ||
modifier = Modifier.fillMaxSize(), | ||
color = MaterialTheme.colors.background | ||
) { | ||
|
||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Composable | ||
fun ArticleWebView( link: String) { | ||
val state = rememberWebViewState(link) | ||
println(link) | ||
WebView( | ||
state, | ||
onCreated = { | ||
it.settings.javaScriptEnabled = true}, | ||
) | ||
} | ||
|
||
@Preview(showBackground = true) | ||
@Composable | ||
fun DefaultPreview4() { | ||
PowerOf10Theme { | ||
|
||
} | ||
} |
404 changes: 216 additions & 188 deletions
404
PowerOf10/app/src/main/java/com/example/powerof10/RankingPage.kt
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
#Mon May 23 03:31:55 BST 2022 | ||
distributionBase=GRADLE_USER_HOME | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip | ||
distributionPath=wrapper/dists | ||
zipStorePath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME |