Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 3.3.0 #140

Merged
merged 49 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
1c499e8
metadata update, update phone screenshots
Hiebeler Jan 20, 2025
3f70daa
#127 show reposts in home timeline
Hiebeler Jan 21, 2025
23565d3
#124 #126 Add content description to buttons
Hiebeler Jan 21, 2025
bc46295
#125 #126 Add content description to buttons
Hiebeler Jan 21, 2025
486ce7c
Merge remote-tracking branch 'origin/dev' into dev
Hiebeler Jan 21, 2025
d6ca50b
add crowdin.yml file
Hiebeler Jan 21, 2025
638a60d
Create crowdin file
daniebeler Jan 21, 2025
52898b7
update crowdin.yml
Hiebeler Jan 21, 2025
c42deea
Merge remote-tracking branch 'origin/dev' into dev
Hiebeler Jan 21, 2025
429dd03
Update crowdin.yml
daniebeler Jan 21, 2025
67d7c49
Update crowdin.yml
daniebeler Jan 21, 2025
645b8b5
Update crowdin.yml
daniebeler Jan 21, 2025
8a7f9a8
update crowdin.yml
Hiebeler Jan 21, 2025
3189f25
Merge remote-tracking branch 'origin/dev' into dev
Hiebeler Jan 21, 2025
17d5b19
Added stream-based file handling from uri
SchwarzNikolas Jan 22, 2025
c1190a8
Merge pull request #131 from SchwarzNikolas/main
Hiebeler Jan 22, 2025
2c667a0
New Crowdin translations by GitHub Action
crowdin-bot Jan 22, 2025
65f58cd
Merge pull request #129 from daniebeler/l10n_crowdin_translations
Hiebeler Jan 22, 2025
9a41f91
implement mentions page, notifications link to mentions page
Hiebeler Jan 22, 2025
369b386
bug fix, scroll to current mention in mention page
Hiebeler Jan 22, 2025
be4b03c
add link to mention page to all notifications without media attachment
Hiebeler Jan 22, 2025
9788a43
add divider to subPosts
Hiebeler Jan 23, 2025
88afcbb
include pull to refresh in mentions page
Hiebeler Jan 23, 2025
878a13a
Merge pull request #132 from daniebeler/feature/notificationViewMention
Hiebeler Jan 23, 2025
3254908
liking animation also when double clicking image
Hiebeler Jan 23, 2025
644bded
#110 bottom bar smaller and smaller icons. profile icon replaced by a…
Hiebeler Jan 23, 2025
3ab6646
#110 add account switch bottom sheet on long click on profile in bott…
Hiebeler Jan 23, 2025
fab571d
#136 change route to get posts by account, status if contentText not …
Hiebeler Jan 24, 2025
25aa4d1
implement search bar with trending component on explore page
Hiebeler Jan 24, 2025
53f0a2e
finish explore page implementation
Hiebeler Jan 24, 2025
066b0c3
bug fix, remove searches when clearing search bar
Hiebeler Jan 26, 2025
a1918c4
language: add question mark to "are_you_sure_you_want_to_remove_this_…
Hiebeler Jan 26, 2025
0a14d13
explore page, add animation to clear button in search bar
Hiebeler Jan 26, 2025
570e447
move trending package to explore, add pager for completed search betw…
Hiebeler Jan 26, 2025
2610ced
Merge pull request #139 from daniebeler/feature/explorePage
Hiebeler Jan 26, 2025
1b83032
add "explore" to strings
Hiebeler Jan 26, 2025
6de5df1
changed github action
Hiebeler Jan 26, 2025
69a78fc
test crowdin fix with afrikaans
Hiebeler Jan 26, 2025
28db24b
add manual running crowdin action
Hiebeler Jan 26, 2025
5ac19d3
#138 change coil caching settings, memory max 20%, disk max 50mb
Hiebeler Jan 26, 2025
8b8aee8
#127 reblogs work, and show reblogged by username
Hiebeler Jan 26, 2025
90242c1
#127 add reblogged by to strings.xml
Hiebeler Jan 26, 2025
8151787
make bottom bar smaller and accounting navigationbar insets
Hiebeler Jan 26, 2025
027ad9b
add default avatars to avatar images on error
Hiebeler Jan 26, 2025
25e6540
New Crowdin translations by GitHub Action
crowdin-bot Jan 26, 2025
2905d24
Merge pull request #135 from daniebeler/l10n_crowdin_translations
Hiebeler Jan 26, 2025
040a38b
bug fix, reposts open comments of repostId
Hiebeler Jan 26, 2025
7000bd7
versionCode: 24, versionName 3.3.0, updated changelogs
Hiebeler Jan 26, 2025
a8f5839
enhance the changelogs
Hiebeler Jan 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/crowdin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Crowdin Action

