Skip to content

Commit d7304cf

Browse files
committed
Fix Text Editor crash
1 parent f8e6a7e commit d7304cf

File tree

4 files changed

+149
-140
lines changed

4 files changed

+149
-140
lines changed

app/src/main/java/com/raival/compose/file/explorer/screen/textEditor/TextEditorActivity.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import android.os.Bundle
44
import androidx.activity.compose.BackHandler
55
import androidx.activity.compose.setContent
66
import androidx.activity.enableEdgeToEdge
7+
import androidx.compose.animation.AnimatedVisibility
8+
import androidx.compose.animation.expandIn
9+
import androidx.compose.animation.shrinkOut
10+
import androidx.compose.animation.slideInVertically
11+
import androidx.compose.animation.slideOutVertically
712
import androidx.compose.foundation.layout.Column
813
import androidx.compose.foundation.layout.fillMaxSize
914
import androidx.compose.foundation.layout.size
@@ -116,11 +121,15 @@ class TextEditorActivity : BaseActivity() {
116121
)
117122
}
118123
}
119-
SearchPanel(
120-
codeEditor,
121-
textEditorManager.getFileInstance()!!.searcher,
122-
textEditorManager.showSearchPanel
123-
)
124+
AnimatedVisibility(
125+
visible = textEditorManager.showSearchPanel && textEditorManager.getFileInstance() != null,
126+
enter = expandIn(expandFrom = Alignment.TopCenter) + slideInVertically(
127+
initialOffsetY = { it }),
128+
exit = shrinkOut(shrinkTowards = Alignment.BottomCenter) + slideOutVertically(
129+
targetOffsetY = { it })
130+
) {
131+
SearchPanel(codeEditor, textEditorManager.getFileInstance()!!.searcher)
132+
}
124133
}
125134
}
126135
}

