This commit is contained in:
X1nto 2021-11-22 16:30:47 +04:00
parent c7e54ba6fa
commit c83ee3df8f
28 changed files with 187 additions and 170 deletions

View File

@ -1,7 +1,6 @@
package com.vanced.manager.core.downloader.impl
import android.content.Context
import android.util.Log
import com.vanced.manager.core.downloader.api.MicrogAPI
import com.vanced.manager.core.downloader.base.AppDownloader
import com.vanced.manager.core.downloader.util.DownloadStatus
@ -33,10 +32,12 @@ class MicrogDownloader(
onStatus(DownloadStatus.StartInstall)
},
onError = { error, fileName ->
onStatus(DownloadStatus.Error(
displayError = "Failed to download $fileName",
stacktrace = error
))
onStatus(
DownloadStatus.Error(
displayError = "Failed to download $fileName",
stacktrace = error
)
)
}
)
}

View File

@ -23,13 +23,15 @@ class MusicDownloader(
absoluteVersion = getLatestOrProvidedAppVersion(musicVersionPref, appVersions)
downloadFiles(
downloadFiles = arrayOf(DownloadFile(
call = musicAPI.getFiles(
version = absoluteVersion,
variant = managerVariantPref,
),
fileName = "music.apk"
)),
downloadFiles = arrayOf(
DownloadFile(
call = musicAPI.getFiles(
version = absoluteVersion,
variant = managerVariantPref,
),
fileName = "music.apk"
)
),
onProgress = { progress ->
onStatus(DownloadStatus.Progress(progress))
},
@ -40,10 +42,12 @@ class MusicDownloader(
onStatus(DownloadStatus.StartInstall)
},
onError = { error, fileName ->
onStatus(DownloadStatus.Error(
displayError = "Failed to download $fileName",
stacktrace = error
))
onStatus(
DownloadStatus.Error(
displayError = "Failed to download $fileName",
stacktrace = error
)
)
}
)
}

View File

@ -53,10 +53,12 @@ class VancedDownloader(
onStatus(DownloadStatus.StartInstall)
},
onError = { error, fileName ->
onStatus(DownloadStatus.Error(
displayError = "Failed to download $fileName",
stacktrace = error
))
onStatus(
DownloadStatus.Error(
displayError = "Failed to download $fileName",
stacktrace = error
)
)
}
)
}

View File

@ -24,7 +24,10 @@ class AppInstallService : Service() {
sendBroadcast(Intent().apply {
action = APP_INSTALL_STATUS
putExtra(EXTRA_INSTALL_STATUS, status)
putExtra(EXTRA_INSTALL_EXTRA, intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE))
putExtra(
EXTRA_INSTALL_EXTRA,
intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
)
})
}
}

View File