on:
push:
branches: [ dev ]
workflow_dispatch:

jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: crowdin action
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: false
download_translations: true
localization_branch_name: l10n_crowdin_translations
create_pull_request: true
pull_request_title: 'New Crowdin Translations'
pull_request_body: 'New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)'
pull_request_base_branch_name: 'dev'
pull_request_assignees: 'crowdin-bot'
env:
# A classic GitHub Personal Access Token with the 'repo' scope selected (the user should have write access to the repository).
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# A numeric ID, found at https://crowdin.com/project/<projectName>/tools/api
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}

# Visit https://crowdin.com/settings#api-key to create this token
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
5 changes: 5 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ android {
applicationId = "com.daniebeler.pfpixelix"
minSdk = 26
targetSdk = 35
versionCode = 23
versionName = "3.2.1"
versionCode = 24
versionName = "3.3.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
146 changes: 123 additions & 23 deletions app/src/main/java/com/daniebeler/pfpixelix/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,43 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.UnfoldMore
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController
Expand All @@ -31,6 +54,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import coil.compose.AsyncImage
import com.daniebeler.pfpixelix.common.Destinations
import com.daniebeler.pfpixelix.di.HostSelectionInterceptorInterface
import com.daniebeler.pfpixelix.domain.model.LoginData
Expand All @@ -43,12 +67,14 @@ import com.daniebeler.pfpixelix.ui.composables.direct_messages.chat.ChatComposab
import com.daniebeler.pfpixelix.ui.composables.direct_messages.conversations.ConversationsComposable
import com.daniebeler.pfpixelix.ui.composables.edit_post.EditPostComposable
import com.daniebeler.pfpixelix.ui.composables.edit_profile.EditProfileComposable
import com.daniebeler.pfpixelix.ui.composables.explore.ExploreComposable
import com.daniebeler.pfpixelix.ui.composables.followers.FollowersMainComposable
import com.daniebeler.pfpixelix.ui.composables.mention.MentionComposable
import com.daniebeler.pfpixelix.ui.composables.newpost.NewPostComposable
import com.daniebeler.pfpixelix.ui.composables.notifications.NotificationsComposable
import com.daniebeler.pfpixelix.ui.composables.profile.other_profile.OtherProfileComposable
import com.daniebeler.pfpixelix.ui.composables.profile.own_profile.AccountSwitchBottomSheet
import com.daniebeler.pfpixelix.ui.composables.profile.own_profile.OwnProfileComposable
import com.daniebeler.pfpixelix.ui.composables.search.SearchComposable
import com.daniebeler.pfpixelix.ui.composables.settings.about_instance.AboutInstanceComposable
import com.daniebeler.pfpixelix.ui.composables.settings.about_pixelix.AboutPixelixComposable
import com.daniebeler.pfpixelix.ui.composables.settings.blocked_accounts.BlockedAccountsComposable
Expand All @@ -60,11 +86,13 @@ import com.daniebeler.pfpixelix.ui.composables.settings.muted_accounts.MutedAcco
import com.daniebeler.pfpixelix.ui.composables.settings.preferences.PreferencesComposable
import com.daniebeler.pfpixelix.ui.composables.single_post.SinglePostComposable
import com.daniebeler.pfpixelix.ui.composables.timelines.hashtag_timeline.HashtagTimelineComposable
import com.daniebeler.pfpixelix.ui.composables.trending.TrendingComposable
import com.daniebeler.pfpixelix.ui.theme.PixelixTheme
import com.daniebeler.pfpixelix.utils.Navigate
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject

Expand All @@ -91,12 +119,13 @@ class MainActivity : ComponentActivity() {
}
}

@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)
enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)

var avatar = ""
runBlocking {
val loginData: LoginData? = currentLoginDataUseCase()
if (loginData == null || loginData.accessToken.isBlank() || loginData.baseUrl.isBlank()) {
Expand All @@ -119,23 +148,30 @@ class MainActivity : ComponentActivity() {
)
)
}
avatar = loginData.avatar
}
}