app/src/main/java/com/raival/compose/file/explorer/screen/textEditor/TextEditorManager.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,11 @@ class TextEditorManager {
435435
scope.launch {
436436
isReading = true
437437

438-
val text = activeFile.readText()
438+
val text = activeFile.file.inputStream().use {
439+
it.bufferedReader().use { reader ->
440+
reader.readText()
441+
}
442+
}
439443
val fileInstance = getFileInstance(bringToTop = true)
440444

441445
if (fileInstance isNot null) {
Lines changed: 116 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package com.raival.compose.file.explorer.screen.textEditor.ui
22

3-
import androidx.compose.animation.AnimatedVisibility
4-
import androidx.compose.animation.expandIn
5-
import androidx.compose.animation.shrinkOut
6-
import androidx.compose.animation.slideInVertically
7-
import androidx.compose.animation.slideOutVertically
83
import androidx.compose.foundation.background
94
import androidx.compose.foundation.layout.Arrangement
105
import androidx.compose.foundation.layout.Column
@@ -18,7 +13,6 @@ import androidx.compose.material3.TextField
1813
import androidx.compose.material3.surfaceColorAtElevation
1914
import androidx.compose.runtime.Composable
2015
import androidx.compose.runtime.LaunchedEffect
21-
import androidx.compose.ui.Alignment
2216
import androidx.compose.ui.Modifier
2317
import androidx.compose.ui.res.stringResource
2418
import androidx.compose.ui.unit.dp
@@ -32,154 +26,147 @@ import io.github.rosemoe.sora.widget.EditorSearcher
3226
@Composable
3327
fun SearchPanel(
3428
codeEditor: CodeEditor,
35-
searcher: Searcher,
36-
show: Boolean
29+
searcher: Searcher
3730
) {
38-
AnimatedVisibility(
39-
visible = show,
40-
enter = expandIn(expandFrom = Alignment.TopCenter) + slideInVertically(initialOffsetY = { it }),
41-
exit = shrinkOut(shrinkTowards = Alignment.BottomCenter) + slideOutVertically(targetOffsetY = { it })
31+
fun codeEditorSearcher() = codeEditor.searcher
32+
fun hasQuery() =
33+
searcher.query.isNotEmpty() && codeEditorSearcher().matchedPositionCount > 0
34+
35+
Column(
36+
modifier = Modifier
37+
.fillMaxWidth()
38+
.background(colorScheme.surfaceContainer)
39+
.padding(8.dp)
4240
) {
43-
fun codeEditorSearcher() = codeEditor.searcher
44-
fun hasQuery() =
45-
searcher.query.isNotEmpty() && codeEditorSearcher().matchedPositionCount > 0
41+
LaunchedEffect(Unit) {
42+
if (searcher.query.isNotEmpty()) {
43+
codeEditor.searcher.search(
44+
searcher.query,
45+
EditorSearcher.SearchOptions(!searcher.caseSensitive, searcher.useRegex)
46+
)
47+
}
48+
}
4649

47-
Column(
48-
modifier = Modifier
49-
.fillMaxWidth()
50-
.background(colorScheme.surfaceContainer)
51-
.padding(8.dp)
52-
) {
53-
LaunchedEffect(Unit) {
54-
if (searcher.query.isNotEmpty()) {
50+
TextField(
51+
modifier = Modifier.fillMaxWidth(),
52+
value = searcher.query,
53+
onValueChange = {
54+
searcher.query = it
55+
if (it.isEmpty()) {
56+
codeEditor.searcher.stopSearch()
57+
codeEditor.invalidate()
58+
} else {
5559
codeEditor.searcher.search(
56-
searcher.query,
60+
it,
5761
EditorSearcher.SearchOptions(!searcher.caseSensitive, searcher.useRegex)
5862
)
5963
}
60-
}
64+
},
65+
label = { Text(text = stringResource(R.string.find)) },
66+
)
67+
68+
Space(size = 4.dp)
6169

62-
TextField(
63-
modifier = Modifier.fillMaxWidth(),
64-
value = searcher.query,
65-
onValueChange = {
66-
searcher.query = it
67-
if (it.isEmpty()) {
70+
TextField(
71+
modifier = Modifier.fillMaxWidth(),
72+
value = searcher.replace,
73+
onValueChange = { searcher.replace = it },
74+
label = { Text(text = stringResource(R.string.replace)) },
75+
)
76+
77+
Row(
78+
modifier = Modifier
79+
.fillMaxWidth()
80+
.padding(horizontal = 4.dp),
81+
horizontalArrangement = Arrangement.Center
82+
) {
83+
CheckableText(
84+
modifier = Modifier
85+
.weight(1f)
86+
.padding(12.dp),
87+
checked = searcher.useRegex,
88+
onCheckedChange = {
89+
searcher.useRegex = it
90+
if (searcher.query.isEmpty()) {
6891
codeEditor.searcher.stopSearch()
6992
codeEditor.invalidate()
7093
} else {
7194
codeEditor.searcher.search(
72-
it,
73-
EditorSearcher.SearchOptions(!searcher.caseSensitive, searcher.useRegex)
95+
searcher.query,
96+
EditorSearcher.SearchOptions(
97+
!searcher.caseSensitive,
98+
searcher.useRegex
99+
)
74100
)
75101
}
76102
},
77-
label = { Text(text = stringResource(R.string.find)) },
78-
)
79-
80-
Space(size = 4.dp)
81-
82-
TextField(
83-
modifier = Modifier.fillMaxWidth(),
84-
value = searcher.replace,
85-
onValueChange = { searcher.replace = it },
86-
label = { Text(text = stringResource(R.string.replace)) },
103+
uncheckedBoxBackgroundColor = colorScheme.surfaceColorAtElevation(8.dp),
104+
text = { Text(text = stringResource(R.string.regex)) }
87105
)
88106

89-
Row(
107+
CheckableText(
90108
modifier = Modifier
91-
.fillMaxWidth()
92-
.padding(horizontal = 4.dp),
93-
horizontalArrangement = Arrangement.Center
94-
) {
95-
CheckableText(
96-
modifier = Modifier
97-
.weight(1f)
98-
.padding(12.dp),
99-
checked = searcher.useRegex,
100-
onCheckedChange = {
101-
searcher.useRegex = it
102-
if (searcher.query.isEmpty()) {
103-
codeEditor.searcher.stopSearch()
104-
codeEditor.invalidate()
105-
} else {
106-
codeEditor.searcher.search(
107-
searcher.query,
108-
EditorSearcher.SearchOptions(
109-
!searcher.caseSensitive,
110-
searcher.useRegex
111-
)
112-
)
113-
}
114-
},
115-
uncheckedBoxBackgroundColor = colorScheme.surfaceColorAtElevation(8.dp),
116-
text = { Text(text = stringResource(R.string.regex)) }
117-
)
118-
119-
CheckableText(
120-
modifier = Modifier
121-
.weight(1f)
122-
.padding(12.dp),
123-
checked = searcher.caseSensitive,
124-
onCheckedChange = {
125-
searcher.caseSensitive = it
126-
if (searcher.query.isEmpty()) {
127-
codeEditor.searcher.stopSearch()
128-
codeEditor.invalidate()
129-
} else {
130-
codeEditor.searcher.search(
131-
searcher.query,
132-
EditorSearcher.SearchOptions(
133-
!searcher.caseSensitive,
134-
searcher.useRegex
135-
)
109+
.weight(1f)
110+
.padding(12.dp),
111+
checked = searcher.caseSensitive,
112+
onCheckedChange = {
113+
searcher.caseSensitive = it
114+
if (searcher.query.isEmpty()) {
115+
codeEditor.searcher.stopSearch()
116+
codeEditor.invalidate()
117+
} else {
118+
codeEditor.searcher.search(
119+
searcher.query,
120+
EditorSearcher.SearchOptions(
121+
!searcher.caseSensitive,
122+
searcher.useRegex
136123
)
137-
}
138-
},
139-
uncheckedBoxBackgroundColor = colorScheme.surfaceColorAtElevation(8.dp),
140-
text = { Text(text = stringResource(R.string.case_sensitive)) }
141-
)
142-
}
143-
144-
Row(
145-
modifier = Modifier.fillMaxWidth()
146-
) {
147-
Space(size = 8.dp)
148-
OutlinedButton(
149-
onClick = {
150-
if (hasQuery()) codeEditorSearcher().replaceCurrentMatch(searcher.replace)
124+
)
151125
}
152-
) {
153-
Text(text = stringResource(R.string.rep))
126+
},
127+
uncheckedBoxBackgroundColor = colorScheme.surfaceColorAtElevation(8.dp),
128+
text = { Text(text = stringResource(R.string.case_sensitive)) }
129+
)
130+
}
131+
132+
Row(
133+
modifier = Modifier.fillMaxWidth()
134+
) {
135+
Space(size = 8.dp)
136+
OutlinedButton(
137+
onClick = {
138+
if (hasQuery()) codeEditorSearcher().replaceCurrentMatch(searcher.replace)
154139
}
155-
Space(size = 8.dp)
156-
OutlinedButton(
157-
onClick = {
158-
if (hasQuery()) codeEditorSearcher().replaceAll(searcher.replace)
159-
}
160-
) {
161-
Text(text = stringResource(R.string.all))
140+
) {
141+
Text(text = stringResource(R.string.rep))
142+
}
143+
Space(size = 8.dp)
144+
OutlinedButton(
145+
onClick = {
146+
if (hasQuery()) codeEditorSearcher().replaceAll(searcher.replace)
162147
}
163-
Space(size = 8.dp)
164-
OutlinedButton(
165-
modifier = Modifier.weight(1f),
166-
onClick = {
167-
if (hasQuery()) codeEditorSearcher().gotoPrevious()
168-
}
169-
) {
170-
Text(text = stringResource(R.string.prev))
148+
) {
149+
Text(text = stringResource(R.string.all))
150+
}
151+
Space(size = 8.dp)
152+
OutlinedButton(
153+
modifier = Modifier.weight(1f),
154+
onClick = {
155+
if (hasQuery()) codeEditorSearcher().gotoPrevious()
171156
}
172-
Space(size = 8.dp)
173-
OutlinedButton(
174-
modifier = Modifier.weight(1f),
175-
onClick = {
176-
if (hasQuery()) codeEditorSearcher().gotoNext()
177-
}
178-
) {
179-
Text(text = stringResource(R.string.next))
157+
) {
158+
Text(text = stringResource(R.string.prev))
159+
}
160+
Space(size = 8.dp)
161+
OutlinedButton(
162+
modifier = Modifier.weight(1f),
163+
onClick = {
164+
if (hasQuery()) codeEditorSearcher().gotoNext()
180165
}
181-
Space(size = 8.dp)
166+
) {
167+
Text(text = stringResource(R.string.next))
182168
}
169+
Space(size = 8.dp)
183170
}
184171
}
185172
}

app/src/main/java/com/raival/compose/file/explorer/screen/viewer/text/TextViewerActivity.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ package com.raival.compose.file.explorer.screen.viewer.text
33
import android.net.Uri
44
import androidx.activity.compose.BackHandler
55
import androidx.activity.compose.setContent
6+
import androidx.compose.animation.AnimatedVisibility
7+
import androidx.compose.animation.expandIn
8+
import androidx.compose.animation.shrinkOut
9+
import androidx.compose.animation.slideInVertically
10+
import androidx.compose.animation.slideOutVertically
611
import androidx.compose.foundation.layout.Column
712
import androidx.compose.foundation.layout.fillMaxSize
813
import androidx.compose.foundation.layout.fillMaxWidth
@@ -167,11 +172,15 @@ class TextViewerActivity : ViewerActivity() {
167172
)
168173
HorizontalDivider()
169174
BottomBarView(codeEditor, symbols)
170-
SearchPanel(
171-
codeEditor,
172-
textViewerInstance.searcher,
173-
textViewerInstance.showSearchPanel
174-
)
175+
AnimatedVisibility(
176+
visible = textViewerInstance.showSearchPanel,
177+
enter = expandIn(expandFrom = Alignment.TopCenter) + slideInVertically(
178+
initialOffsetY = { it }),
179+
exit = shrinkOut(shrinkTowards = Alignment.BottomCenter) + slideOutVertically(
180+
targetOffsetY = { it })
181+
) {
182+
SearchPanel(codeEditor, textViewerInstance.searcher)
183+
}
175184
}
176185
}
177186
}

0 commit comments

Comments
 (0)