Skip to content

Commit

Permalink
Improve iOS UI
Browse files Browse the repository at this point in the history
  • Loading branch information
prof18 committed Jan 6, 2024
1 parent 8b32f42 commit bc0db68
Show file tree
Hide file tree
Showing 18 changed files with 366 additions and 286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class MainActivity : ComponentActivity() {
onFeedListClick = {
navController.navigate(Screen.FeedList.name)
},
onAddFeedClick = {
navController.navigate(Screen.AddFeed.name)
},
navigateBack = {
navController.popBackStack()
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import org.koin.compose.koinInject
@Composable
fun SettingsScreen(
onFeedListClick: () -> Unit,
onAddFeedClick: () -> Unit,
navigateBack: () -> Unit,
onAboutClick: () -> Unit,
navigateToImportExport: () -> Unit,
Expand All @@ -69,6 +70,7 @@ fun SettingsScreen(
SettingsScreenContent(
browsers = browserListState,
onFeedListClick = onFeedListClick,
onAddFeedClick = onAddFeedClick,
isMarkReadWhenScrollingEnabled = settingState.isMarkReadWhenScrollingEnabled,
onBrowserSelected = { browser ->
browserManager.setFavouriteBrowser(browser)
Expand All @@ -92,11 +94,13 @@ fun SettingsScreen(
)
}

@Suppress("LongParameterList")
@Composable
private fun SettingsScreenContent(
browsers: List<Browser>,
isMarkReadWhenScrollingEnabled: Boolean,
onFeedListClick: () -> Unit,
onAddFeedClick: () -> Unit,
onBrowserSelected: (Browser) -> Unit,
navigateBack: () -> Unit,
onAboutClick: () -> Unit,
Expand Down Expand Up @@ -132,6 +136,7 @@ private fun SettingsScreenContent(
modifier = Modifier
.padding(paddingValues),
onFeedListClick = onFeedListClick,
onAddFeedClick = onAddFeedClick,
onBrowserSelectionClick = {
showBrowserSelection = true
},
Expand Down Expand Up @@ -175,6 +180,7 @@ private fun SettingsList(
isMarkReadWhenScrollingEnabled: Boolean,
modifier: Modifier = Modifier,
onFeedListClick: () -> Unit,
onAddFeedClick: () -> Unit,
onBrowserSelectionClick: () -> Unit,
navigateToImportExport: () -> Unit,
onAboutClick: () -> Unit,
Expand All @@ -198,9 +204,9 @@ private fun SettingsList(

item {
SettingsMenuItem(
text = stringResource(resource = MR.strings.browser_selection_button),
text = stringResource(resource = MR.strings.add_feed),
) {
onBrowserSelectionClick()
onAddFeedClick()
}
}

Expand All @@ -220,6 +226,18 @@ private fun SettingsList(
SettingsDivider()
}

item {
SettingsMenuItem(
text = stringResource(resource = MR.strings.browser_selection_button),
) {
onBrowserSelectionClick()
}
}

item {
SettingsDivider()
}

item {
MarkReadWhenScrollingSwitch(
setMarkReadWhenScrolling = setMarkReadWhenScrolling,
Expand Down Expand Up @@ -299,6 +317,7 @@ private fun SettingsScreenPreview() {
browsers = browsersForPreview,
isMarkReadWhenScrollingEnabled = true,
onFeedListClick = {},
onAddFeedClick = {},
onBrowserSelected = {},
navigateBack = {},
onAboutClick = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package com.prof18.feedflow.settings.about

import FeedFlowTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -17,7 +19,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import com.prof18.feedflow.BrowserManager
import com.prof18.feedflow.BuildConfig
import com.prof18.feedflow.MR
import com.prof18.feedflow.core.utils.Websites.FEED_FLOW_WEBSITE
import com.prof18.feedflow.core.utils.Websites.MG_WEBSITE
Expand Down Expand Up @@ -56,6 +60,7 @@ fun AboutScreen(
}

@OptIn(ExperimentalMaterial3Api::class)
@Suppress("LongMethod")
@Composable
private fun AboutScreenContent(
licensesClicked: () -> Unit,
Expand Down Expand Up @@ -110,6 +115,17 @@ private fun AboutScreenContent(
buttonText = stringResource(MR.strings.open_source_licenses),
)
}

item {
Text(
modifier = Modifier
.fillMaxWidth(),
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onBackground,
text = stringResource(MR.strings.about_app_version, BuildConfig.VERSION_NAME),
style = MaterialTheme.typography.bodySmall,
)
}
}
AuthorText(
modifier = Modifier.align(Alignment.CenterHorizontally),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ data class CategoriesState(

data class CategoryItem(
val id: Long,
val name: String,
val name: String?,
val isSelected: Boolean,
val onClick: (CategoryId) -> Unit,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,11 @@ class DatabaseHelper(
is FeedFilter.Category -> {
dbRef.feedItemQueries.markAllReadByCategory(feedFilter.feedCategory.id)
}

is FeedFilter.Source -> {
dbRef.feedItemQueries.markAllReadByFeedSource(feedFilter.feedSource.id)
}

FeedFilter.Timeline -> {
dbRef.feedItemQueries.markAllRead()
}
Expand Down Expand Up @@ -225,6 +227,12 @@ class DatabaseHelper(
.mapToOneOrDefault(0, backgroundDispatcher)
.flowOn(backgroundDispatcher)

suspend fun deleteCategory(id: Long) =
dbRef.transactionWithContext(backgroundDispatcher) {
dbRef.feedSourceQueries.resetCategory(categoryId = id)
dbRef.feedSourceCategoryQueries.delete(id = id)
}

private suspend fun Transacter.transactionWithContext(
coroutineContext: CoroutineContext,
noEnclosing: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ updateLogoUrl:
UPDATE feed_source
SET logo_url = :logoUrl
WHERE url_hash = :urlHash;

resetCategory:
UPDATE feed_source
SET category_id = NULL
WHERE category_id = :categoryId;
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ SELECT * FROM feed_source_category WHERE title = ?;

selectAll:
SELECT * FROM feed_source_category
ORDER BY title COLLATE NOCASE ASC;
ORDER BY title COLLATE NOCASE ASC;

delete:
DELETE FROM feed_source_category WHERE id = ?;
12 changes: 9 additions & 3 deletions i18n/src/commonMain/resources/MR/base/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<string name="feeds_import_done_message">Import done</string>
<string name="feeds_export_done_message">Export done</string>
<string name="settings_title">Settings</string>
<string name="browser_selection_button">Favorite web browser</string>
<string name="browser_selection_button">Browser</string>
<string name="import_feed_button">Import feed from OPML</string>
<string name="export_feeds_button">Export feeds to OPML</string>
<string name="about_button">About</string>
Expand All @@ -45,6 +45,7 @@
<string name="force_feed_refresh">Force feeds refresh</string>
<string name="invalid_rss_url">The link you provided is not a valid RSS feed</string>
<string name="import_export_opml">Import and export OPML</string>
<string name="import_export_opml_title">Import and export</string>
<string name="retry_button">Retry</string>
<string name="done_button">OK</string>
<string name="wrong_link_report_title">The following feeds were not added because they are not valid</string>
Expand All @@ -55,14 +56,19 @@
<string name="issue_content_title">Issue with FeedFlow</string>
<string name="issue_content_template">Please describe the issue and provide a link to the RSS Feed that causes the issues. If you can, please attach a screenshot and the OPML file</string>
<string name="missing_title_and_link">There was an error while getting the title of the feed</string>
<string name="no_category_selected_header">No category selected</string>
<string name="no_category_selected_header">No category</string>
<string name="new_category_hint">New category name</string>
<string name="no_category">Uncategorized</string>
<string name="drawer_title_timeline">Timeline</string>
<string name="drawer_title_categories">Categories</string>
<string name="drawer_title_feed_sources">Feed Sources</string>
<string name="toggle_mark_read_when_scrolling">Mark items as read when scrolling</string>
<string name="toggle_mark_read_when_scrolling">Mark as read when scrolling</string>
<string name="action_done">Done</string>
<string name="settings_general_title">General</string>
<string name="settings_app_title">App</string>
<string name="about_app_version">App Version: %s</string>
<string name="add_feed_category_title">Category</string>
<string name="add_feed_categories_title">Categories</string>
<string name="action_save">Save</string>
<string name="import_export_description">FeedFlow supports the import and export of your subscriptions with an OPML file, for better interoperability with the other feed readers</string>
</resources>
77 changes: 41 additions & 36 deletions iosApp/Source/Settings/About/AboutScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,54 +15,59 @@ struct AboutScreen: View {
@Environment(\.openURL)
private var openURL

@State
private var showLicensesSheet = false

@State
private var licensesContent: String = ""

var body: some View {

VStack {
Text(localizer.about_the_app.localized)
.padding(Spacing.regular)
.font(.system(size: 16))
List {
Section {
Text(localizer.about_the_app.localized)
.padding(.vertical, Spacing.small)
.font(.system(size: 16))

Button(
localizer.open_website_button.localized,
action: {
if let url = URL(string: Websites.shared.FEED_FLOW_WEBSITE) {
self.openURL(url)
NavigationLink(destination: LicensesScreen()) {
Label(
localizer.open_source_licenses.localized,
systemImage: "shield"
)
}
}
)
.buttonStyle(.bordered)
.padding(.top, Spacing.regular)

Button(
localizer.open_source_licenses.localized,
action: {
let baseURL = Bundle.main.url(forResource: "licenses", withExtension: "html")!
let htmlString = try? String(contentsOf: baseURL, encoding: String.Encoding.utf8)

self.licensesContent = htmlString ?? ""
self.showLicensesSheet.toggle()
Link(destination: URL(string: Websites.shared.FEED_FLOW_WEBSITE)!) {
Label(
localizer.open_website_button.localized,
systemImage: "globe"
)
}
} footer: {
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
let appVersionString = LocalizationUtils.shared.formatString(
resource: MR.strings().about_app_version,
args: [appVersion]
)
Text(appVersionString)
.frame(maxWidth: .infinity, alignment: .center)
.padding(.vertical, Spacing.small)
}
}
)
.buttonStyle(.bordered)
.padding(.top, Spacing.regular)
}
.listStyle(.insetGrouped)
.scrollContentBackground(.hidden)
.padding(.top, -Spacing.medium)
.background(Color.secondaryBackgroundColor)

Spacer()

let authorLink: LocalizedStringKey = """
\(localizer.author_label.localized) [Marco Gomiero](https://www.marcogomiero.com)
"""
\(localizer.author_label.localized) [Marco Gomiero](https://www.marcogomiero.com)
"""
Text(authorLink)
}.sheet(isPresented: $showLicensesSheet) {
LicensesScreen(htmlContent: licensesContent)
.padding(.bottom, Spacing.small)
}
.navigationTitle(localizer.about_nav_bar.localized)
.background(Color.secondaryBackgroundColor)
.navigationTitle(Text(localizer.about_nav_bar.localized))
.navigationBarTitleDisplayMode(.inline)

}
}

#Preview {
AboutScreen()

}
45 changes: 22 additions & 23 deletions iosApp/Source/Settings/About/LicensesScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,34 @@ struct LicensesScreen: View {
@Environment(\.presentationMode)
private var presentationMode

let htmlContent: String
@State
var htmlContent: String?

var body: some View {
NavigationStack {
HTMLStringView(
htmlContent: htmlContent
)
licenseView
.padding(Spacing.regular)
.toolbar {

ToolbarItem(placement: .navigationBarLeading) {
Button(
action: {
self.presentationMode.wrappedValue.dismiss()
},
label: {
Image(systemName: "xmark")
}
)
}

ToolbarItem(placement: .navigationBarLeading) {
Text(localizer.open_source_nav_bar.localized)
.font(.title2)
.padding(.vertical, Spacing.medium)
}
.onAppear {
let baseURL = Bundle.main.url(forResource: "licenses", withExtension: "html")!
let htmlString = try? String(contentsOf: baseURL, encoding: String.Encoding.utf8)

self.htmlContent = htmlString ?? ""
}
}

@ViewBuilder
private var licenseView: some View {
if let content = htmlContent {
HTMLStringView(
htmlContent: content
)
} else {
Spacer()

ProgressView()
Spacer()
}
}

}

struct LicensesScreen_Previews: PreviewProvider {
Expand Down
Loading

0 comments on commit bc0db68

Please sign in to comment.