@ -70,7 +70,7 @@ class ManagerPreference<T>(
var value by mutableStateOf(sharedPreferences.getter(key, defaultValue) ?: defaultValue)
private set
operator fun getValue(
thisRef: Any?,
property: KProperty<*>

View File

@ -7,14 +7,20 @@ import com.vanced.manager.core.preferences.managerStringSetPreference
import com.vanced.manager.ui.theme.defAccentColor
var useCustomTabsPref by managerBooleanPreference(USE_CUSTOM_TABS_KEY)
var managerVariantPref by managerStringPreference(MANAGER_VARIANT_KEY, MANAGER_VARIANT_DEFAULT_VALUE)
var managerVariantPref by managerStringPreference(
MANAGER_VARIANT_KEY,
MANAGER_VARIANT_DEFAULT_VALUE
)
var managerThemePref by managerStringPreference(MANAGER_THEME_KEY, MANAGER_THEME_DEFAULT_VALUE)
var managerAccentColorPref by managerLongPreference(MANAGER_ACCENT_COLOR_KEY, defAccentColor)
var vancedThemePref by managerStringPreference(APP_VANCED_THEME_KEY, VANCED_THEME_DEFAULT_VALUE)
var vancedVersionPref by managerStringPreference(APP_VANCED_VERSION_KEY, APP_VERSION_DEFAULT_VALUE)
var vancedLanguagesPref by managerStringSetPreference(APP_VANCED_LANGUAGE_KEY, VANCED_LANGUAGE_DEFAULT_VALUE)
var vancedLanguagesPref by managerStringSetPreference(
APP_VANCED_LANGUAGE_KEY,
VANCED_LANGUAGE_DEFAULT_VALUE
)
var musicVersionPref by managerStringPreference(APP_MUSIC_VERSION_KEY, APP_VERSION_DEFAULT_VALUE)

View File

@ -74,72 +74,72 @@ class AppDtoMapper(
appVersions: List<String>?,
appLanguages: List<String>?,
) = when (appName) {
VANCED_NAME -> listOf(
InstallationOption.SingleSelect(
titleId = R.string.app_installation_options_theme,
getOption = { vancedThemePref },
setOption = {
vancedThemePref = it
},
items = appThemes?.map { theme ->
InstallationOptionItem(
displayText = {
theme.replaceFirstChar {
it.titlecase(Locale.getDefault())
}
},
key = theme
)
} ?: emptyList(),
),
InstallationOption.SingleSelect(
titleId = R.string.app_installation_options_version,
getOption = { vancedVersionPref },
setOption = {
vancedVersionPref = it
},
items = appVersions?.map { version ->
InstallationOptionItem(
displayText = { "v$version" },
key = version
)
}?.plus(latestVersionRadioButton)?.reversed() ?: emptyList(),
),
InstallationOption.MultiSelect(
titleId = R.string.app_installation_options_language,
getOption = { vancedLanguagesPref },
addOption = {
vancedLanguagesPref = vancedLanguagesPref + it
},
removeOption = {
vancedLanguagesPref = vancedLanguagesPref - it
},
items = appLanguages?.map { language ->
InstallationOptionItem(
displayText = {
val locale = Locale(it)
locale.getDisplayName(locale)
},
key = language
)
} ?: emptyList(),
),
VANCED_NAME -> listOf(
InstallationOption.SingleSelect(
titleId = R.string.app_installation_options_theme,
getOption = { vancedThemePref },
setOption = {
vancedThemePref = it
},
items = appThemes?.map { theme ->
InstallationOptionItem(
displayText = {
theme.replaceFirstChar {
it.titlecase(Locale.getDefault())
}
},
key = theme
)
} ?: emptyList(),
),
InstallationOption.SingleSelect(
titleId = R.string.app_installation_options_version,
getOption = { vancedVersionPref },
setOption = {
vancedVersionPref = it
},
items = appVersions?.map { version ->
InstallationOptionItem(
displayText = { "v$version" },
key = version
)
}?.plus(latestVersionRadioButton)?.reversed() ?: emptyList(),
),
InstallationOption.MultiSelect(
titleId = R.string.app_installation_options_language,
getOption = { vancedLanguagesPref },
addOption = {
vancedLanguagesPref = vancedLanguagesPref + it
},
removeOption = {
vancedLanguagesPref = vancedLanguagesPref - it
},
items = appLanguages?.map { language ->
InstallationOptionItem(
displayText = {
val locale = Locale(it)
locale.getDisplayName(locale)
},
key = language
)
} ?: emptyList(),
),
)
MUSIC_NAME -> listOf(
InstallationOption.SingleSelect(
titleId = R.string.app_installation_options_version,
getOption = { musicVersionPref },
setOption = {
musicVersionPref = it
},
items = appVersions?.map { version ->
InstallationOptionItem(
displayText = { version },
key = version
)
} ?: emptyList(),
)
MUSIC_NAME -> listOf(
InstallationOption.SingleSelect(
titleId = R.string.app_installation_options_version,
getOption = { musicVersionPref },
setOption = {
musicVersionPref = it
},
items = appVersions?.map { version ->
InstallationOptionItem(
displayText = { version },
key = version
)
} ?: emptyList(),
)
)
else -> null
}
)
else -> null
}
}

View File

@ -7,7 +7,7 @@ import android.content.IntentFilter
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.*
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.CompositionLocalProvider
@ -23,11 +23,13 @@ import com.vanced.manager.ui.theme.ManagerTheme
import com.vanced.manager.ui.theme.isDark
import com.vanced.manager.ui.util.Screen
import com.vanced.manager.ui.viewmodel.InstallViewModel
import com.vanced.manager.ui.viewmodel.MainViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
class MainActivity : ComponentActivity() {
private val installViewModel: InstallViewModel by viewModel()
private val mainViewModel: MainViewModel by viewModel()
private val backPressHandler = BackPressHandler()
@ -46,7 +48,7 @@ class MainActivity : ComponentActivity() {
@OptIn(
ExperimentalAnimationApi::class,
ExperimentalMaterial3Api::class,
ExperimentalFoundationApi::class
ExperimentalFoundationApi::class,
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -72,6 +74,7 @@ class MainActivity : ComponentActivity() {
when (val screen = backStack.last()) {
is Screen.Home -> {
HomeLayout(
viewModel = mainViewModel,
onToolbarScreenSelected = {
backStack.push(it)
},
@ -124,7 +127,11 @@ class MainActivity : ComponentActivity() {
)
}
is Screen.Install -> {
InstallScreen(screen.appName, screen.appVersions)
InstallScreen(
appName = screen.appName,
appVersions = screen.appVersions,
viewModel = installViewModel
)
}
}
}

View File

@ -1,14 +1,9 @@
package com.vanced.manager.ui.component.layout
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
@Composable
fun ManagerLazyColumn(

View File

@ -20,13 +20,13 @@ fun ManagerScaffold(
// CompositionLocalProvider(
// LocalAbsoluteTonalElevation provides absoluteTonalElevation
// ) {
Scaffold(
modifier = modifier,
scaffoldState = scaffoldState,
topBar = topBar,
floatingActionButton = floatingActionButton,
floatingActionButtonPosition = floatingActionButtonPosition,
content = content
)
Scaffold(
modifier = modifier,
scaffoldState = scaffoldState,
topBar = topBar,
floatingActionButton = floatingActionButton,
floatingActionButtonPosition = floatingActionButtonPosition,
content = content
)
// }
}

View File

@ -3,13 +3,9 @@ package com.vanced.manager.ui.component.layout
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.SwipeRefreshIndicator
import com.google.accompanist.swiperefresh.SwipeRefreshState
import com.vanced.manager.ui.component.card.ManagerCard
import com.vanced.manager.ui.component.color.managerAccentColor
@Composable
fun ManagerSwipeRefresh(

View File

@ -1,7 +1,6 @@
package com.vanced.manager.ui.component.layout
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState

View File

@ -1,9 +1,17 @@
package com.vanced.manager.ui.component.menu
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha

View File

@ -1,26 +1,17 @@
package com.vanced.manager.ui.component.preference
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.vanced.manager.R
import com.vanced.manager.core.preferences.CheckboxPreference
import com.vanced.manager.core.preferences.ManagerPreference
import com.vanced.manager.core.preferences.RadioButtonPreference
import com.vanced.manager.ui.component.button.ManagerThemedTextButton
import com.vanced.manager.ui.component.text.ManagerText
import com.vanced.manager.ui.resources.managerString
import com.vanced.manager.ui.widget.list.CheckboxItem
import kotlinx.coroutines.launch
@Composable
fun CheckboxDialogPreference(

View File

@ -1,11 +1,8 @@
package com.vanced.manager.ui.component.preference
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.unit.dp
import com.vanced.manager.core.preferences.ManagerPreference
import com.vanced.manager.ui.widget.checkbox.ManagerAnimatedCheckbox
import kotlinx.coroutines.launch
@Composable
fun CheckboxPreference(

View File

@ -11,11 +11,9 @@ import androidx.compose.ui.unit.dp
import com.vanced.manager.ui.component.card.ManagerTonalCard
import com.vanced.manager.ui.component.color.managerAnimatedColor
import com.vanced.manager.ui.component.list.ManagerListItem
import com.vanced.manager.ui.component.modifier.managerClickable
import com.vanced.manager.ui.component.text.ManagerText
import com.vanced.manager.ui.theme.LargeShape
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
import com.vanced.manager.ui.util.DefaultContentPaddingVertical
@Composable
fun Preference(

View File

@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.TextButton
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.vanced.manager.R

View File

@ -67,7 +67,7 @@ private val vancedTeam = listOf(
)
)
private val otherContributors = listOf(
private val otherContributors = listOf(
Person(
name = "bhatVikrant",
contribution = "Website"
@ -132,7 +132,9 @@ fun AboutLayout(
}
) { paddingValues ->
ManagerLazyColumn(
modifier = Modifier.fillMaxSize().padding(paddingValues),
modifier = Modifier
.fillMaxSize()
.padding(paddingValues),
) {
item {
ManagerTonalCard(

View File

@ -4,7 +4,10 @@ import androidx.compose.animation.*
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.MoreVert
import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.TextButton
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
@ -33,12 +36,12 @@ import com.vanced.manager.ui.viewmodel.MainViewModel
import com.vanced.manager.ui.widget.app.AppCard
import com.vanced.manager.ui.widget.app.AppCardPlaceholder
import com.vanced.manager.ui.widget.layout.managerCategory
import org.koin.androidx.compose.getViewModel
@ExperimentalMaterial3Api
@ExperimentalAnimationApi
@Composable
fun HomeLayout(
viewModel: MainViewModel,
onToolbarScreenSelected: (Screen) -> Unit,
onAppInstallPress: (
appName: String,
@ -46,11 +49,10 @@ fun HomeLayout(
installationOptions: List<InstallationOption>?
) -> Unit
) {
val viewModel: MainViewModel = getViewModel()
val appState by viewModel.appState.collectAsState()
val refreshState = rememberSwipeRefreshState(isRefreshing = appState is MainViewModel.AppState.Fetching)
val refreshState =
rememberSwipeRefreshState(isRefreshing = appState is MainViewModel.AppState.Fetching)
var isMenuExpanded by remember { mutableStateOf(false) }
val dropdownScreens = remember { listOf(Screen.Settings, Screen.About) }
@ -69,7 +71,7 @@ fun HomeLayout(
contentDescription = "Navigation"
)
}
ManagerDropdownMenu(
expanded = isMenuExpanded,
onDismissRequest = {
@ -116,7 +118,11 @@ fun HomeLayout(
diskCachePolicy(CachePolicy.ENABLED)
}
var showAppInfoDialog by rememberSaveable { mutableStateOf(false) }
var showAppInfoDialog by rememberSaveable {
mutableStateOf(
false
)
}
AppCard(
appName = app.name,
@ -124,7 +130,11 @@ fun HomeLayout(
appInstalledVersion = app.installedVersion,
appRemoteVersion = app.remoteVersion,
onAppDownloadClick = {
onAppInstallPress(app.name, app.versions, app.installationOptions)
onAppInstallPress(
app.name,
app.versions,
app.installationOptions
)
},
onAppUninstallClick = { /*TODO*/ },
onAppLaunchClick = { /*TODO*/ },
@ -135,7 +145,10 @@ fun HomeLayout(
if (showAppInfoDialog) {
ManagerDialog(
title = managerString(R.string.app_info_title, app.name),
title = managerString(
R.string.app_info_title,
app.name
),
onDismissRequest = { showAppInfoDialog = false },
confirmButton = {
TextButton(onClick = {

View File

@ -8,7 +8,10 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowDropDown
import androidx.compose.material.icons.rounded.Done
import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
@ -30,7 +33,6 @@ import com.vanced.manager.ui.component.topappbar.ManagerTopAppBar
import com.vanced.manager.ui.resources.managerString
import com.vanced.manager.ui.util.DefaultContentPaddingHorizontal
import com.vanced.manager.ui.viewmodel.InstallViewModel
import org.koin.androidx.compose.getViewModel
@OptIn(
ExperimentalFoundationApi::class,
@ -39,10 +41,9 @@ import org.koin.androidx.compose.getViewModel
@Composable
fun InstallScreen(
appName: String,
appVersions: List<String>?
appVersions: List<String>?,
viewModel: InstallViewModel,
) {
val viewModel: InstallViewModel = getViewModel()
var startedProcess by rememberSaveable { mutableStateOf(false) }
val logs = viewModel.logs

View File

@ -13,19 +13,21 @@ sealed class Screen(
displayName = R.string.app_name
)
object Settings: Screen(
object Settings : Screen(
route = "settings",
displayName = R.string.toolbar_settings,
)
object About: Screen(
object About : Screen(
route = "about",
displayName = R.string.toolbar_about,
)
object Logs : Screen(
route = "logs",
displayName = R.string.toolbar_logs,
)
data class InstallPreferences(
val appName: String,
val appVersions: List<String>?,

View File

@ -83,11 +83,14 @@ class InstallViewModel(
downloader.download(appVersions) { downloadStatus ->
when (downloadStatus) {
is DownloadStatus.File -> log(Log.Info("Downloading ${downloadStatus.fileName}"))
is DownloadStatus.Error -> log(Log.Error(
displayText = downloadStatus.displayError,
stacktrace = downloadStatus.stacktrace
))
is DownloadStatus.Progress -> status = Status.Progress(downloadStatus.progress / 100)
is DownloadStatus.Error -> log(
Log.Error(
displayText = downloadStatus.displayError,
stacktrace = downloadStatus.stacktrace
)
)
is DownloadStatus.Progress -> status =
Status.Progress(downloadStatus.progress / 100)
is DownloadStatus.StartInstall -> {
log(Log.Success("Successfully downloaded $appName"))
installApp(appName, appVersions)

View File

@ -8,7 +8,6 @@ import com.vanced.manager.core.preferences.holder.musicEnabled
import com.vanced.manager.core.preferences.holder.vancedEnabled
import com.vanced.manager.domain.model.App
import com.vanced.manager.repository.JsonRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

View File

@ -5,7 +5,6 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.rounded.DeleteForever
import androidx.compose.material.icons.rounded.Download
@ -19,7 +18,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import coil.compose.ImagePainter
import com.vanced.manager.R
import com.vanced.manager.ui.component.button.ManagerIconButton
import com.vanced.manager.ui.component.text.AppVersionText
import com.vanced.manager.ui.component.text.ManagerText

View File

@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

View File

@ -1,6 +1,9 @@
package com.vanced.manager.ui.widget.layout
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items

View File

@ -2,7 +2,6 @@ package com.vanced.manager.ui.widget.layout
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
@Composable
fun SettingsCategoryLayout(

View File

@ -1,15 +1,6 @@
package com.vanced.manager.ui.widget.screens.settings
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import com.vanced.manager.R
import com.vanced.manager.core.preferences.holder.managerAccentColorPref
import com.vanced.manager.ui.component.color.ManagerColorPicker
import com.vanced.manager.ui.component.preference.DialogPreference
import com.vanced.manager.ui.resources.managerString
import com.vanced.manager.ui.theme.defAccentColor
import com.vanced.manager.ui.widget.button.ManagerResetButton
import com.vanced.manager.ui.widget.button.ManagerSaveButton
import androidx.compose.runtime.Composable
@Composable
fun SettingsAccentColorItem() {