Skip to content

Commit

Permalink
1.新增笔记内容长文本折叠/展开功能
Browse files Browse the repository at this point in the history
2.优化开始书写保存体验
  • Loading branch information
JIULANG9 committed Aug 11, 2024
1 parent 32701ef commit dd2b7e2
Show file tree
Hide file tree
Showing 23 changed files with 330 additions and 146 deletions.
74 changes: 36 additions & 38 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import kotlin.collections.*

plugins {
id("com.android.application")
id("kotlin-android")
Expand All @@ -13,9 +14,9 @@ android {
compileSdk = BuildConfig.compileSdk


defaultConfig{
defaultConfig {
applicationId = BuildConfig.applicationId
minSdk=BuildConfig.minSdkVersion
minSdk = BuildConfig.minSdkVersion
targetSdk = BuildConfig.targetSdkVersion
versionCode = BuildConfig.versionCode
versionName = BuildConfig.versionName
Expand Down Expand Up @@ -47,7 +48,6 @@ android {
buildTypes {
debug {
isMinifyEnabled = false
isZipAlignEnabled = false
isShrinkResources = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
Expand All @@ -58,13 +58,11 @@ android {

release {
isMinifyEnabled = true
isZipAlignEnabled = true
isShrinkResources = true
isDebuggable = false //是否debug
isJniDebuggable = false // 是否打开jniDebuggable开关
isZipAlignEnabled = true //压缩优化
isJniDebuggable = false // 是否打开jniDebuggable开关

proguardFiles (
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
Expand Down Expand Up @@ -96,47 +94,47 @@ android {

dependencies {

implementation (AndroidX.coreKtx)
implementation (AndroidX.coresplashscreen)
implementation (AndroidX.Lifecycle.runtimeKtx)
implementation (AndroidX.Compose.activity)
implementation (AndroidX.Compose.ui)
implementation (AndroidX.Compose.tooling_preview)
implementation (AndroidX.Compose.material3)
implementation (AndroidX.Compose.runtime)
implementation (AndroidX.Compose.ui_util)
implementation (AndroidX.Compose.Accompanist.insets)
implementation (AndroidX.Compose.Accompanist.placeholder)
implementation (AndroidX.Compose.Accompanist.systemuicontroller)
implementation (AndroidX.Paging.compose)
implementation (AndroidX.Paging.runtimeKtx)
implementation (AndroidX.Navigation.compose)
implementation (AndroidX.Navigation.uiKtx)
implementation (AndroidX.Navigation.animation)
implementation (AndroidX.Work.runtime)
implementation (AndroidX.Work.runtime_ktx)
implementation (AndroidX.multidex)
implementation (AndroidX.Documentfile)
implementation(AndroidX.coreKtx)
implementation(AndroidX.coresplashscreen)
implementation(AndroidX.Lifecycle.runtimeKtx)
implementation(AndroidX.Compose.activity)
implementation(AndroidX.Compose.ui)
implementation(AndroidX.Compose.tooling_preview)
implementation(AndroidX.Compose.material3)
implementation(AndroidX.Compose.runtime)
implementation(AndroidX.Compose.ui_util)
implementation(AndroidX.Compose.Accompanist.insets)
implementation(AndroidX.Compose.Accompanist.placeholder)
implementation(AndroidX.Compose.Accompanist.systemuicontroller)
implementation(AndroidX.Paging.compose)
implementation(AndroidX.Paging.runtimeKtx)
implementation(AndroidX.Navigation.compose)
implementation(AndroidX.Navigation.uiKtx)
implementation(AndroidX.Navigation.animation)
implementation(AndroidX.Work.runtime)
implementation(AndroidX.Work.runtime_ktx)
implementation(AndroidX.multidex)
implementation(AndroidX.Documentfile)
//Hilt
implementation (AndroidX.Hilt.common)
kapt (AndroidX.Hilt.compiler)
implementation (AndroidX.Hilt.navigation_compose)
implementation(AndroidX.Hilt.common)
kapt(AndroidX.Hilt.compiler)
implementation(AndroidX.Hilt.navigation_compose)

//Room
implementation(AndroidX.Room.runtime)
kapt(AndroidX.Room.compiler)
implementation(AndroidX.Room.ktx)

// debugImplementation(ThirdPart.leakcanary)
// debugImplementation(ThirdPart.leakcanary)

implementation(project(Lib.base))
implementation(project(Lib.common))

debugImplementation (AndroidX.Compose.uiTooling)
debugImplementation (AndroidX.Compose.ui_test_manifest)
debugImplementation(AndroidX.Compose.uiTooling)
debugImplementation(AndroidX.Compose.ui_test_manifest)

testImplementation (Testing.junit)
androidTestImplementation (Testing.androidJunit)
androidTestImplementation (Testing.espresso)
androidTestImplementation (Testing.compose_ui_test)
testImplementation(Testing.junit)
androidTestImplementation(Testing.androidJunit)
androidTestImplementation(Testing.espresso)
androidTestImplementation(Testing.compose_ui_test)
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ object AppSystemSetManage {
var jumpToWeChat: Boolean
get() = DataStoreUtils.readBooleanData(JumpToWeChat, false)
set(value) = DataStoreUtils.saveSyncBooleanData(JumpToWeChat, value = value)

/**
* 长文本自动折叠 默认开启
*/
var longTextAutoFold: Boolean
get() = DataStoreUtils.readBooleanData("long_text_auto_fold", true)
set(value) = DataStoreUtils.saveSyncBooleanData("long_text_auto_fold", value = value)
/**
* 首页索引
*/
Expand Down
27 changes: 22 additions & 5 deletions app/src/main/kotlin/com/wordsfairy/note/ui/common/AppModifier.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.wordsfairy.note.ui.common

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.view.inputmethod.InputMethodManager
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
Expand All @@ -14,9 +13,7 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.semantics.Role
import androidx.core.content.ContextCompat.getSystemService
import com.wordsfairy.base.tools.hideKeyboard
import com.wordsfairy.note.MainActivity

Expand All @@ -29,6 +26,7 @@ const val VIEW_CLICK_INTERVAL_TIME = 800
/**
* 防止重复点击(有的人可能会手抖连点两次,造成奇怪的bug)
*/
@SuppressLint("ModifierFactoryUnreferencedReceiver")
@Composable
inline fun Modifier.click(
time: Int = VIEW_CLICK_INTERVAL_TIME,
Expand Down Expand Up @@ -113,7 +111,7 @@ fun Modifier.autoCloseKeyboard(activity: Activity = MainActivity.CONTEXT): Modif
)
}


//不会触发水波纹之类的效果
@Composable
fun Modifier.clickableNoIndication(focusManager: FocusManager) =
this.clickable(
Expand All @@ -126,6 +124,25 @@ fun Modifier.clickableNoIndication(focusManager: FocusManager) =
MutableInteractionSource()
}
)
/**
* 点击时,自动隐藏键盘
* 同时解决 输入框 换行时,输入法消失的问题
*/
@Composable
fun Modifier.onPressNoIndication(focusManager: FocusManager) =
this.pointerInput(Unit) {
detectTapGestures(
onDoubleTap = {
},
onLongPress = {
},
onPress = {
},
onTap = {
focusManager.clearFocus()
}
)
}

fun HapticFeedback.vibration() {
this.performHapticFeedback(HapticFeedbackType.TextHandleMove)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import com.wordsfairy.note.ext.flow.noteStartWith
import com.wordsfairy.note.ext.flowbus.observeEvent
import com.wordsfairy.note.ext.flowbus.postEventValue
import com.wordsfairy.note.ui.common.clickableNoIndication
import com.wordsfairy.note.ui.common.onPressNoIndication
import com.wordsfairy.note.ui.common.vibration

import com.wordsfairy.note.ui.theme.AppColor
Expand Down Expand Up @@ -165,7 +166,7 @@ fun CreateNoteUI(
.fillMaxSize()
.blur(if (isShowAddFolderDialog) 6.dp else 0.dp)
.background(WordsFairyTheme.colors.whiteBackground)
.clickableNoIndication(focusManager)
.onPressNoIndication(focusManager)
.systemBarsPadding()
) {
Row(
Expand Down Expand Up @@ -284,16 +285,9 @@ fun NoteContentEditView(
Column(
Modifier.padding(horizontal = 6.dp)
) {
Spacer(Modifier.height(6.dp))

var appendTextValue by remember { mutableStateOf("") }
/** 笔记输入框 */
CreateNoteContentEditView(
text = viewState.noteContent,
addendText = appendTextValue,
placeholder = "开始书学"
) {
intentChannel.trySend(ViewIntent.NoteContentChanged(it))
}

Row(Modifier.fillMaxWidth()) {
Spacer(Modifier.width(6.dp))
if (viewState.noteEntity != null) {
Expand All @@ -313,6 +307,15 @@ fun NoteContentEditView(
}
Spacer(Modifier.width(6.dp))
}
/** 笔记输入框 */
CreateNoteContentEditView(
text = viewState.noteContent,
addendText = appendTextValue,
placeholder = "开始书学"
) {
intentChannel.trySend(ViewIntent.NoteContentChanged(it))
}
Spacer(Modifier.height(6.dp))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.wordsfairy.note.constants.GlobalData
import com.wordsfairy.note.constants.NavigateRouter
import com.wordsfairy.note.data.entity.NoteEntity
import com.wordsfairy.note.ext.flowbus.postEventValue
import kotlinx.coroutines.ExperimentalCoroutinesApi
import java.net.URLDecoder


Expand All @@ -26,6 +27,8 @@ fun ColumnScope.toNoteDetailsUI(it: NoteEntity, isSearch: Boolean) {
GlobalData.noteDetailsNoteEntity = it
postEventValue(EventBus.NavController, NavigateRouter.DetailPage.Detail + "/$isSearch")
}

@OptIn(ExperimentalCoroutinesApi::class)
@ExperimentalAnimationApi
fun NavGraphBuilder.noteDetailScreen(
navController: NavHostController
Expand All @@ -44,6 +47,6 @@ fun NavGraphBuilder.noteDetailScreen(
val isSearch = backStackEntry.arguments?.getBoolean(Detail_Is_Search)
NoteDetailsUI(onBack = {
navController.navigateUp()
}, isSearch?:false)
}, isSearch ?: false)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.wordsfairy.note.ext.coreui.rememberFlowWithLifecycle
import com.wordsfairy.note.ext.flow.noteStartWith
import com.wordsfairy.note.ext.flowbus.postEventValue
import com.wordsfairy.note.ui.common.clickableNoIndication
import com.wordsfairy.note.ui.common.onPressNoIndication
import com.wordsfairy.note.ui.common.vibration

import com.wordsfairy.note.ui.page.create.ChooseClassifyButton
Expand Down Expand Up @@ -115,7 +116,7 @@ fun NoteDetailsUI(
.fillMaxSize()
.blur(if (isShowContentModifierDialog) 6.dp else 0.dp)
.background(WordsFairyTheme.colors.whiteBackground)
.clickableNoIndication(focusManager) //点击无涟漪效果
.onPressNoIndication(focusManager) //点击无涟漪效果
.systemBarsPadding()
) {
Row(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.wordsfairy.note.ext.coreui.rememberFlowWithLifecycle
import com.wordsfairy.note.ext.flow.noteStartWith
import com.wordsfairy.note.ui.common.autoCloseKeyboard
import com.wordsfairy.note.ui.common.clickableNoIndication
import com.wordsfairy.note.ui.common.onPressNoIndication
import com.wordsfairy.note.ui.theme.AppResId
import com.wordsfairy.note.ui.widgets.SearchEditView
import kotlinx.coroutines.channels.Channel
Expand Down Expand Up @@ -80,7 +81,7 @@ fun ContentSearchUI(
Column(
Modifier
.fillMaxSize()
.clickableNoIndication(focusManager),
.onPressNoIndication(focusManager),
horizontalAlignment = Alignment.CenterHorizontally
) {
SearchEditView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ sealed interface ViewIntent : MviIntent {
object Initial : ViewIntent
data class SearchEngines(val url: String) : ViewIntent
data class CopyJumpToWeChat(val jump: Boolean) : ViewIntent
// 长文本自动折叠
data class LongTextAutoFold(val fold: Boolean) : ViewIntent
object RecycleNote : ViewIntent
object RecycleNoteContents : ViewIntent
data class ShowDialog(val dialogDataBean: DialogDataBean) : ViewIntent
Expand All @@ -25,13 +27,15 @@ data class ViewState(
val isLoading: Boolean,
val currentUrl: String,
val jumpToWeChat: Boolean,
val longTextAutoFold: Boolean,
val dialogDataBean: DialogDataBean
) : MviViewState {
companion object {
fun initial() = ViewState(
isLoading = true,
currentUrl = AppSystemSetManage.searchEngines,
jumpToWeChat = AppSystemSetManage.jumpToWeChat,
longTextAutoFold = AppSystemSetManage.longTextAutoFold,
dialogDataBean = DialogDataBean.create(),
)
}
Expand All @@ -53,12 +57,14 @@ internal sealed interface PartialChange {
is Dialog -> vs
is SetSearchEngines -> vs.copy(currentUrl = url)
is CopyJumpToWeChat -> vs.copy(jumpToWeChat = jump)
is LongTextAutoFold -> vs.copy(longTextAutoFold = fold)
is ShowDialog -> vs.copy(dialogDataBean = dialogDataBean)
}
}
object Init : UI()
data class SetSearchEngines(val url:String) : UI()
data class CopyJumpToWeChat(val jump:Boolean) : UI()
data class LongTextAutoFold(val fold:Boolean) : UI()
data class ShowDialog(val dialogDataBean :DialogDataBean) : UI()
data class Dialog(val dialogDataBean :DialogDataBean) : UI()
}
Expand Down
Loading

0 comments on commit dd2b7e2

Please sign in to comment.