setContent {
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
var showAccountSwitchBottomSheet by remember { mutableStateOf(false) }

PixelixTheme {
val navController: NavHostController = rememberNavController()

Scaffold(bottomBar = {
BottomBar(navController = navController)
Scaffold(contentWindowInsets = WindowInsets(0.dp), bottomBar = {
BottomBar(
navController = navController,
avatar = avatar,
openAccountSwitchBottomSheet = { showAccountSwitchBottomSheet = true },
context = this
)
}) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues)
) {


NavigationGraph(
navController = navController
navController = navController,
)
val destination = intent.extras?.getString(KEY_DESTINATION) ?: ""
if (destination.isNotBlank()) {
Expand Down Expand Up @@ -175,11 +211,23 @@ class MainActivity : ComponentActivity() {


}
if (showAccountSwitchBottomSheet) {
ModalBottomSheet(
onDismissRequest = {
showAccountSwitchBottomSheet = false
}, sheetState = sheetState
) {
AccountSwitchBottomSheet(closeBottomSheet = {
showAccountSwitchBottomSheet = false
}, null)
}
}
}
}
}
}


fun updateAuthToV2(context: Context, baseUrl: String, accessToken: String) {
val intent = Intent(context, LoginActivity::class.java)
intent.putExtra("base_url", baseUrl)
Expand Down Expand Up @@ -207,10 +255,6 @@ fun NavigationGraph(navController: NavHostController) {
composable(Destinations.HomeScreen.route) {
HomeComposable(navController)
}
composable(Destinations.TrendingScreen.route) { navBackStackEntry ->
val page = navBackStackEntry.arguments?.getString("page") ?: "posts"
TrendingComposable(navController, page)
}

composable(Destinations.NotificationsScreen.route) {
NotificationsComposable(navController)
Expand Down Expand Up @@ -329,7 +373,7 @@ fun NavigationGraph(navController: NavHostController) {
}

composable(Destinations.Search.route) {
SearchComposable(navController)
ExploreComposable(navController)
}

composable(Destinations.Conversation.route) {
Expand All @@ -342,37 +386,90 @@ fun NavigationGraph(navController: NavHostController) {
ChatComposable(navController = navController, accountId = id)
}
}

composable(Destinations.Mention.route) { navBackStackEntry ->
val mentionId = navBackStackEntry.arguments?.getString("mentionid")
mentionId?.let { id ->
MentionComposable(navController = navController, mentionId = id)
}
}
}
}

@Composable
fun BottomBar(navController: NavHostController) {
fun BottomBar(
navController: NavHostController,
avatar: String,
openAccountSwitchBottomSheet: () -> Unit,
context: Context
) {
val screens = listOf(
Destinations.HomeScreen,
Destinations.Search,
Destinations.TrendingScreen,
Destinations.NotificationsScreen,
Destinations.OwnProfile
)
val systemNavigationBarHeight =
WindowInsets.navigationBars.asPaddingValues(Density(context)).calculateBottomPadding()

NavigationBar {
NavigationBar(
modifier = Modifier.height(60.dp + systemNavigationBarHeight)
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route

screens.forEach { screen ->
val interactionSource = remember { MutableInteractionSource() }
val coroutineScope = rememberCoroutineScope()
var isLongPress by remember { mutableStateOf(false) }

LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
is PressInteraction.Press -> {
isLongPress = false // Reset flag before starting detection
coroutineScope.launch {
delay(500L) // Long-press threshold
if (screen.route == Destinations.OwnProfile.route) {
openAccountSwitchBottomSheet()
}
isLongPress = true
}
}

is PressInteraction.Release, is PressInteraction.Cancel -> {
coroutineScope.coroutineContext.cancelChildren()
}
}
}
}
NavigationBarItem(icon = {
if (currentRoute == screen.route) {
if (screen.route == Destinations.OwnProfile.route && avatar.isNotBlank()) {
Row(verticalAlignment = Alignment.CenterVertically) {
AsyncImage(
model = avatar,
error = painterResource(id = R.drawable.default_avatar),
contentDescription = "",
modifier = Modifier
.height(30.dp)
.width(30.dp)
.clip(CircleShape)
)
Icon(
Icons.Outlined.UnfoldMore,
contentDescription = "long press to switch account"
)
}
} else if (currentRoute == screen.route) {
Icon(
imageVector = screen.activeIcon!!,
modifier = Modifier.size(32.dp),
contentDescription = ""
modifier = Modifier.size(30.dp),
contentDescription = stringResource(screen.label)
)
} else {
Icon(
imageVector = screen.icon!!,
modifier = Modifier.size(32.dp),
contentDescription = ""
modifier = Modifier.size(30.dp),
contentDescription = stringResource(screen.label)
)
}
},
Expand All @@ -381,8 +478,11 @@ fun BottomBar(navController: NavHostController) {
selectedIconColor = MaterialTheme.colorScheme.inverseSurface,
indicatorColor = Color.Transparent
),
interactionSource = interactionSource,
onClick = {
Navigate.navigateWithPopUp(screen.route, navController)
if (!isLongPress) {
Navigate.navigateWithPopUp(screen.route, navController)
}
})
}
}
Expand Down
Loading
Loading