Skip to content

Commit 6d8c5dc

Browse files
committed
Gravatar is now optional (turned off by default) and uses sha256
Fixes #291
1 parent b522dfd commit 6d8c5dc

File tree

12 files changed

+96
-13
lines changed

12 files changed

+96
-13
lines changed

src/main/kotlin/com/jetpackduba/gitnuro/extensions/StringExtensions.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ package com.jetpackduba.gitnuro.extensions
22

33
import com.jetpackduba.gitnuro.exceptions.SshException
44
import com.jetpackduba.gitnuro.system.systemSeparator
5-
import java.math.BigInteger
65
import java.security.MessageDigest
76

8-
val String.md5: String
9-
get() {
10-
val md = MessageDigest.getInstance("MD5")
11-
return BigInteger(1, md.digest(this.toByteArray())).toString(16).padStart(32, '0')
12-
}
7+
@OptIn(ExperimentalStdlibApi::class)
8+
val String.sha256: String
9+
get() = MessageDigest.getInstance("SHA-256")
10+
.digest(this.toByteArray(Charsets.UTF_8))
11+
.toHexString()
1312

1413
val String.dirName: String
1514
get() {

src/main/kotlin/com/jetpackduba/gitnuro/main.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.jetpackduba.gitnuro
22

3+
import com.jetpackduba.gitnuro.extensions.sha256
34
import com.jetpackduba.gitnuro.repositories.initPreferencesPath
45
import org.bouncycastle.jce.provider.BouncyCastleProvider
56
import java.security.Security

src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ private const val PREF_SWAP_UNCOMMITTED_CHANGES = "inverseUncommittedChanges"
3434
private const val PREF_TERMINAL_PATH = "terminalPath"
3535
private const val PREF_SHOW_CHANGES_AS_TREE = "showChangesAsTree"
3636
private const val PREF_USE_PROXY = "useProxy"
37+
private const val PREF_USE_GRAVATAR = "useGravatar"
3738
private const val PREF_PROXY_TYPE = "proxyType"
3839
private const val PREF_PROXY_HOST_NAME = "proxyHostName"
3940
private const val PREF_PROXY_PORT = "proxyPort"
@@ -104,6 +105,9 @@ class AppSettingsRepository @Inject constructor() {
104105
private val _terminalPathFlow = MutableStateFlow(terminalPath)
105106
val terminalPathFlow = _terminalPathFlow.asStateFlow()
106107

108+
private val _useGravatarFlow = MutableStateFlow(useGravatar)
109+
val useGravatarFlow = _useGravatarFlow.asStateFlow()
110+
107111
private val _proxyFlow = MutableStateFlow(
108112
ProxySettings(
109113
useProxy,
@@ -300,6 +304,15 @@ class AppSettingsRepository @Inject constructor() {
300304
_terminalPathFlow.value = value
301305
}
302306

307+
var useGravatar: Boolean
308+
get() {
309+
return preferences.getBoolean(PREF_USE_GRAVATAR, false)
310+
}
311+
set(value) {
312+
preferences.putBoolean(PREF_USE_GRAVATAR, value)
313+
_useGravatarFlow.value = value
314+
}
315+
303316
var useProxy: Boolean
304317
get() {
305318
return preferences.getBoolean(PREF_USE_PROXY, false)

src/main/kotlin/com/jetpackduba/gitnuro/ui/CommitChanges.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fun CommitChanges(
7070
val changesListScroll by commitChangesViewModel.changesLazyListState.collectAsState()
7171
val textScroll by commitChangesViewModel.textScroll.collectAsState()
7272
val showAsTree by commitChangesViewModel.showAsTree.collectAsState()
73+
val useGravatar by commitChangesViewModel.useGravatar.collectAsState()
7374

7475
var searchFilter by remember(commitChangesViewModel, showSearch, commitChangesStatus) {
7576
mutableStateOf(commitChangesViewModel.searchFilter.value)
@@ -92,6 +93,7 @@ fun CommitChanges(
9293
textScroll = textScroll,
9394
searchFilter = searchFilter,
9495
onDiffSelected = onDiffSelected,
96+
useGravatar = useGravatar,
9597
onSearchFilterToggled = { visible ->
9698
commitChangesViewModel.onSearchFilterToggled(visible)
9799
},
@@ -118,6 +120,7 @@ private fun CommitChangesView(
118120
showSearch: Boolean,
119121
showAsTree: Boolean,
120122
searchFilter: TextFieldValue,
123+
useGravatar: Boolean,
121124
onBlame: (String) -> Unit,
122125
onHistory: (String) -> Unit,
123126
onDiffSelected: (DiffEntry) -> Unit,
@@ -191,7 +194,11 @@ private fun CommitChangesView(
191194

192195
}
193196

194-
MessageAuthorFooter(commit, textScroll)
197+
MessageAuthorFooter(
198+
commit,
199+
textScroll,
200+
useGravatar,
201+
)
195202
}
196203
}
197204

@@ -286,6 +293,7 @@ private fun Header(
286293
private fun MessageAuthorFooter(
287294
commit: RevCommit,
288295
textScroll: ScrollState,
296+
useGravatar: Boolean,
289297
) {
290298
Column(
291299
modifier = Modifier
@@ -306,7 +314,12 @@ private fun MessageAuthorFooter(
306314
)
307315
}
308316

309-
Author(commit.shortName, commit.name, commit.authorIdent)
317+
Author(
318+
shortName = commit.shortName,
319+
name = commit.name,
320+
author = commit.authorIdent,
321+
useGravatar = useGravatar,
322+
)
310323
}
311324
}
312325

@@ -315,6 +328,7 @@ fun Author(
315328
shortName: String,
316329
name: String,
317330
author: PersonIdent,
331+
useGravatar: Boolean,
318332
) {
319333
var copied by remember(name) { mutableStateOf(false) }
320334
val scope = rememberCoroutineScope()
@@ -332,6 +346,7 @@ fun Author(
332346
.padding(horizontal = 16.dp)
333347
.size(40.dp),
334348
personIdent = author,
349+
useGravatar = useGravatar,
335350
)
336351

337352
Column(

src/main/kotlin/com/jetpackduba/gitnuro/ui/FileHistory.kt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,14 @@ private fun HistoryContent(
122122
historyState: HistoryState,
123123
onCommitSelected: (RevCommit) -> Unit,
124124
) {
125+
val useGravatar by historyViewModel.useGravatar.collectAsState()
125126
val textScrollState by historyViewModel.lazyListState.collectAsState()
126127
val viewDiffResult by historyViewModel.viewDiffResult.collectAsState()
127128

128129
when (historyState) {
129130
is HistoryState.Loaded -> HistoryContentLoaded(
130131
historyState = historyState,
132+
useGravatar = useGravatar,
131133
viewDiffResult = viewDiffResult,
132134
scrollState = textScrollState,
133135
onCommitSelected = onCommitSelected,
@@ -140,6 +142,7 @@ private fun HistoryContent(
140142
@Composable
141143
fun HistoryContentLoaded(
142144
historyState: HistoryState.Loaded,
145+
useGravatar: Boolean,
143146
viewDiffResult: ViewDiffResult?,
144147
scrollState: LazyListState,
145148
onCommitSelected: (RevCommit) -> Unit,
@@ -155,7 +158,11 @@ fun HistoryContentLoaded(
155158
.background(MaterialTheme.colors.surface)
156159
) {
157160
items(historyState.commits) { commit ->
158-
HistoryCommit(commit, onCommitSelected = { onCommitSelected(commit) })
161+
HistoryCommit(
162+
useGravatar = useGravatar,
163+
commit = commit,
164+
onCommitSelected = { onCommitSelected(commit) }
165+
)
159166
}
160167
}
161168

@@ -214,7 +221,11 @@ fun HistoryContentLoaded(
214221
}
215222

216223
@Composable
217-
fun HistoryCommit(commit: RevCommit, onCommitSelected: () -> Unit) {
224+
fun HistoryCommit(
225+
useGravatar: Boolean,
226+
commit: RevCommit,
227+
onCommitSelected: () -> Unit,
228+
) {
218229
Row(
219230
modifier = Modifier
220231
.fillMaxWidth()
@@ -223,6 +234,7 @@ fun HistoryCommit(commit: RevCommit, onCommitSelected: () -> Unit) {
223234
verticalAlignment = Alignment.CenterVertically
224235
) {
225236
AvatarImage(
237+
useGravatar = useGravatar,
226238
modifier = Modifier
227239
.padding(horizontal = 16.dp)
228240
.size(40.dp),

src/main/kotlin/com/jetpackduba/gitnuro/ui/components/AvatarImage.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@ import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.draw.clip
1414
import androidx.compose.ui.graphics.Color
1515
import androidx.compose.ui.graphics.ImageBitmap
16-
import com.jetpackduba.gitnuro.extensions.md5
16+
import com.jetpackduba.gitnuro.extensions.sha256
1717
import com.jetpackduba.gitnuro.images.rememberNetworkImageOrNull
1818
import org.eclipse.jgit.lib.PersonIdent
1919

2020
@Composable
2121
fun AvatarImage(
2222
modifier: Modifier = Modifier,
23+
useGravatar: Boolean,
2324
personIdent: PersonIdent,
2425
color: Color = MaterialTheme.colors.primary,
2526
) {
2627
Box(
2728
modifier = modifier
2829
.clip(CircleShape)
2930
) {
30-
val avatar = rememberAvatar(personIdent.emailAddress)
31+
val avatar = if (useGravatar) {
32+
rememberAvatar(personIdent.emailAddress)
33+
} else {
34+
null
35+
}
36+
3137
if (avatar == null) {
3238
Box(
3339
modifier = Modifier
@@ -54,7 +60,7 @@ fun AvatarImage(
5460

5561
@Composable
5662
fun rememberAvatar(email: String): ImageBitmap? {
57-
val url = "https://www.gravatar.com/avatar/${email.md5}?s=60&d=404"
63+
val url = "https://www.gravatar.com/avatar/${email.sha256}?s=60&d=404"
5864
return rememberNetworkImageOrNull(
5965
url = url,
6066
placeHolderImageRes = null,

src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ val linesHeightTypesList = listOf(
416416
private fun Appearance(settingsViewModel: SettingsViewModel) {
417417
val currentTheme by settingsViewModel.themeState.collectAsState()
418418
val currentLinesHeightType by settingsViewModel.linesHeightTypeState.collectAsState()
419+
val useGravatar by settingsViewModel.useGravatarFlow.collectAsState()
419420
val (errorToDisplay, setErrorToDisplay) = remember { mutableStateOf<Error?>(null) }
420421

421422
SettingDropDown(
@@ -510,6 +511,15 @@ private fun Appearance(settingsViewModel: SettingsViewModel) {
510511
}
511512
)
512513

514+
SettingToggle(
515+
title = "Use Gravatar's avatars",
516+
subtitle = "The e-mail addresses will be hashed using SHA256 before sending the request to gravatar.com",
517+
value = useGravatar,
518+
onValueChanged = {
519+
settingsViewModel.useGravatar = it
520+
}
521+
)
522+
513523
if (errorToDisplay != null) {
514524
ErrorDialog(
515525
errorToDisplay,

src/main/kotlin/com/jetpackduba/gitnuro/ui/log/Log.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,13 @@ fun Log(
110110
val logStatusState = logViewModel.logStatus.collectAsState()
111111
val logStatus = logStatusState.value
112112
val showLogDialog by logViewModel.logDialog.collectAsState()
113+
val useGravatar by logViewModel.useGravatar.collectAsState()
113114

114115
when (logStatus) {
115116
is LogStatus.Loaded -> LogLoaded(
116117
logViewModel = logViewModel,
117118
logStatus = logStatus,
119+
useGravatar = useGravatar,
118120
showLogDialog = showLogDialog,
119121
selectedItem = selectedItem,
120122
repositoryState = repositoryState,
@@ -151,6 +153,7 @@ private fun LogLoaded(
151153
showLogDialog: LogDialog,
152154
selectedItem: SelectedItem,
153155
repositoryState: RepositoryState,
156+
useGravatar: Boolean,
154157
changeUpstreamBranchDialogViewModel: () -> ChangeUpstreamBranchDialogViewModel,
155158
onRequestMoreLogItems: (Int) -> Unit,
156159
) {
@@ -274,6 +277,7 @@ private fun LogLoaded(
274277
selectedItem = selectedItem,
275278
commitList = commitList,
276279
graphWidth = graphWidth,
280+
useGravatar = useGravatar,
277281
onMerge = { ref -> logViewModel.mergeBranch(ref) },
278282
onRebase = { ref -> logViewModel.rebaseBranch(ref) },
279283
onShowLogDialog = { dialog -> logViewModel.showDialog(dialog) },
@@ -514,6 +518,7 @@ fun CommitsList(
514518
onShowLogDialog: (LogDialog) -> Unit,
515519
onCopyBranchNameToClipboard: (Ref) -> Unit,
516520
graphWidth: Dp,
521+
useGravatar: Boolean,
517522
horizontalScrollState: ScrollState,
518523
) {
519524
val scope = rememberCoroutineScope()
@@ -567,6 +572,7 @@ fun CommitsList(
567572
CommitLine(
568573
graphWidth = graphWidth,
569574
graphNode = graphNode,
575+
useGravatar = useGravatar,
570576
isSelected = selectedCommit?.name == graphNode.name,
571577
currentBranch = logStatus.currentBranch,
572578
matchesSearchFilter = searchFilter?.contains(graphNode),
@@ -809,6 +815,7 @@ fun SummaryEntry(
809815
private fun CommitLine(
810816
graphWidth: Dp,
811817
graphNode: GraphNode,
818+
useGravatar: Boolean,
812819
isSelected: Boolean,
813820
currentBranch: Ref?,
814821
matchesSearchFilter: Boolean?,
@@ -879,6 +886,7 @@ private fun CommitLine(
879886
modifier = Modifier
880887
.fillMaxHeight(),
881888
plotCommit = graphNode,
889+
useGravatar = useGravatar,
882890
nodeColor = nodeColor,
883891
isSelected = isSelected,
884892
)
@@ -1055,6 +1063,7 @@ fun SimpleDividerLog(modifier: Modifier) {
10551063
fun CommitsGraph(
10561064
modifier: Modifier = Modifier,
10571065
plotCommit: GraphNode,
1066+
useGravatar: Boolean,
10581067
nodeColor: Color,
10591068
isSelected: Boolean,
10601069
) {
@@ -1131,6 +1140,7 @@ fun CommitsGraph(
11311140
.align(Alignment.CenterStart)
11321141
.padding(start = ((itemPosition + 1) * 30 - 15).dp),
11331142
plotCommit = plotCommit,
1143+
useGravatar = useGravatar,
11341144
color = nodeColor,
11351145
)
11361146
}
@@ -1139,6 +1149,7 @@ fun CommitsGraph(
11391149
@Composable
11401150
fun CommitNode(
11411151
modifier: Modifier = Modifier,
1152+
useGravatar: Boolean,
11421153
plotCommit: GraphNode,
11431154
color: Color,
11441155
) {
@@ -1171,6 +1182,7 @@ fun CommitNode(
11711182
.clip(CircleShape)
11721183
) {
11731184
AvatarImage(
1185+
useGravatar = useGravatar,
11741186
modifier = Modifier.fillMaxSize(),
11751187
personIdent = plotCommit.authorIdent,
11761188
color = color,

src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/CommitChangesViewModel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class CommitChangesViewModel @Inject constructor(
4242
val textScroll = MutableStateFlow(ScrollState(0))
4343

4444
val showAsTree = appSettingsRepository.showChangesAsTreeFlow
45+
val useGravatar = appSettingsRepository.useGravatarFlow
46+
4547
private val treeContractedDirectories = MutableStateFlow(emptyList<String>())
4648

4749
private val _commitChangesState = MutableStateFlow<CommitChangesState>(CommitChangesState.Loading)

src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/HistoryViewModel.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@ class HistoryViewModel @Inject constructor(
2626
private val settings: AppSettingsRepository,
2727
private val generateSplitHunkFromDiffResultUseCase: GenerateSplitHunkFromDiffResultUseCase,
2828
private val tabScope: CoroutineScope,
29+
private val appSettingsRepository: AppSettingsRepository,
2930
) {
3031
private val _historyState = MutableStateFlow<HistoryState>(HistoryState.Loading(""))
3132
val historyState: StateFlow<HistoryState> = _historyState
3233

3334
private val _viewDiffResult = MutableStateFlow<ViewDiffResult>(ViewDiffResult.None)
3435
val viewDiffResult: StateFlow<ViewDiffResult> = _viewDiffResult
36+
37+
val useGravatar = appSettingsRepository.useGravatarFlow
38+
3539
var filePath: String = ""
3640

3741
val lazyListState = MutableStateFlow(

0 commit comments

Comments
 (0)