Porównaj commity

...

73 Commity

Autor SHA1 Wiadomość Data
Vitor Pamplona 539433014e Fixes Notification for Follows now showing Zaps 2024-03-26 21:05:24 -04:00
Vitor Pamplona d3f54a7082 Removes the Draft dependency for signer implementations 2024-03-26 16:56:58 -04:00
Vitor Pamplona d3a0ae743a
Merge pull request #749 from greenart7c3/main
save a draft while you are typing the post
2024-03-26 15:24:59 -04:00
Vitor Pamplona 6690d5391c Fixes controller comparison for keep playing 2024-03-26 15:06:55 -04:00
Vitor Pamplona d61d684a27
Merge pull request #818 from jiftechnify/url-preview
Fix garbled URL preview for non UTF-8 HTML, with optimization
2024-03-26 13:40:15 -04:00
jiftechnify 4f84fad0cd
remove jsoup version 2024-03-27 01:03:29 +09:00
Vitor Pamplona cd32c4db72 Makes a cache for Media Items 2024-03-26 11:56:10 -04:00
jiftechnify a71ce69cab
support tags in quoted attribute value 2024-03-27 00:47:35 +09:00
Vitor Pamplona b45f9bd460 Avoids launching coroutines that were just launched. 2024-03-26 09:09:35 -04:00
Vitor Pamplona 75ac17b57d increases the time to notify to 15 minutes 2024-03-26 08:35:15 -04:00
Vitor Pamplona fa4745038f Uses the cached pool instead of the scheduled pool for translation services. 2024-03-26 08:34:45 -04:00
Vitor Pamplona 0182011487 Fixes NPE with the cached state. 2024-03-25 20:11:23 -04:00
Vitor Pamplona 37fdb8b2aa Removes unecessary parameters in the UserDisplay function 2024-03-25 17:58:54 -04:00
Vitor Pamplona 9ade18e1c1 Adds a bot field to the user info 2024-03-25 17:57:27 -04:00
Vitor Pamplona aff6588791 Removing unnecessary layouts from the top bar 2024-03-25 17:57:11 -04:00
Vitor Pamplona 4274d2ddbd Blocks previews from being too big 2024-03-25 17:54:41 -04:00
Vitor Pamplona 63600f4782 Removes time measuring log 2024-03-25 16:45:21 -04:00
Vitor Pamplona 5deb9af477 Avoids publishing with two equal hashtags. 2024-03-25 16:41:52 -04:00
Vitor Pamplona 38e701a363 Moves the Following Vector to a native composable. 2024-03-25 16:41:38 -04:00
greenart7c3 6e6fa66c53
Merge branch 'main' into main 2024-03-25 17:34:22 -03:00
Vitor Pamplona 1f60d39cbf turning hashtag icons into programmable vectors 2024-03-25 16:02:36 -04:00
Vitor Pamplona 8ba474e79a Adjusting some of the icon sizes on the galleries 2024-03-25 14:23:36 -04:00
Vitor Pamplona 1123b3b3c1 Removes the need to observe author changes to event. 2024-03-25 13:51:08 -04:00
jiftechnify bffb9f3778
remove jsoup from dependencies 2024-03-26 02:42:15 +09:00
jiftechnify e11961695f
parse HTML as little as possible 2024-03-26 02:31:06 +09:00
jiftechnify 042579ddfb
remove unnecessary items from mata-tag canditates for getting URL info 2024-03-25 23:53:47 +09:00
jiftechnify d0aa7430ca
optimize HTML charset detection 2024-03-25 23:53:47 +09:00
jiftechnify 3434c31487
fix garbled URL preview for non-UTF-8 HTML 2024-03-25 23:53:43 +09:00
Vitor Pamplona 7eefbee0e3 Realigning the reaction icons and texts between main feed and video feed. 2024-03-25 10:44:10 -04:00
greenart7c3 ed4d867622 save draft when toogling nip4 and nip 44 2024-03-25 07:48:30 -03:00
greenart7c3 27db2b91ab save draft when changing options from polls and classifieds 2024-03-25 07:32:31 -03:00
greenart7c3 a2316b6ed0
Merge branch 'main' into main 2024-03-25 07:08:08 -03:00
Vitor Pamplona a26b5490b2 updates compose 2024-03-24 18:53:11 -04:00
greenart7c3 62a114b981
Merge branch 'main' into main 2024-03-22 08:48:47 -03:00
greenart7c3 8d7a3f4d5e
Merge branch 'main' into main 2024-03-20 15:13:33 -03:00
greenart7c3 c087042f7d Merge branch 'main' into main 2024-03-20 15:10:32 -03:00
greenart7c3 644d2fc2bb add generic draft event to default permissions 2024-03-20 14:56:29 -03:00
greenart7c3 ea33cc77ed add edit draft in the dropdown menu and the long press popup 2024-03-20 14:50:53 -03:00
greenart7c3 090b643f43 add edit draft in the dropdown menu and the long press popup 2024-03-20 14:45:45 -03:00
greenart7c3 220ce75f19 add validations to draft notes 2024-03-20 10:25:41 -03:00
greenart7c3 bc180ae210 fix draft delete not working 2024-03-20 09:31:31 -03:00
greenart7c3 5910ef199f fix build after merge 2024-03-20 07:22:55 -03:00
greenart7c3 499939ed68
Merge branch 'main' into main 2024-03-20 07:06:24 -03:00
greenart7c3 940fa2ee8d add debouncer 2024-03-18 17:47:15 -03:00
greenart7c3 f6e5af3e98 support for dms, streams and communities 2024-03-18 16:18:12 -03:00
greenart7c3 8b3e3e7af8 support Classifieds 2024-03-18 14:51:50 -03:00
greenart7c3 84faa7557e add support for polls 2024-03-18 14:37:51 -03:00
greenart7c3 f7ab925b1d fix delete on close 2024-03-18 14:21:58 -03:00
greenart7c3 204eaa4606 fix crash when loading draft from channels or lives 2024-03-18 11:16:13 -03:00
greenart7c3 1c249eed20 load post from draft 2024-03-18 10:56:36 -03:00
greenart7c3 3cc32ecd9a create a loadFromDraft method 2024-03-18 09:09:00 -03:00
greenart7c3 0a20d5484b show drafts as soon as its created 2024-03-18 08:39:55 -03:00
greenart7c3 6e4f1269dd add todo 2024-03-18 07:43:19 -03:00
greenart7c3 eba0837e52 fix draftnotes filter 2024-03-18 07:20:30 -03:00
greenart7c3 d682518ddb
Merge branch 'main' into main 2024-03-18 07:07:32 -03:00
greenart7c3 f949d5624e add draft support for public chat screen 2024-03-15 13:35:54 -03:00
greenart7c3 2bc2890d08 add draft support for other event kinds 2024-03-15 12:35:14 -03:00
greenart7c3 f3f8bc1b65 show draft in the simplified view 2024-03-15 10:45:53 -03:00
greenart7c3 99e9514d6c remove drafts from shared prefs 2024-03-15 10:38:22 -03:00
greenart7c3 8ade5b7e5f
Merge branch 'main' into main 2024-03-15 09:18:38 -03:00
greenart7c3 e292affbe6 add draft in the home feed 2024-03-15 09:08:35 -03:00
greenart7c3 fa5d992010 add draftevent class 2024-03-13 13:24:22 -03:00
greenart7c3 0d47e8b823
Merge branch 'main' into main 2024-03-13 11:24:12 -03:00
greenart7c3 91b0d5b7fc
Merge branch 'main' into main 2024-03-13 07:17:52 -03:00
greenart7c3 4938ba03a6
Merge branch 'main' into main 2024-03-08 12:35:23 -03:00
greenart7c3 4d2c17cd1c fix draft on nip94 2024-02-28 11:16:19 -03:00
greenart7c3 53987336c0
Merge branch 'main' into main 2024-02-28 10:59:39 -03:00
greenart7c3 cdd620987b implement reply draft 2024-01-24 09:55:31 -03:00
greenart7c3 2c086f76e2 open the post screen after editing the text 2024-01-24 08:40:55 -03:00
greenart7c3 99965ecd2d add an edit draft in the drawer 2024-01-24 08:22:35 -03:00
greenart7c3 ba7c59fdd5 draft was not saving in some places 2024-01-24 08:22:11 -03:00
greenart7c3 76a93f84c3 fix default value for the draft note 2024-01-24 08:21:04 -03:00
greenart7c3 26a1624399 save a draft while you are typing the post 2024-01-22 09:02:44 -03:00
124 zmienionych plików z 6613 dodań i 817 usunięć

Wyświetl plik

@ -205,9 +205,6 @@ dependencies {
// Websockets API // Websockets API
implementation libs.okhttp implementation libs.okhttp
// HTML Parsing for Link Preview
implementation libs.jsoup
// Encrypted Key Storage // Encrypted Key Storage
implementation libs.androidx.security.crypto.ktx implementation libs.androidx.security.crypto.ktx

Wyświetl plik

@ -56,6 +56,7 @@ import com.vitorpamplona.quartz.events.ClassifiedsEvent
import com.vitorpamplona.quartz.events.Contact import com.vitorpamplona.quartz.events.Contact
import com.vitorpamplona.quartz.events.ContactListEvent import com.vitorpamplona.quartz.events.ContactListEvent
import com.vitorpamplona.quartz.events.DeletionEvent import com.vitorpamplona.quartz.events.DeletionEvent
import com.vitorpamplona.quartz.events.DraftEvent
import com.vitorpamplona.quartz.events.EmojiPackEvent import com.vitorpamplona.quartz.events.EmojiPackEvent
import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent
import com.vitorpamplona.quartz.events.EmojiUrl import com.vitorpamplona.quartz.events.EmojiUrl
@ -845,7 +846,14 @@ class Account(
} }
suspend fun delete(note: Note) { suspend fun delete(note: Note) {
return delete(listOf(note)) if (note.isDraft()) {
note.event?.let {
val drafts = LocalCache.getDrafts(it.id())
return delete(drafts)
}
} else {
return delete(listOf(note))
}
} }
suspend fun delete(notes: List<Note>) { suspend fun delete(notes: List<Note>) {
@ -897,10 +905,17 @@ class Account(
fun broadcast(note: Note) { fun broadcast(note: Note) {
note.event?.let { note.event?.let {
if (it is WrappedEvent && it.host != null) { if (note.isDraft()) {
it.host?.let { hostEvent -> Client.send(hostEvent) } val drafts = LocalCache.getDrafts(it.id())
drafts.forEach { draftNote ->
broadcast(draftNote)
}
} else { } else {
Client.send(it) if (it is WrappedEvent && it.host != null) {
it.host?.let { hostEvent -> Client.send(hostEvent) }
} else {
Client.send(it)
}
} }
} }
} }
@ -929,6 +944,7 @@ class Account(
fun timestamp(note: Note) { fun timestamp(note: Note) {
if (!isWriteable()) return if (!isWriteable()) return
if (note.isDraft()) return
val id = note.event?.id() ?: note.idHex val id = note.event?.id() ?: note.idHex
@ -1318,6 +1334,7 @@ class Account(
relayList: List<Relay>? = null, relayList: List<Relay>? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<Event>? = null, nip94attachments: List<Event>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1345,14 +1362,24 @@ class Account(
geohash = geohash, geohash = geohash,
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
signer = signer, signer = signer,
isDraft = draftTag != null,
) { ) {
Client.send(it, relayList = relayList) if (draftTag != null) {
LocalCache.justConsume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent, relayList = relayList)
LocalCache.justConsume(draftEvent, null)
LocalCache.justConsume(it, null)
LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
}
} else {
Client.send(it, relayList = relayList)
LocalCache.justConsume(it, null)
replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } } replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } }
addresses?.forEach { addresses?.forEach {
LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let { LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let {
Client.send(it, relayList = relayList) Client.send(it, relayList = relayList)
}
} }
} }
} }
@ -1373,6 +1400,7 @@ class Account(
relayList: List<Relay>? = null, relayList: List<Relay>? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1396,20 +1424,30 @@ class Account(
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
forkedFrom = forkedFrom, forkedFrom = forkedFrom,
signer = signer, signer = signer,
isDraft = draftTag != null,
) { ) {
Client.send(it, relayList = relayList) if (draftTag != null) {
LocalCache.justConsume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent, relayList = relayList)
// broadcast replied notes LocalCache.justConsume(draftEvent, null)
replyingTo?.let { LocalCache.justConsume(it, null)
LocalCache.getNoteIfExists(replyingTo)?.event?.let { LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
Client.send(it, relayList = relayList)
} }
} } else {
replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } } Client.send(it, relayList = relayList)
addresses?.forEach { LocalCache.justConsume(it, null)
LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let {
Client.send(it, relayList = relayList) // broadcast replied notes
replyingTo?.let {
LocalCache.getNoteIfExists(replyingTo)?.event?.let {
Client.send(it, relayList = relayList)
}
}
replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } }
addresses?.forEach {
LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let {
Client.send(it, relayList = relayList)
}
} }
} }
} }
@ -1430,6 +1468,7 @@ class Account(
relayList: List<Relay>? = null, relayList: List<Relay>? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1453,20 +1492,30 @@ class Account(
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
forkedFrom = forkedFrom, forkedFrom = forkedFrom,
signer = signer, signer = signer,
isDraft = draftTag != null,
) { ) {
Client.send(it, relayList = relayList) if (draftTag != null) {
LocalCache.justConsume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent, relayList = relayList)
// broadcast replied notes LocalCache.justConsume(draftEvent, null)
replyingTo?.let { LocalCache.justConsume(it, null)
LocalCache.getNoteIfExists(replyingTo)?.event?.let { LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
Client.send(it, relayList = relayList)
} }
} } else {
replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } } Client.send(it, relayList = relayList)
addresses?.forEach { LocalCache.justConsume(it, null)
LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let {
Client.send(it, relayList = relayList) // broadcast replied notes
replyingTo?.let {
LocalCache.getNoteIfExists(replyingTo)?.event?.let {
Client.send(it, relayList = relayList)
}
}
replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } }
addresses?.forEach {
LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let {
Client.send(it, relayList = relayList)
}
} }
} }
} }
@ -1510,6 +1559,7 @@ class Account(
relayList: List<Relay>? = null, relayList: List<Relay>? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1533,15 +1583,25 @@ class Account(
zapRaiserAmount = zapRaiserAmount, zapRaiserAmount = zapRaiserAmount,
geohash = geohash, geohash = geohash,
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
isDraft = draftTag != null,
) { ) {
Client.send(it, relayList = relayList) if (draftTag != null) {
LocalCache.justConsume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent, relayList = relayList)
LocalCache.justConsume(draftEvent, null)
LocalCache.justConsume(it, null)
LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
}
} else {
Client.send(it, relayList = relayList)
LocalCache.justConsume(it, null)
// Rebroadcast replies and tags to the current relay set // Rebroadcast replies and tags to the current relay set
replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } } replyTo?.forEach { it.event?.let { Client.send(it, relayList = relayList) } }
addresses?.forEach { addresses?.forEach {
LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let { LocalCache.getAddressableNoteIfExists(it.toTag())?.event?.let {
Client.send(it, relayList = relayList) Client.send(it, relayList = relayList)
}
} }
} }
} }
@ -1557,6 +1617,7 @@ class Account(
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1574,9 +1635,19 @@ class Account(
geohash = geohash, geohash = geohash,
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
signer = signer, signer = signer,
isDraft = draftTag != null,
) { ) {
Client.send(it) if (draftTag != null) {
LocalCache.justConsume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent)
LocalCache.justConsume(draftEvent, null)
LocalCache.justConsume(it, null)
LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
}
} else {
Client.send(it)
LocalCache.justConsume(it, null)
}
} }
} }
@ -1590,6 +1661,7 @@ class Account(
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1608,9 +1680,19 @@ class Account(
geohash = geohash, geohash = geohash,
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
signer = signer, signer = signer,
isDraft = draftTag != null,
) { ) {
Client.send(it) if (draftTag != null) {
LocalCache.justConsume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent)
LocalCache.justConsume(draftEvent, null)
LocalCache.justConsume(it, null)
LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
}
} else {
Client.send(it)
LocalCache.justConsume(it, null)
}
} }
} }
@ -1624,6 +1706,7 @@ class Account(
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
sendPrivateMessage( sendPrivateMessage(
message, message,
@ -1635,6 +1718,7 @@ class Account(
zapRaiserAmount, zapRaiserAmount,
geohash, geohash,
nip94attachments, nip94attachments,
draftTag,
) )
} }
@ -1648,6 +1732,7 @@ class Account(
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1667,9 +1752,19 @@ class Account(
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
signer = signer, signer = signer,
advertiseNip18 = false, advertiseNip18 = false,
isDraft = draftTag != null,
) { ) {
Client.send(it) if (draftTag != null) {
LocalCache.consume(it, null) DraftEvent.create(draftTag, it, signer) { draftEvent ->
Client.send(draftEvent)
LocalCache.justConsume(draftEvent, null)
LocalCache.justConsume(it, null)
LocalCache.addDraft(draftTag, draftEvent.id(), it.id())
}
} else {
Client.send(it)
LocalCache.consume(it, null)
}
} }
} }
@ -1684,6 +1779,7 @@ class Account(
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null, geohash: String? = null,
nip94attachments: List<FileHeaderEvent>? = null, nip94attachments: List<FileHeaderEvent>? = null,
draftTag: String? = null,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@ -1701,9 +1797,19 @@ class Account(
zapRaiserAmount = zapRaiserAmount, zapRaiserAmount = zapRaiserAmount,
geohash = geohash, geohash = geohash,
nip94attachments = nip94attachments, nip94attachments = nip94attachments,
draftTag = draftTag,
signer = signer, signer = signer,
) { ) {
broadcastPrivately(it) if (draftTag != null) {
DraftEvent.create(draftTag, it.msg, signer) { draftEvent ->
Client.send(draftEvent)
LocalCache.justConsume(draftEvent, null)
LocalCache.justConsume(it.msg, null)
LocalCache.addDraft(draftTag, draftEvent.id(), it.msg.id())
}
} else {
broadcastPrivately(it)
}
} }
} }
@ -1851,6 +1957,7 @@ class Account(
isPrivate: Boolean, isPrivate: Boolean,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
if (note.isDraft()) return
if (note is AddressableNote) { if (note is AddressableNote) {
BookmarkListEvent.addReplaceable( BookmarkListEvent.addReplaceable(
@ -2218,6 +2325,7 @@ class Account(
fun cachedDecryptContent(note: Note): String? { fun cachedDecryptContent(note: Note): String? {
val event = note.event val event = note.event
return if (event is PrivateDmEvent && isWriteable()) { return if (event is PrivateDmEvent && isWriteable()) {
event.cachedContentFor(signer) event.cachedContentFor(signer)
} else if (event is LnZapRequestEvent && event.isPrivateZap() && isWriteable()) { } else if (event is LnZapRequestEvent && event.isPrivateZap() && isWriteable()) {

Wyświetl plik

@ -0,0 +1,23 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.model
data class Drafts(val mainId: String, val eventId: String)

Wyświetl plik

@ -25,9 +25,24 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.hashtags.Amethyst
import com.vitorpamplona.amethyst.commons.hashtags.Btc
import com.vitorpamplona.amethyst.commons.hashtags.Cashu
import com.vitorpamplona.amethyst.commons.hashtags.Coffee
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Footstr
import com.vitorpamplona.amethyst.commons.hashtags.Grownostr
import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.commons.hashtags.Mate
import com.vitorpamplona.amethyst.commons.hashtags.Nostr
import com.vitorpamplona.amethyst.commons.hashtags.Plebs
import com.vitorpamplona.amethyst.commons.hashtags.Skull
import com.vitorpamplona.amethyst.commons.hashtags.Tunestr
import com.vitorpamplona.amethyst.commons.hashtags.Weed
import com.vitorpamplona.amethyst.commons.hashtags.Zap
import com.vitorpamplona.amethyst.commons.richtext.HashTagSegment import com.vitorpamplona.amethyst.commons.richtext.HashTagSegment
import com.vitorpamplona.amethyst.commons.richtext.RegularTextSegment import com.vitorpamplona.amethyst.commons.richtext.RegularTextSegment
import com.vitorpamplona.amethyst.ui.components.HashTag import com.vitorpamplona.amethyst.ui.components.HashTag
@ -42,7 +57,7 @@ fun RenderHashTagIcons() {
ThemeComparisonColumn { ThemeComparisonColumn {
RenderRegular( RenderRegular(
"Testing rendering of hashtags: #Bitcoin, #nostr, #lightning, #zap, #amethyst, #cashu, #plebs, #coffee, #skullofsatoshi, #grownostr, #footstr, #tunestr, #weed", "Testing rendering of hashtags: #Bitcoin, #nostr, #lightning, #zap, #amethyst, #cashu, #plebs, #coffee, #skullofsatoshi, #grownostr, #footstr, #tunestr, #weed, #mate",
EmptyTagList, EmptyTagList,
) { word, state -> ) { word, state ->
when (word) { when (word) {
@ -67,28 +82,30 @@ fun checkForHashtagWithIcon(tag: String): HashtagIcon? {
"grownostr", "gardening", "garden" -> growstr "grownostr", "gardening", "garden" -> growstr
"footstr" -> footstr "footstr" -> footstr
"tunestr", "music", "nowplaying" -> tunestr "tunestr", "music", "nowplaying" -> tunestr
"mate", "matechain", "matestr" -> matestr
"weed", "weedstr", "420", "cannabis", "marijuana" -> weed "weed", "weedstr", "420", "cannabis", "marijuana" -> weed
else -> null else -> null
} }
} }
val bitcoin = HashtagIcon(R.drawable.ht_btc, "Bitcoin", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val bitcoin = HashtagIcon(CustomHashTagIcons.Btc, "Bitcoin", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val nostr = HashtagIcon(R.drawable.ht_nostr, "Nostr", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val nostr = HashtagIcon(CustomHashTagIcons.Nostr, "Nostr", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val lightning = HashtagIcon(R.drawable.lightning, "Lightning", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val lightning = HashtagIcon(CustomHashTagIcons.Lightning, "Lightning", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val zap = HashtagIcon(R.drawable.zap, "Zap", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val zap = HashtagIcon(CustomHashTagIcons.Zap, "Zap", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val amethyst = HashtagIcon(R.drawable.amethyst, "Amethyst", Modifier.padding(start = 2.dp, bottom = 1.dp, top = 1.dp)) val amethyst = HashtagIcon(CustomHashTagIcons.Amethyst, "Amethyst", Modifier.padding(start = 2.dp, bottom = 1.dp, top = 1.dp))
val cashu = HashtagIcon(R.drawable.cashu, "Cashu", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val cashu = HashtagIcon(CustomHashTagIcons.Cashu, "Cashu", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val plebs = HashtagIcon(R.drawable.plebs, "Pleb", Modifier.padding(start = 2.dp, bottom = 1.dp, top = 1.dp)) val plebs = HashtagIcon(CustomHashTagIcons.Plebs, "Pleb", Modifier.padding(start = 2.dp, bottom = 1.dp, top = 1.dp))
val coffee = HashtagIcon(R.drawable.coffee, "Coffee", Modifier.padding(start = 3.dp, bottom = 1.dp, top = 1.dp)) val coffee = HashtagIcon(CustomHashTagIcons.Coffee, "Coffee", Modifier.padding(start = 3.dp, bottom = 1.dp, top = 1.dp))
val skull = HashtagIcon(R.drawable.skull, "SkullofSatoshi", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val skull = HashtagIcon(CustomHashTagIcons.Skull, "SkullofSatoshi", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val growstr = HashtagIcon(R.drawable.grownostr, "GrowNostr", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val growstr = HashtagIcon(CustomHashTagIcons.Grownostr, "GrowNostr", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val footstr = HashtagIcon(R.drawable.footstr, "Footstr", Modifier.padding(start = 2.dp, bottom = 1.dp, top = 1.dp)) val footstr = HashtagIcon(CustomHashTagIcons.Footstr, "Footstr", Modifier.padding(start = 2.dp, bottom = 1.dp, top = 1.dp))
val tunestr = HashtagIcon(R.drawable.tunestr, "Tunestr", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp)) val tunestr = HashtagIcon(CustomHashTagIcons.Tunestr, "Tunestr", Modifier.padding(start = 1.dp, bottom = 1.dp, top = 1.dp))
val weed = HashtagIcon(R.drawable.weed, "Weed", Modifier.padding(start = 1.dp, bottom = 0.dp, top = 0.dp)) val weed = HashtagIcon(CustomHashTagIcons.Weed, "Weed", Modifier.padding(start = 1.dp, bottom = 0.dp, top = 0.dp))
val matestr = HashtagIcon(CustomHashTagIcons.Mate, "Mate", Modifier.padding(start = 1.dp, bottom = 0.dp, top = 0.dp))
@Immutable @Immutable
class HashtagIcon( class HashtagIcon(
val icon: Int, val icon: ImageVector,
val description: String, val description: String,
val modifier: Modifier = Modifier, val modifier: Modifier = Modifier,
) )

Wyświetl plik

@ -62,6 +62,7 @@ import com.vitorpamplona.quartz.events.CommunityListEvent
import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent import com.vitorpamplona.quartz.events.CommunityPostApprovalEvent
import com.vitorpamplona.quartz.events.ContactListEvent import com.vitorpamplona.quartz.events.ContactListEvent
import com.vitorpamplona.quartz.events.DeletionEvent import com.vitorpamplona.quartz.events.DeletionEvent
import com.vitorpamplona.quartz.events.DraftEvent
import com.vitorpamplona.quartz.events.EmojiPackEvent import com.vitorpamplona.quartz.events.EmojiPackEvent
import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent
import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.Event
@ -128,7 +129,7 @@ object LocalCache {
val users = LargeCache<HexKey, User>() val users = LargeCache<HexKey, User>()
val notes = LargeCache<HexKey, Note>() val notes = LargeCache<HexKey, Note>()
val addressables = LargeCache<String, AddressableNote>() val addressables = LargeCache<String, AddressableNote>()
val drafts = ConcurrentHashMap<String, MutableList<Drafts>>()
val channels = LargeCache<HexKey, Channel>() val channels = LargeCache<HexKey, Channel>()
val awaitingPaymentRequests = ConcurrentHashMap<HexKey, Pair<Note?, (LnZapPaymentResponseEvent) -> Unit>>(10) val awaitingPaymentRequests = ConcurrentHashMap<HexKey, Pair<Note?, (LnZapPaymentResponseEvent) -> Unit>>(10)
@ -141,6 +142,34 @@ object LocalCache {
return null return null
} }
fun draftNotes(draftTag: String): List<Note> {
return drafts[draftTag]?.mapNotNull {
getNoteIfExists(it.mainId)
} ?: listOf()
}
fun getDrafts(eventId: String): List<Note> {
return drafts.filter {
it.value.any { it.eventId == eventId }
}.values.map {
it.mapNotNull {
checkGetOrCreateNote(it.mainId)
}
}.flatten()
}
fun addDraft(
key: String,
mainId: String,
draftId: String,
) {
val data = drafts[key] ?: mutableListOf()
if (data.none { it.mainId == mainId }) {
data.add(Drafts(mainId, draftId))
drafts[key] = data
}
}
fun getOrCreateUser(key: HexKey): User { fun getOrCreateUser(key: HexKey): User {
// checkNotInMainThread() // checkNotInMainThread()
require(isValidHex(key = key)) { "$key is not a valid hex" } require(isValidHex(key = key)) { "$key is not a valid hex" }
@ -2013,6 +2042,13 @@ object LocalCache {
} }
} }
private fun consume(
event: DraftEvent,
relay: Relay?,
) {
consumeBaseReplaceable(event, relay)
}
fun justConsume( fun justConsume(
event: Event, event: Event,
relay: Relay?, relay: Relay?,
@ -2050,6 +2086,7 @@ object LocalCache {
} }
is ContactListEvent -> consume(event) is ContactListEvent -> consume(event)
is DeletionEvent -> consume(event) is DeletionEvent -> consume(event)
is DraftEvent -> consume(event, relay)
is EmojiPackEvent -> consume(event, relay) is EmojiPackEvent -> consume(event, relay)
is EmojiPackSelectionEvent -> consume(event, relay) is EmojiPackSelectionEvent -> consume(event, relay)
is SealedGossipEvent -> consume(event, relay) is SealedGossipEvent -> consume(event, relay)

Wyświetl plik

@ -184,6 +184,13 @@ open class Note(val idHex: String) {
open fun createdAt() = event?.createdAt() open fun createdAt() = event?.createdAt()
fun isDraft(): Boolean {
event?.let {
return it.sig().isBlank()
}
return false
}
fun loadEvent( fun loadEvent(
event: Event, event: Event,
author: User, author: User,
@ -965,8 +972,6 @@ class NoteLiveSet(u: Note) {
val relays = innerRelays.map { it } val relays = innerRelays.map { it }
val zaps = innerZaps.map { it } val zaps = innerZaps.map { it }
val authorChanges = innerMetadata.map { it.note.author }.distinctUntilChanged()
val hasEvent = innerMetadata.map { it.note.event != null }.distinctUntilChanged() val hasEvent = innerMetadata.map { it.note.event != null }.distinctUntilChanged()
val hasReactions = val hasReactions =
@ -1004,7 +1009,6 @@ class NoteLiveSet(u: Note) {
reports.hasObservers() || reports.hasObservers() ||
relays.hasObservers() || relays.hasObservers() ||
zaps.hasObservers() || zaps.hasObservers() ||
authorChanges.hasObservers() ||
hasEvent.hasObservers() || hasEvent.hasObservers() ||
hasReactions.hasObservers() || hasReactions.hasObservers() ||
replyCount.hasObservers() || replyCount.hasObservers() ||

Wyświetl plik

@ -40,6 +40,7 @@ import com.vitorpamplona.quartz.events.CalendarRSVPEvent
import com.vitorpamplona.quartz.events.CalendarTimeSlotEvent import com.vitorpamplona.quartz.events.CalendarTimeSlotEvent
import com.vitorpamplona.quartz.events.ChannelMessageEvent import com.vitorpamplona.quartz.events.ChannelMessageEvent
import com.vitorpamplona.quartz.events.ContactListEvent import com.vitorpamplona.quartz.events.ContactListEvent
import com.vitorpamplona.quartz.events.DraftEvent
import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent
import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.EventInterface import com.vitorpamplona.quartz.events.EventInterface
@ -229,6 +230,16 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
) )
} }
fun createDraftsFilter() =
TypedFilter(
types = COMMON_FEED_TYPES,
filter =
JsonFilter(
kinds = listOf(DraftEvent.KIND),
authors = listOf(account.userProfile().pubkeyHex),
),
)
fun createGiftWrapsToMeFilter() = fun createGiftWrapsToMeFilter() =
TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
@ -262,22 +273,59 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
checkNotInMainThread() checkNotInMainThread()
if (LocalCache.justVerify(event)) { if (LocalCache.justVerify(event)) {
if (event is GiftWrapEvent) { when (event) {
// Avoid decrypting over and over again if the event already exist. is DraftEvent -> {
val note = LocalCache.getNoteIfExists(event.id) // Avoid decrypting over and over again if the event already exist.
if (note != null && relay.brief in note.relays) return
event.cachedGift(account.signer) { this.consume(it, relay) } val note = LocalCache.getNoteIfExists(event.id)
} if (note != null && relay.brief in note.relays) return
if (event is SealedGossipEvent) { LocalCache.justConsume(event, relay)
// Avoid decrypting over and over again if the event already exist. event.plainContent(account.signer) {
val note = LocalCache.getNoteIfExists(event.id) val tag =
if (note != null && relay.brief in note.relays) return event.tags().filter { it.size > 1 && it[0] == "d" }.map {
it[1]
}.firstOrNull()
event.cachedGossip(account.signer) { LocalCache.justConsume(it, relay) } LocalCache.justConsume(it, relay)
} else { tag?.let { lTag ->
LocalCache.justConsume(event, relay) LocalCache.addDraft(lTag, event.id(), it.id())
}
}
}
is GiftWrapEvent -> {
// Avoid decrypting over and over again if the event already exist.
val note = LocalCache.getNoteIfExists(event.id)
if (note != null && relay.brief in note.relays) return
event.cachedGift(account.signer) { this.consume(it, relay) }
}
is SealedGossipEvent -> {
// Avoid decrypting over and over again if the event already exist.
val note = LocalCache.getNoteIfExists(event.id)
if (note != null && relay.brief in note.relays) return
event.cachedGossip(account.signer) { LocalCache.justConsume(it, relay) }
}
is LnZapEvent -> {
// Avoid decrypting over and over again if the event already exist.
val note = LocalCache.getNoteIfExists(event.id)
if (note != null && relay.brief in note.relays) return
event.zapRequest?.let {
if (it.isPrivateZap()) {
it.decryptPrivateZap(account.signer) {}
}
}
}
else -> {
LocalCache.justConsume(event, relay)
}
} }
} }
} }
@ -328,6 +376,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
createAccountSettingsFilter(), createAccountSettingsFilter(),
createAccountLastPostsListFilter(), createAccountLastPostsListFilter(),
createOtherAccountsBaseFilter(), createOtherAccountsBaseFilter(),
createDraftsFilter(),
) )
.ifEmpty { null } .ifEmpty { null }
} else { } else {

Wyświetl plik

@ -108,7 +108,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
acc: Account, acc: Account,
) { ) {
if ( if (
event.createdAt > TimeUtils.fiveMinutesAgo() && // old event being re-broadcasted event.createdAt > TimeUtils.fifteenMinutesAgo() && // old event being re-broadcasted
event.pubKey != acc.userProfile().pubkeyHex event.pubKey != acc.userProfile().pubkeyHex
) { // from the user ) { // from the user
@ -148,7 +148,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
val note = LocalCache.getNoteIfExists(event.id) ?: return val note = LocalCache.getNoteIfExists(event.id) ?: return
// old event being re-broadcast // old event being re-broadcast
if (event.createdAt < TimeUtils.fiveMinutesAgo()) return if (event.createdAt < TimeUtils.fifteenMinutesAgo()) return
if (acc.userProfile().pubkeyHex == event.verifiedRecipientPubKey()) { if (acc.userProfile().pubkeyHex == event.verifiedRecipientPubKey()) {
val followingKeySet = acc.followingKeySet() val followingKeySet = acc.followingKeySet()
@ -187,7 +187,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
val noteZapEvent = LocalCache.getNoteIfExists(event.id) ?: return val noteZapEvent = LocalCache.getNoteIfExists(event.id) ?: return
// old event being re-broadcast // old event being re-broadcast
if (event.createdAt < TimeUtils.fiveMinutesAgo()) return if (event.createdAt < TimeUtils.fifteenMinutesAgo()) return
val noteZapRequest = event.zapRequest?.id?.let { LocalCache.checkGetOrCreateNote(it) } ?: return val noteZapRequest = event.zapRequest?.id?.let { LocalCache.checkGetOrCreateNote(it) } ?: return
val noteZapped = val noteZapped =
@ -195,7 +195,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
if ((event.amount ?: BigDecimal.ZERO) < BigDecimal.TEN) return if ((event.amount ?: BigDecimal.ZERO) < BigDecimal.TEN) return
if (acc.userProfile().pubkeyHex == event.zappedAuthor().firstOrNull()) { if (event.isTaggedUser(acc.userProfile().pubkeyHex)) {
val amount = showAmount(event.amount) val amount = showAmount(event.amount)
(noteZapRequest.event as? LnZapRequestEvent)?.let { event -> (noteZapRequest.event as? LnZapRequestEvent)?.let { event ->
acc.decryptZapContentAuthor(noteZapRequest) { acc.decryptZapContentAuthor(noteZapRequest) {

Wyświetl plik

@ -0,0 +1,311 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.service.previews
import kotlinx.collections.immutable.toImmutableMap
import java.lang.StringBuilder
internal data class MetaTag(private val attrs: Map<String, String>) {
fun attr(name: String): String = attrs[name.lowercase()] ?: ""
}
// parse a partial HTML document and extract meta tags
internal object MetaTagsParser {
private val NON_ATTR_NAME_CHARS = setOf(Char(0x0), '"', '\'', '>', '/')
private val NON_UNQUOTED_ATTR_VALUE_CHARS = setOf('"', '\'', '=', '>', '<', '`')
fun parse(input: String): Sequence<MetaTag> =
sequence {
val s = TagScanner(input)
while (!s.exhausted()) {
val t = s.nextTag() ?: continue
if (t.name == "/head") {
break
}
if (t.name == "meta") {
val attrs = parseAttrs(t.attrPart) ?: continue
yield(MetaTag(attrs))
}
}
}
private data class RawTag(val name: String, val attrPart: String)
private class TagScanner(private val input: String) {
var p = 0
fun exhausted(): Boolean = p >= input.length
private fun peek(): Char = input[p]
private fun consume(): Char {
return input[p++]
}
private fun consumeChar(c: Char): Boolean {
if (this.peek() == c) {
this.consume()
return true
}
return false
}
private fun skipSpaces() {
while (!this.exhausted() && this.peek().isWhitespace()) {
this.consume()
}
}
private fun skipUntil(c: Char) {
while (!this.exhausted() && this.peek() != c) {
this.consume()
}
}
private fun readWhile(pred: (Char) -> Boolean): String {
val sb = StringBuilder()
while (!this.exhausted() && pred(this.peek())) {
sb.append(this.consume())
}
return sb.toString()
}
fun nextTag(): RawTag? {
skipUntil('<')
consume()
// read tag name
val name = StringBuilder()
if (consumeChar('/')) {
name.append('/')
}
val n = readWhile { !it.isWhitespace() && it != '>' }
skipSpaces()
// read until end of tag
val attrsPart = StringBuilder()
var quote: Char? = null
while (!exhausted()) {
val c = consume()
when {
// `/>` out of quote -> end of tag
quote == null && c == '/' && peek() == '>' -> {
consume()
break
}
// `>` out of quote -> end of tag
quote == null && c == '>' -> {
break
}
// entering quote
quote == null && (c == '\'' || c == '"') -> {
quote = c
}
// leaving quote
quote != null && c == quote -> {
quote = null
}
}
attrsPart.append(c)
}
if (!n.matches(Regex("""[0-9a-zA-Z]+"""))) {
return null
}
return RawTag(name.append(n).toString().lowercase(), attrsPart.toString())
}
}
// map of HTML element attribute name to its value, with additional logics:
// - attribute names are matched in a case-insensitive manner
// - attribute names never duplicate
// - commonly used character references in attribute values are resolved
private class Attrs {
companion object {
val RE_CHAR_REF = Regex("""&(\w+)(;?)""")
val BASE_CHAR_REFS =
mapOf(
"amp" to "&",
"AMP" to "&",
"quot" to "\"",
"QUOT" to "\"",
"lt" to "<",
"LT" to "<",
"gt" to ">",
"GT" to ">",
)
val CHAR_REFS =
mapOf(
"apos" to "'",
"equals" to "=",
"grave" to "`",
"DiacriticalGrave" to "`",
)
fun replaceCharRefs(match: MatchResult): String {
val bcr = BASE_CHAR_REFS[match.groupValues[1]]
if (bcr != null) {
return bcr
}
// non-base char refs must be terminated by ';'
if (match.groupValues[2].isNotEmpty()) {
val cr = CHAR_REFS[match.groupValues[1]]
if (cr != null) {
return cr
}
}
return match.value
}
}
private val attrs = mutableMapOf<String, String>()
fun add(attr: Pair<String, String>) {
val name = attr.first.lowercase()
if (attrs.containsKey(name)) {
throw IllegalArgumentException("duplicated attribute name: $name")
}
val value = attr.second.replace(RE_CHAR_REF, Companion::replaceCharRefs)
attrs += Pair(name, value)
}
fun freeze(): Map<String, String> = attrs.toImmutableMap()
}
private enum class State {
NAME,
BEFORE_EQ,
AFTER_EQ,
VALUE,
SPACE,
}
private fun parseAttrs(input: String): Map<String, String>? {
val attrs = Attrs()
var state = State.NAME
var nameBegin = 0
var nameEnd = 0
var valueBegin = 0
var valueQuote: Char? = null
input.forEachIndexed { i, c ->
when (state) {
State.NAME -> {
when {
c == '=' -> {
nameEnd = i
state = State.AFTER_EQ
}
c.isWhitespace() -> {
nameEnd = i
state = State.BEFORE_EQ
}
NON_ATTR_NAME_CHARS.contains(c) || c.isISOControl() || !c.isDefined() -> {
return null
}
}
}
State.BEFORE_EQ -> {
when {
c == '=' -> {
state = State.AFTER_EQ
}
c.isWhitespace() -> {}
else -> return null
}
}
State.AFTER_EQ -> {
when {
c.isWhitespace() -> {}
c == '\'' || c == '"' -> {
valueBegin = i + 1
valueQuote = c
state = State.VALUE
}
else -> {
valueBegin = i
valueQuote = null
state = State.VALUE
}
}
}
State.VALUE -> {
var attr: Pair<String, String>? = null
when {
valueQuote != null -> {
if (c == valueQuote) {
attr =
Pair(
input.slice(nameBegin..<nameEnd),
input.slice(valueBegin..<i),
)
}
}
valueQuote == null -> {
when {
c.isWhitespace() -> {
attr =
Pair(
input.slice(nameBegin..<nameEnd),
input.slice(valueBegin..<i),
)
}
i == input.length - 1 -> {
attr =
Pair(
input.slice(nameBegin..<nameEnd),
input.slice(valueBegin..i),
)
}
NON_UNQUOTED_ATTR_VALUE_CHARS.contains(c) -> {
return null
}
}
}
}
if (attr != null) {
runCatching { attrs.add(attr) }.getOrNull() ?: return null
state = State.SPACE
}
}
State.SPACE -> {
if (!c.isWhitespace()) {
nameBegin = i
state = State.NAME
}
}
}
}
return attrs.freeze()
}
}

Wyświetl plik

@ -27,60 +27,39 @@ import kotlinx.coroutines.withContext
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request import okhttp3.Request
import org.jsoup.Jsoup import okio.BufferedSource
import org.jsoup.nodes.Document import okio.ByteString.Companion.decodeHex
import okio.Options
import java.nio.charset.Charset
private const val ELEMENT_TAG_META = "meta"
private const val ATTRIBUTE_VALUE_PROPERTY = "property" private const val ATTRIBUTE_VALUE_PROPERTY = "property"
private const val ATTRIBUTE_VALUE_NAME = "name" private const val ATTRIBUTE_VALUE_NAME = "name"
private const val ATTRIBUTE_VALUE_ITEMPROP = "itemprop" private const val ATTRIBUTE_VALUE_ITEMPROP = "itemprop"
private const val ATTRIBUTE_VALUE_CHARSET = "charset"
private const val ATTRIBUTE_VALUE_HTTP_EQUIV = "http-equiv"
// for <meta itemprop=... to get title // for <meta itemprop=... to get title
private val META_X_TITLE = private val META_X_TITLE =
arrayOf( arrayOf(
"og:title", "og:title",
"\"og:title\"",
"'og:title'",
"name",
"\"name\"",
"'name'",
"twitter:title", "twitter:title",
"\"twitter:title\"",
"'twitter:title'",
"title", "title",
"\"title\"",
"'title'",
) )
// for <meta itemprop=... to get description // for <meta itemprop=... to get description
private val META_X_DESCRIPTION = private val META_X_DESCRIPTION =
arrayOf( arrayOf(
"og:description", "og:description",
"\"og:description\"",
"'og:description'",
"description",
"\"description\"",
"'description'",
"twitter:description", "twitter:description",
"\"twitter:description\"",
"'twitter:description'",
"description", "description",
"\"description\"",
"'description'",
) )
// for <meta itemprop=... to get image // for <meta itemprop=... to get image
private val META_X_IMAGE = private val META_X_IMAGE =
arrayOf( arrayOf(
"og:image", "og:image",
"\"og:image\"",
"'og:image'",
"image",
"\"image\"",
"'image'",
"twitter:image", "twitter:image",
"\"twitter:image\"", "image",
"'twitter:image'",
) )
private const val CONTENT = "content" private const val CONTENT = "content"
@ -95,14 +74,12 @@ suspend fun getDocument(
checkNotInMainThread() checkNotInMainThread()
if (it.isSuccessful) { if (it.isSuccessful) {
val mimeType = val mimeType =
it.headers.get("Content-Type")?.toMediaType() it.headers["Content-Type"]?.toMediaType()
?: throw IllegalArgumentException( ?: throw IllegalArgumentException(
"Website returned unknown mimetype: ${it.headers.get("Content-Type")}", "Website returned unknown mimetype: ${it.headers["Content-Type"]}",
) )
if (mimeType.type == "text" && mimeType.subtype == "html") { if (mimeType.type == "text" && mimeType.subtype == "html") {
val document = Jsoup.parse(it.body.string()) parseHtml(url, it.body.source(), mimeType)
parseHtml(url, document, mimeType)
} else if (mimeType.type == "image") { } else if (mimeType.type == "image") {
UrlInfoItem(url, image = url, mimeType = mimeType) UrlInfoItem(url, image = url, mimeType = mimeType)
} else if (mimeType.type == "video") { } else if (mimeType.type == "video") {
@ -120,65 +97,141 @@ suspend fun getDocument(
suspend fun parseHtml( suspend fun parseHtml(
url: String, url: String,
document: Document, source: BufferedSource,
type: MediaType, type: MediaType,
): UrlInfoItem = ): UrlInfoItem =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val metaTags = document.getElementsByTag(ELEMENT_TAG_META) // sniff charset from Content-Type header or BOM
val sniffedCharset = type.charset() ?: source.readBomAsCharset()
if (sniffedCharset != null) {
val metaTags = MetaTagsParser.parse(source.readByteArray().toString(sniffedCharset))
return@withContext extractUrlInfo(url, metaTags, type)
}
var title: String = "" // if sniffing was failed, detect charset from content
var description: String = "" val bodyBytes = source.readByteArray()
var image: String = "" val charset = detectCharset(bodyBytes)
val metaTags = MetaTagsParser.parse(bodyBytes.toString(charset))
return@withContext extractUrlInfo(url, metaTags, type)
}
metaTags.forEach { // taken from okhttp
when (it.attr(ATTRIBUTE_VALUE_PROPERTY)) { private val UNICODE_BOMS =
in META_X_TITLE -> Options.of(
if (title.isEmpty()) { // UTF-8
title = it.attr(CONTENT) "efbbbf".decodeHex(),
} // UTF-16BE
in META_X_DESCRIPTION -> "feff".decodeHex(),
if (description.isEmpty()) { // UTF-16LE
description = it.attr(CONTENT) "fffe".decodeHex(),
} // UTF-32BE
in META_X_IMAGE -> "0000ffff".decodeHex(),
if (image.isEmpty()) { // UTF-32LE
image = it.attr(CONTENT) "ffff0000".decodeHex(),
} )
}
when (it.attr(ATTRIBUTE_VALUE_NAME)) { private fun BufferedSource.readBomAsCharset(): Charset? {
in META_X_TITLE -> return when (select(UNICODE_BOMS)) {
if (title.isEmpty()) { 0 -> Charsets.UTF_8
title = it.attr(CONTENT) 1 -> Charsets.UTF_16BE
} 2 -> Charsets.UTF_16LE
in META_X_DESCRIPTION -> 3 -> Charsets.UTF_32BE
if (description.isEmpty()) { 4 -> Charsets.UTF_32LE
description = it.attr(CONTENT) -1 -> null
} else -> throw AssertionError()
in META_X_IMAGE -> }
if (image.isEmpty()) { }
image = it.attr(CONTENT)
}
}
when (it.attr(ATTRIBUTE_VALUE_ITEMPROP)) { private val RE_CONTENT_TYPE_CHARSET = Regex("""charset=([^;]+)""")
in META_X_TITLE ->
if (title.isEmpty()) {
title = it.attr(CONTENT)
}
in META_X_DESCRIPTION ->
if (description.isEmpty()) {
description = it.attr(CONTENT)
}
in META_X_IMAGE ->
if (image.isEmpty()) {
image = it.attr(CONTENT)
}
}
if (title.isNotEmpty() && description.isNotEmpty() && image.isNotEmpty()) { private fun detectCharset(bodyBytes: ByteArray): Charset {
return@withContext UrlInfoItem(url, title, description, image, type) // try to detect charset from meta tags parsed from first 1024 bytes of body
val firstPart = String(bodyBytes, 0, 1024, Charset.forName("utf-8"))
val metaTags = MetaTagsParser.parse(firstPart)
metaTags.forEach { meta ->
val charsetAttr = meta.attr(ATTRIBUTE_VALUE_CHARSET)
if (charsetAttr.isNotEmpty()) {
runCatching { Charset.forName(charsetAttr) }.getOrNull()?.let {
return it
} }
} }
return@withContext UrlInfoItem(url, title, description, image, type) if (meta.attr(ATTRIBUTE_VALUE_HTTP_EQUIV).lowercase() == "content-type") {
RE_CONTENT_TYPE_CHARSET.find(meta.attr(CONTENT))
?.let {
runCatching { Charset.forName(it.groupValues[1]) }.getOrNull()
}?.let {
return it
}
}
} }
// defaults to UTF-8
return Charset.forName("utf-8")
}
private fun extractUrlInfo(
url: String,
metaTags: Sequence<MetaTag>,
type: MediaType,
): UrlInfoItem {
var title: String = ""
var description: String = ""
var image: String = ""
metaTags.forEach {
when (it.attr(ATTRIBUTE_VALUE_PROPERTY)) {
in META_X_TITLE ->
if (title.isEmpty()) {
title = it.attr(CONTENT)
}
in META_X_DESCRIPTION ->
if (description.isEmpty()) {
description = it.attr(CONTENT)
}
in META_X_IMAGE ->
if (image.isEmpty()) {
image = it.attr(CONTENT)
}
}
when (it.attr(ATTRIBUTE_VALUE_NAME)) {
in META_X_TITLE ->
if (title.isEmpty()) {
title = it.attr(CONTENT)
}
in META_X_DESCRIPTION ->
if (description.isEmpty()) {
description = it.attr(CONTENT)
}
in META_X_IMAGE ->
if (image.isEmpty()) {
image = it.attr(CONTENT)
}
}
when (it.attr(ATTRIBUTE_VALUE_ITEMPROP)) {
in META_X_TITLE ->
if (title.isEmpty()) {
title = it.attr(CONTENT)
}
in META_X_DESCRIPTION ->
if (description.isEmpty()) {
description = it.attr(CONTENT)
}
in META_X_IMAGE ->
if (image.isEmpty()) {
image = it.attr(CONTENT)
}
}
if (title.isNotEmpty() && description.isNotEmpty() && image.isNotEmpty()) {
return UrlInfoItem(url, title, description, image, type)
}
}
return UrlInfoItem(url, title, description, image, type)
}

Wyświetl plik

@ -34,8 +34,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable @Composable
fun NewPollOption( fun NewPollOption(
@ -45,7 +48,12 @@ fun NewPollOption(
Row { Row {
val deleteIcon: @Composable (() -> Unit) = { val deleteIcon: @Composable (() -> Unit) = {
IconButton( IconButton(
onClick = { pollViewModel.pollOptions.remove(optionIndex) }, onClick = {
pollViewModel.pollOptions.remove(optionIndex)
pollViewModel.viewModelScope.launch(Dispatchers.IO) {
pollViewModel.saveDraft()
}
},
) { ) {
Icon( Icon(
imageVector = Icons.Default.Delete, imageVector = Icons.Default.Delete,
@ -57,7 +65,12 @@ fun NewPollOption(
OutlinedTextField( OutlinedTextField(
modifier = Modifier.weight(1F), modifier = Modifier.weight(1F),
value = pollViewModel.pollOptions[optionIndex] ?: "", value = pollViewModel.pollOptions[optionIndex] ?: "",
onValueChange = { pollViewModel.pollOptions[optionIndex] = it }, onValueChange = {
pollViewModel.pollOptions[optionIndex] = it
pollViewModel.viewModelScope.launch(Dispatchers.IO) {
pollViewModel.saveDraft()
}
},
label = { label = {
Text( Text(
text = stringResource(R.string.poll_option_index).format(optionIndex + 1), text = stringResource(R.string.poll_option_index).format(optionIndex + 1),

Wyświetl plik

@ -119,6 +119,7 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
@ -171,13 +172,18 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.lang.Math.round import java.lang.Math.round
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class, FlowPreview::class)
@Composable @Composable
fun NewPostView( fun NewPostView(
onClose: () -> Unit, onClose: () -> Unit,
@ -185,6 +191,7 @@ fun NewPostView(
quote: Note? = null, quote: Note? = null,
fork: Note? = null, fork: Note? = null,
version: Note? = null, version: Note? = null,
draft: Note? = null,
enableMessageInterface: Boolean = false, enableMessageInterface: Boolean = false,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
@ -200,9 +207,17 @@ fun NewPostView(
var relayList = remember { accountViewModel.account.activeWriteRelays().toImmutableList() } var relayList = remember { accountViewModel.account.activeWriteRelays().toImmutableList() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
postViewModel.load(accountViewModel, baseReplyTo, quote, fork, version)
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
postViewModel.draftTextChanges
.receiveAsFlow()
.debounce(1000)
.collectLatest {
postViewModel.sendPost(relayList = relayList, localDraft = postViewModel.draftTag)
}
}
launch(Dispatchers.IO) {
postViewModel.load(accountViewModel, baseReplyTo, quote, fork, version, draft)
postViewModel.imageUploadingError.collect { error -> postViewModel.imageUploadingError.collect { error ->
withContext(Dispatchers.Main) { Toast.makeText(context, error, Toast.LENGTH_SHORT).show() } withContext(Dispatchers.Main) { Toast.makeText(context, error, Toast.LENGTH_SHORT).show() }
} }
@ -582,6 +597,9 @@ private fun BottomRowActions(postViewModel: NewPostViewModel) {
MarkAsSensitive(postViewModel) { MarkAsSensitive(postViewModel) {
postViewModel.wantsToMarkAsSensitive = !postViewModel.wantsToMarkAsSensitive postViewModel.wantsToMarkAsSensitive = !postViewModel.wantsToMarkAsSensitive
postViewModel.viewModelScope.launch(Dispatchers.IO) {
postViewModel.saveDraft()
}
} }
AddGeoHash(postViewModel) { AddGeoHash(postViewModel) {
@ -827,7 +845,12 @@ fun SellProduct(postViewModel: NewPostViewModel) {
MyTextField( MyTextField(
value = postViewModel.title, value = postViewModel.title,
onValueChange = { postViewModel.title = it }, onValueChange = {
postViewModel.title = it
postViewModel.viewModelScope.launch(Dispatchers.IO) {
postViewModel.saveDraft()
}
},
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
placeholder = { placeholder = {
Text( Text(
@ -870,6 +893,9 @@ fun SellProduct(postViewModel: NewPostViewModel) {
postViewModel.price = it postViewModel.price = it
} }
} }
postViewModel.viewModelScope.launch(Dispatchers.IO) {
postViewModel.saveDraft()
}
}, },
placeholder = { placeholder = {
Text( Text(
@ -934,7 +960,12 @@ fun SellProduct(postViewModel: NewPostViewModel) {
TextSpinner( TextSpinner(
placeholder = conditionTypes.filter { it.first == postViewModel.condition }.first().second, placeholder = conditionTypes.filter { it.first == postViewModel.condition }.first().second,
options = conditionOptions, options = conditionOptions,
onSelect = { postViewModel.condition = conditionTypes[it].first }, onSelect = {
postViewModel.condition = conditionTypes[it].first
postViewModel.viewModelScope.launch(Dispatchers.IO) {
postViewModel.saveDraft()
}
},
modifier = modifier =
Modifier Modifier
.weight(1f) .weight(1f)
@ -998,7 +1029,12 @@ fun SellProduct(postViewModel: NewPostViewModel) {
categoryTypes.filter { it.second == postViewModel.category.text }.firstOrNull()?.second categoryTypes.filter { it.second == postViewModel.category.text }.firstOrNull()?.second
?: "", ?: "",
options = categoryOptions, options = categoryOptions,
onSelect = { postViewModel.category = TextFieldValue(categoryTypes[it].second) }, onSelect = {
postViewModel.category = TextFieldValue(categoryTypes[it].second)
postViewModel.viewModelScope.launch(Dispatchers.IO) {
postViewModel.saveDraft()
}
},
modifier = modifier =
Modifier Modifier
.weight(1f) .weight(1f)
@ -1033,7 +1069,12 @@ fun SellProduct(postViewModel: NewPostViewModel) {
MyTextField( MyTextField(
value = postViewModel.locationText, value = postViewModel.locationText,
onValueChange = { postViewModel.locationText = it }, onValueChange = {
postViewModel.locationText = it
postViewModel.viewModelScope.launch(Dispatchers.IO) {
postViewModel.saveDraft()
}
},
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
placeholder = { placeholder = {
Text( Text(
@ -1100,7 +1141,7 @@ fun FowardZapTo(
Spacer(modifier = DoubleHorzSpacer) Spacer(modifier = DoubleHorzSpacer)
Column(modifier = Modifier.weight(1f)) { Column(modifier = Modifier.weight(1f)) {
UsernameDisplay(splitItem.key, showPlayButton = false) UsernameDisplay(splitItem.key)
Text( Text(
text = String.format("%.0f%%", splitItem.percentage * 100), text = String.format("%.0f%%", splitItem.percentage * 100),
maxLines = 1, maxLines = 1,

Wyświetl plik

@ -69,10 +69,12 @@ import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.UUID
enum class UserSuggestionAnchor { enum class UserSuggestionAnchor {
MAIN_MESSAGE, MAIN_MESSAGE,
@ -82,6 +84,7 @@ enum class UserSuggestionAnchor {
@Stable @Stable
open class NewPostViewModel() : ViewModel() { open class NewPostViewModel() : ViewModel() {
var draftTag: String = UUID.randomUUID().toString()
var accountViewModel: AccountViewModel? = null var accountViewModel: AccountViewModel? = null
var account: Account? = null var account: Account? = null
var requiresNIP24: Boolean = false var requiresNIP24: Boolean = false
@ -164,6 +167,8 @@ open class NewPostViewModel() : ViewModel() {
// NIP24 Wrapped DMs / Group messages // NIP24 Wrapped DMs / Group messages
var nip24 by mutableStateOf(false) var nip24 by mutableStateOf(false)
val draftTextChanges = Channel<String>(Channel.CONFLATED)
fun lnAddress(): String? { fun lnAddress(): String? {
return account?.userProfile()?.info?.lnAddress() return account?.userProfile()?.info?.lnAddress()
} }
@ -182,127 +187,236 @@ open class NewPostViewModel() : ViewModel() {
quote: Note?, quote: Note?,
fork: Note?, fork: Note?,
version: Note?, version: Note?,
draft: Note?,
) { ) {
this.accountViewModel = accountViewModel this.accountViewModel = accountViewModel
this.account = accountViewModel.account this.account = accountViewModel.account
originalNote = replyingTo if (draft != null) {
replyingTo?.let { replyNote -> loadFromDraft(draft, accountViewModel)
if (replyNote.event is BaseTextNoteEvent) { } else {
this.eTags = (replyNote.replyTo ?: emptyList()).plus(replyNote) originalNote = replyingTo
} else { replyingTo?.let { replyNote ->
this.eTags = listOf(replyNote) if (replyNote.event is BaseTextNoteEvent) {
} this.eTags = (replyNote.replyTo ?: emptyList()).plus(replyNote)
} else {
this.eTags = listOf(replyNote)
}
if (replyNote.event !is CommunityDefinitionEvent) { if (replyNote.event !is CommunityDefinitionEvent) {
replyNote.author?.let { replyUser -> replyNote.author?.let { replyUser ->
val currentMentions = val currentMentions =
(replyNote.event as? TextNoteEvent)?.mentions()?.map { LocalCache.getOrCreateUser(it) } (replyNote.event as? TextNoteEvent)?.mentions()?.map { LocalCache.getOrCreateUser(it) }
?: emptyList() ?: emptyList()
if (currentMentions.contains(replyUser)) { if (currentMentions.contains(replyUser)) {
this.pTags = currentMentions this.pTags = currentMentions
} else { } else {
this.pTags = currentMentions.plus(replyUser) this.pTags = currentMentions.plus(replyUser)
}
} }
} }
} }
} ?: run {
?: run { eTags = null
eTags = null pTags = null
pTags = null }
canAddInvoice = accountViewModel.userProfile().info?.lnAddress() != null
canAddZapRaiser = accountViewModel.userProfile().info?.lnAddress() != null
canUsePoll = originalNote?.event !is PrivateDmEvent && originalNote?.channelHex() == null
contentToAddUrl = null
wantsForwardZapTo = false
wantsToMarkAsSensitive = false
wantsToAddGeoHash = false
wantsZapraiser = false
zapRaiserAmount = null
forwardZapTo = Split()
forwardZapToEditting = TextFieldValue("")
quote?.let {
message = TextFieldValue(message.text + "\nnostr:${it.toNEvent()}")
urlPreview = findUrlInMessage()
it.author?.let { quotedUser ->
if (quotedUser.pubkeyHex != accountViewModel.userProfile().pubkeyHex) {
if (forwardZapTo.items.none { it.key.pubkeyHex == quotedUser.pubkeyHex }) {
forwardZapTo.addItem(quotedUser)
}
if (forwardZapTo.items.none { it.key.pubkeyHex == accountViewModel.userProfile().pubkeyHex }) {
forwardZapTo.addItem(accountViewModel.userProfile())
}
val pos = forwardZapTo.items.indexOfFirst { it.key.pubkeyHex == quotedUser.pubkeyHex }
forwardZapTo.updatePercentage(pos, 0.9f)
}
}
} }
fork?.let {
message = TextFieldValue(version?.event?.content() ?: it.event?.content() ?: "")
urlPreview = findUrlInMessage()
it.event?.isSensitive()?.let {
if (it) wantsToMarkAsSensitive = true
}
it.event?.zapraiserAmount()?.let {
zapRaiserAmount = it
}
it.event?.zapSplitSetup()?.let {
val totalWeight = it.sumOf { if (it.isLnAddress) 0.0 else it.weight }
it.forEach {
if (!it.isLnAddress) {
forwardZapTo.addItem(LocalCache.getOrCreateUser(it.lnAddressOrPubKeyHex), (it.weight / totalWeight).toFloat())
}
}
}
// Only adds if it is not already set up.
if (forwardZapTo.items.isEmpty()) {
it.author?.let { forkedAuthor ->
if (forkedAuthor.pubkeyHex != accountViewModel.userProfile().pubkeyHex) {
if (forwardZapTo.items.none { it.key.pubkeyHex == forkedAuthor.pubkeyHex }) forwardZapTo.addItem(forkedAuthor)
if (forwardZapTo.items.none { it.key.pubkeyHex == accountViewModel.userProfile().pubkeyHex }) forwardZapTo.addItem(accountViewModel.userProfile())
val pos = forwardZapTo.items.indexOfFirst { it.key.pubkeyHex == forkedAuthor.pubkeyHex }
forwardZapTo.updatePercentage(pos, 0.8f)
}
}
}
it.author?.let {
if (this.pTags == null) {
this.pTags = listOf(it)
} else if (this.pTags?.contains(it) != true) {
this.pTags = listOf(it) + (this.pTags ?: emptyList())
}
}
forkedFromNote = it
} ?: run {
forkedFromNote = null
}
if (!forwardZapTo.items.isEmpty()) {
wantsForwardZapTo = true
}
}
}
private fun loadFromDraft(
draft: Note,
accountViewModel: AccountViewModel,
) {
Log.d("draft", draft.event!!.toJson())
draftTag = LocalCache.drafts.filter {
it.value.any { it.eventId == draft.event?.id() }
}.keys.firstOrNull() ?: draftTag
canAddInvoice = accountViewModel.userProfile().info?.lnAddress() != null canAddInvoice = accountViewModel.userProfile().info?.lnAddress() != null
canAddZapRaiser = accountViewModel.userProfile().info?.lnAddress() != null canAddZapRaiser = accountViewModel.userProfile().info?.lnAddress() != null
canUsePoll = originalNote?.event !is PrivateDmEvent && originalNote?.channelHex() == null
contentToAddUrl = null contentToAddUrl = null
wantsForwardZapTo = false val localfowardZapTo = draft.event?.tags()?.filter { it.size > 1 && it[0] == "zap" } ?: listOf()
wantsToMarkAsSensitive = false
wantsToAddGeoHash = false
wantsZapraiser = false
zapRaiserAmount = null
forwardZapTo = Split() forwardZapTo = Split()
localfowardZapTo.forEach {
val user = LocalCache.getOrCreateUser(it[1])
val value = it.last().toFloatOrNull() ?: 0f
forwardZapTo.addItem(user, value)
}
forwardZapToEditting = TextFieldValue("") forwardZapToEditting = TextFieldValue("")
wantsForwardZapTo = localfowardZapTo.isNotEmpty()
quote?.let { wantsToMarkAsSensitive = draft.event?.tags()?.any { it.size > 1 && it[0] == "content-warning" } ?: false
message = TextFieldValue(message.text + "\nnostr:${it.toNEvent()}") wantsToAddGeoHash = draft.event?.tags()?.any { it.size > 1 && it[0] == "g" } ?: false
urlPreview = findUrlInMessage() val zapraiser = draft.event?.tags()?.filter { it.size > 1 && it[0] == "zapraiser" } ?: listOf()
wantsZapraiser = zapraiser.isNotEmpty()
it.author?.let { quotedUser -> zapRaiserAmount = null
if (quotedUser.pubkeyHex != accountViewModel.userProfile().pubkeyHex) { if (wantsZapraiser) {
if (forwardZapTo.items.none { it.key.pubkeyHex == quotedUser.pubkeyHex }) { zapRaiserAmount = zapraiser.first()[1].toLongOrNull() ?: 0
forwardZapTo.addItem(quotedUser)
}
if (forwardZapTo.items.none { it.key.pubkeyHex == accountViewModel.userProfile().pubkeyHex }) {
forwardZapTo.addItem(accountViewModel.userProfile())
}
val pos = forwardZapTo.items.indexOfFirst { it.key.pubkeyHex == quotedUser.pubkeyHex }
forwardZapTo.updatePercentage(pos, 0.9f)
}
}
} }
fork?.let { eTags =
message = TextFieldValue(version?.event?.content() ?: it.event?.content() ?: "") draft.event?.tags()?.filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) != "fork" }?.mapNotNull {
urlPreview = findUrlInMessage() val note = LocalCache.checkGetOrCreateNote(it[1])
note
it.event?.isSensitive()?.let {
if (it) wantsToMarkAsSensitive = true
} }
it.event?.zapraiserAmount()?.let { pTags =
zapRaiserAmount = it draft.event?.tags()?.filter { it.size > 1 && it[0] == "p" }?.map {
LocalCache.getOrCreateUser(it[1])
} }
it.event?.zapSplitSetup()?.let { draft.event?.tags()?.filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "fork" }?.forEach {
val totalWeight = it.sumOf { if (it.isLnAddress) 0.0 else it.weight } val note = LocalCache.checkGetOrCreateNote(it[1])
forkedFromNote = note
it.forEach {
if (!it.isLnAddress) {
forwardZapTo.addItem(LocalCache.getOrCreateUser(it.lnAddressOrPubKeyHex), (it.weight / totalWeight).toFloat())
}
}
}
// Only adds if it is not already set up.
if (forwardZapTo.items.isEmpty()) {
it.author?.let { forkedAuthor ->
if (forkedAuthor.pubkeyHex != accountViewModel.userProfile().pubkeyHex) {
if (forwardZapTo.items.none { it.key.pubkeyHex == forkedAuthor.pubkeyHex }) forwardZapTo.addItem(forkedAuthor)
if (forwardZapTo.items.none { it.key.pubkeyHex == accountViewModel.userProfile().pubkeyHex }) forwardZapTo.addItem(accountViewModel.userProfile())
val pos = forwardZapTo.items.indexOfFirst { it.key.pubkeyHex == forkedAuthor.pubkeyHex }
forwardZapTo.updatePercentage(pos, 0.8f)
}
}
}
it.author?.let {
if (this.pTags == null) {
this.pTags = listOf(it)
} else if (this.pTags?.contains(it) != true) {
this.pTags = listOf(it) + (this.pTags ?: emptyList())
}
}
forkedFromNote = it
} ?: run {
forkedFromNote = null
} }
if (!forwardZapTo.items.isEmpty()) { originalNote =
draft.event?.tags()?.filter { it.size > 1 && (it[0] == "e" || it[0] == "a") && it.getOrNull(3) == "root" }?.map {
LocalCache.checkGetOrCreateNote(it[1])
}?.firstOrNull()
canUsePoll = originalNote?.event !is PrivateDmEvent && originalNote?.channelHex() == null
if (forwardZapTo.items.isNotEmpty()) {
wantsForwardZapTo = true wantsForwardZapTo = true
} }
val polls = draft.event?.tags()?.filter { it.size > 1 && it[0] == "poll_option" } ?: emptyList()
wantsPoll = polls.isNotEmpty()
polls.forEach {
pollOptions[it[1].toInt()] = it[2]
}
val minMax = draft.event?.tags()?.filter { it.size > 1 && (it[0] == "value_minimum" || it[0] == "value_maximum") } ?: listOf()
minMax.forEach {
if (it[0] == "value_maximum") {
valueMaximum = it[1].toInt()
} else if (it[0] == "value_minimum") {
valueMinimum = it[1].toInt()
}
}
wantsProduct = draft.event?.kind() == 30402
title = TextFieldValue(draft.event?.tags()?.filter { it.size > 1 && it[0] == "title" }?.map { it[1] }?.firstOrNull() ?: "")
price = TextFieldValue(draft.event?.tags()?.filter { it.size > 1 && it[0] == "price" }?.map { it[1] }?.firstOrNull() ?: "")
category = TextFieldValue(draft.event?.tags()?.filter { it.size > 1 && it[0] == "t" }?.map { it[1] }?.firstOrNull() ?: "")
locationText = TextFieldValue(draft.event?.tags()?.filter { it.size > 1 && it[0] == "location" }?.map { it[1] }?.firstOrNull() ?: "")
condition = ClassifiedsEvent.CONDITION.entries.firstOrNull {
it.value == draft.event?.tags()?.filter { it.size > 1 && it[0] == "condition" }?.map { it[1] }?.firstOrNull()
} ?: ClassifiedsEvent.CONDITION.USED_LIKE_NEW
message =
if (draft.event is PrivateDmEvent) {
val event = draft.event as PrivateDmEvent
TextFieldValue(event.cachedContentFor(accountViewModel.account.signer) ?: "")
} else {
TextFieldValue(draft.event?.content() ?: "")
}
nip24 = draft.event is ChatMessageEvent
urlPreview = findUrlInMessage()
} }
fun sendPost(relayList: List<Relay>? = null) { fun sendPost(
viewModelScope.launch(Dispatchers.IO) { innerSendPost(relayList) } relayList: List<Relay>? = null,
localDraft: String? = null,
) {
viewModelScope.launch(Dispatchers.IO) { innerSendPost(relayList, localDraft) }
} }
suspend fun innerSendPost(relayList: List<Relay>? = null) { private suspend fun innerSendPost(
relayList: List<Relay>? = null,
localDraft: String?,
) {
if (accountViewModel == null) { if (accountViewModel == null) {
cancel() cancel()
return return
@ -363,6 +477,7 @@ open class NewPostViewModel() : ViewModel() {
zapRaiserAmount = localZapRaiserAmount, zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} else { } else {
account?.sendChannelMessage( account?.sendChannelMessage(
@ -375,6 +490,7 @@ open class NewPostViewModel() : ViewModel() {
zapRaiserAmount = localZapRaiserAmount, zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} }
} else if (originalNote?.event is PrivateDmEvent) { } else if (originalNote?.event is PrivateDmEvent) {
@ -388,6 +504,7 @@ open class NewPostViewModel() : ViewModel() {
zapRaiserAmount = localZapRaiserAmount, zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} else if (originalNote?.event is ChatMessageEvent) { } else if (originalNote?.event is ChatMessageEvent) {
val receivers = val receivers =
@ -423,6 +540,7 @@ open class NewPostViewModel() : ViewModel() {
zapRaiserAmount = localZapRaiserAmount, zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} else { } else {
account?.sendPrivateMessage( account?.sendPrivateMessage(
@ -435,6 +553,7 @@ open class NewPostViewModel() : ViewModel() {
zapRaiserAmount = localZapRaiserAmount, zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} }
} else if (originalNote?.event is GitIssueEvent) { } else if (originalNote?.event is GitIssueEvent) {
@ -475,6 +594,7 @@ open class NewPostViewModel() : ViewModel() {
relayList = relayList, relayList = relayList,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} else { } else {
if (wantsPoll) { if (wantsPoll) {
@ -493,6 +613,7 @@ open class NewPostViewModel() : ViewModel() {
relayList, relayList,
geoHash, geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} else if (wantsProduct) { } else if (wantsProduct) {
account?.sendClassifieds( account?.sendClassifieds(
@ -511,6 +632,7 @@ open class NewPostViewModel() : ViewModel() {
relayList = relayList, relayList = relayList,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} else { } else {
// adds markers // adds markers
@ -547,11 +669,13 @@ open class NewPostViewModel() : ViewModel() {
relayList = relayList, relayList = relayList,
geohash = geoHash, geohash = geoHash,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = localDraft,
) )
} }
} }
if (localDraft == null) {
cancel() cancel()
}
} }
fun upload( fun upload(
@ -635,6 +759,7 @@ open class NewPostViewModel() : ViewModel() {
urlPreview = null urlPreview = null
isUploadingImage = false isUploadingImage = false
pTags = null pTags = null
eTags = null
wantsDirectMessage = false wantsDirectMessage = false
@ -663,6 +788,11 @@ open class NewPostViewModel() : ViewModel() {
userSuggestions = emptyList() userSuggestions = emptyList()
userSuggestionAnchor = null userSuggestionAnchor = null
userSuggestionsMainMessage = null userSuggestionsMainMessage = null
originalNote = null
viewModelScope.launch(Dispatchers.IO) {
accountViewModel?.deleteDraft(draftTag)
}
NostrSearchEventOrUserDataSource.clear() NostrSearchEventOrUserDataSource.clear()
} }
@ -679,6 +809,10 @@ open class NewPostViewModel() : ViewModel() {
pTags = pTags?.filter { it != userToRemove } pTags = pTags?.filter { it != userToRemove }
} }
open suspend fun saveDraft() {
draftTextChanges.send("")
}
open fun updateMessage(it: TextFieldValue) { open fun updateMessage(it: TextFieldValue) {
message = it message = it
urlPreview = findUrlInMessage() urlPreview = findUrlInMessage()
@ -701,6 +835,10 @@ open class NewPostViewModel() : ViewModel() {
userSuggestions = emptyList() userSuggestions = emptyList()
} }
} }
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
open fun updateToUsers(it: TextFieldValue) { open fun updateToUsers(it: TextFieldValue) {
@ -724,10 +862,16 @@ open class NewPostViewModel() : ViewModel() {
userSuggestions = emptyList() userSuggestions = emptyList()
} }
} }
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
open fun updateSubject(it: TextFieldValue) { open fun updateSubject(it: TextFieldValue) {
subject = it subject = it
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
open fun updateZapForwardTo(it: TextFieldValue) { open fun updateZapForwardTo(it: TextFieldValue) {
@ -754,6 +898,9 @@ open class NewPostViewModel() : ViewModel() {
userSuggestions = emptyList() userSuggestions = emptyList()
} }
} }
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
open fun autocompleteWithUser(item: User) { open fun autocompleteWithUser(item: User) {
@ -799,6 +946,10 @@ open class NewPostViewModel() : ViewModel() {
userSuggestionsMainMessage = null userSuggestionsMainMessage = null
userSuggestions = emptyList() userSuggestions = emptyList()
} }
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
private fun newStateMapPollOptions(): SnapshotStateMap<Int, String> { private fun newStateMapPollOptions(): SnapshotStateMap<Int, String> {
@ -869,6 +1020,9 @@ open class NewPostViewModel() : ViewModel() {
message = message.insertUrlAtCursor(imageUrl) message = message.insertUrlAtCursor(imageUrl)
urlPreview = findUrlInMessage() urlPreview = findUrlInMessage()
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
}, },
onError = { onError = {
@ -913,6 +1067,9 @@ open class NewPostViewModel() : ViewModel() {
} }
urlPreview = findUrlInMessage() urlPreview = findUrlInMessage()
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
}, },
onError = { onError = {
@ -933,6 +1090,7 @@ open class NewPostViewModel() : ViewModel() {
locUtil?.let { locUtil?.let {
location = location =
it.locationStateFlow.mapLatest { it.toGeoHash(GeohashPrecision.KM_5_X_5.digits).toString() } it.locationStateFlow.mapLatest { it.toGeoHash(GeohashPrecision.KM_5_X_5.digits).toString() }
viewModelScope.launch(Dispatchers.IO) { saveDraft() }
} }
viewModelScope.launch(Dispatchers.IO) { locUtil?.start() } viewModelScope.launch(Dispatchers.IO) { locUtil?.start() }
} }
@ -957,6 +1115,11 @@ open class NewPostViewModel() : ViewModel() {
} else { } else {
nip24 = !nip24 nip24 = !nip24
} }
if (message.text.isNotBlank()) {
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
}
} }
fun updateMinZapAmountForPoll(textMin: String) { fun updateMinZapAmountForPoll(textMin: String) {
@ -976,6 +1139,9 @@ open class NewPostViewModel() : ViewModel() {
} }
checkMinMax() checkMinMax()
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
fun updateMaxZapAmountForPoll(textMax: String) { fun updateMaxZapAmountForPoll(textMax: String) {
@ -995,6 +1161,9 @@ open class NewPostViewModel() : ViewModel() {
} }
checkMinMax() checkMinMax()
viewModelScope.launch(Dispatchers.IO) {
saveDraft()
}
} }
fun checkMinMax() { fun checkMinMax() {

Wyświetl plik

@ -53,7 +53,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -65,6 +64,8 @@ import androidx.core.content.ContextCompat.startActivity
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.fasterxml.jackson.databind.node.TextNode import com.fasterxml.jackson.databind.node.TextNode
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.Cashu
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.model.ThemeType import com.vitorpamplona.amethyst.model.ThemeType
import com.vitorpamplona.amethyst.service.CachedCashuProcessor import com.vitorpamplona.amethyst.service.CachedCashuProcessor
import com.vitorpamplona.amethyst.service.CashuToken import com.vitorpamplona.amethyst.service.CashuToken
@ -182,7 +183,7 @@ fun CashuPreview(
.padding(bottom = 10.dp), .padding(bottom = 10.dp),
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.cashu), imageVector = CustomHashTagIcons.Cashu,
null, null,
modifier = Size20Modifier, modifier = Size20Modifier,
tint = Color.Unspecified, tint = Color.Unspecified,
@ -320,7 +321,7 @@ fun CashuPreviewNew(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.cashu), imageVector = CustomHashTagIcons.Cashu,
null, null,
modifier = Modifier.size(13.dp), modifier = Modifier.size(13.dp),
tint = Color.Unspecified, tint = Color.Unspecified,

Wyświetl plik

@ -44,13 +44,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDirection import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.service.lnurl.CachedLnInvoiceParser import com.vitorpamplona.amethyst.service.lnurl.CachedLnInvoiceParser
import com.vitorpamplona.amethyst.service.lnurl.InvoiceAmount import com.vitorpamplona.amethyst.service.lnurl.InvoiceAmount
import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog
@ -135,7 +136,7 @@ fun InvoicePreview(
.padding(bottom = 10.dp), .padding(bottom = 10.dp),
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.lightning), imageVector = CustomHashTagIcons.Lightning,
null, null,
modifier = Size20Modifier, modifier = Size20Modifier,
tint = Color.Unspecified, tint = Color.Unspecified,

Wyświetl plik

@ -44,7 +44,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
@ -52,6 +51,8 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
@ -118,7 +119,7 @@ fun InvoiceRequest(
modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp), modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp),
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.lightning), imageVector = CustomHashTagIcons.Lightning,
null, null,
modifier = Size20Modifier, modifier = Size20Modifier,
tint = Color.Unspecified, tint = Color.Unspecified,

Wyświetl plik

@ -52,7 +52,6 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFontFamilyResolver import androidx.compose.ui.platform.LocalFontFamilyResolver
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.Placeholder import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
@ -761,7 +760,7 @@ private fun InlineIcon(hashtagIcon: HashtagIcon) =
), ),
) { ) {
Icon( Icon(
painter = painterResource(hashtagIcon.icon), imageVector = hashtagIcon.icon,
contentDescription = hashtagIcon.description, contentDescription = hashtagIcon.description,
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = hashtagIcon.modifier, modifier = hashtagIcon.modifier,

Wyświetl plik

@ -25,6 +25,7 @@ import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -41,6 +42,7 @@ import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.previews.UrlInfoItem import com.vitorpamplona.amethyst.service.previews.UrlInfoItem
@ -106,8 +108,8 @@ fun UrlPreviewCard(
AsyncImage( AsyncImage(
model = previewInfo.imageUrlFullPath, model = previewInfo.imageUrlFullPath,
contentDescription = stringResource(R.string.preview_card_image_for, previewInfo.url), contentDescription = stringResource(R.string.preview_card_image_for, previewInfo.url),
contentScale = ContentScale.FillWidth, contentScale = ContentScale.Fit,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth().heightIn(max = 200.dp),
) )
Spacer(modifier = StdVertSpacer) Spacer(modifier = StdVertSpacer)

Wyświetl plik

@ -57,7 +57,6 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
@ -91,6 +90,8 @@ import androidx.media3.session.MediaController
import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
import com.linc.audiowaveform.infiniteLinearGradient import com.linc.audiowaveform.infiniteLinearGradient
import com.vitorpamplona.amethyst.commons.compose.GenericBaseCache
import com.vitorpamplona.amethyst.commons.compose.produceCachedState
import com.vitorpamplona.amethyst.service.playback.PlaybackClientController import com.vitorpamplona.amethyst.service.playback.PlaybackClientController
import com.vitorpamplona.amethyst.ui.note.DownloadForOfflineIcon import com.vitorpamplona.amethyst.ui.note.DownloadForOfflineIcon
import com.vitorpamplona.amethyst.ui.note.LyricsIcon import com.vitorpamplona.amethyst.ui.note.LyricsIcon
@ -328,6 +329,43 @@ fun VideoViewInner(
} }
} }
val mediaItemCache = MediaItemCache()
@Immutable
data class MediaItemData(
val videoUri: String,
val authorName: String? = null,
val title: String? = null,
val artworkUri: String? = null,
)
class MediaItemCache() : GenericBaseCache<MediaItemData, MediaItem>(20) {
override suspend fun compute(data: MediaItemData): MediaItem? {
return MediaItem.Builder()
.setMediaId(data.videoUri)
.setUri(data.videoUri)
.setMediaMetadata(
MediaMetadata.Builder()
.setArtist(data.authorName?.ifBlank { null })
.setTitle(data.title?.ifBlank { null } ?: data.videoUri)
.setArtworkUri(
try {
if (data.artworkUri != null) {
Uri.parse(data.artworkUri)
} else {
null
}
} catch (e: Exception) {
if (e is CancellationException) throw e
null
},
)
.build(),
)
.build()
}
}
@Composable @Composable
fun GetMediaItem( fun GetMediaItem(
videoUri: String, videoUri: String,
@ -336,51 +374,15 @@ fun GetMediaItem(
authorName: String?, authorName: String?,
inner: @Composable (State<MediaItem>) -> Unit, inner: @Composable (State<MediaItem>) -> Unit,
) { ) {
val mediaItem = val data = remember(videoUri) { MediaItemData(videoUri, title, artworkUri, authorName) }
produceState<MediaItem?>( val mediaItem by produceCachedState(cache = mediaItemCache, key = data)
initialValue = null,
key1 = videoUri,
) {
this.value =
MediaItem.Builder()
.setMediaId(videoUri)
.setUri(videoUri)
.setMediaMetadata(
MediaMetadata.Builder()
.setArtist(authorName?.ifBlank { null })
.setTitle(title?.ifBlank { null } ?: videoUri)
.setArtworkUri(
try {
if (artworkUri != null) {
Uri.parse(artworkUri)
} else {
null
}
} catch (e: Exception) {
if (e is CancellationException) throw e
null
},
)
.build(),
)
.build()
}
mediaItem.value?.let { mediaItem?.let {
val myState = remember(videoUri) { mutableStateOf(it) } val myState = remember(videoUri) { mutableStateOf(it) }
inner(myState) inner(myState)
} }
} }
@Immutable
sealed class MediaControllerState {
@Immutable object NotStarted : MediaControllerState()
@Immutable object Loading : MediaControllerState()
@Stable class Loaded(val instance: MediaController) : MediaControllerState()
}
@Composable @Composable
@OptIn(UnstableApi::class) @OptIn(UnstableApi::class)
fun GetVideoController( fun GetVideoController(
@ -394,12 +396,11 @@ fun GetVideoController(
val controller = val controller =
remember(videoUri) { remember(videoUri) {
val globalMutex = keepPlayingMutex mutableStateOf(
mutableStateOf<MediaControllerState>( if (videoUri == keepPlayingMutex?.currentMediaItem?.mediaId) {
if (videoUri == globalMutex?.currentMediaItem?.mediaId) { keepPlayingMutex
MediaControllerState.Loaded(globalMutex)
} else { } else {
MediaControllerState.NotStarted null
}, },
) )
} }
@ -419,9 +420,7 @@ fun GetVideoController(
DisposableEffect(key1 = videoUri) { DisposableEffect(key1 = videoUri) {
// If it is not null, the user might have come back from a playing video, like clicking on // If it is not null, the user might have come back from a playing video, like clicking on
// the notification of the video player. // the notification of the video player.
if (controller.value == MediaControllerState.NotStarted) { if (controller.value == null) {
controller.value = MediaControllerState.Loading
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
Log.d("PlaybackService", "Preparing Video $videoUri ") Log.d("PlaybackService", "Preparing Video $videoUri ")
PlaybackClientController.prepareController( PlaybackClientController.prepareController(
@ -432,29 +431,27 @@ fun GetVideoController(
) { ) {
scope.launch(Dispatchers.Main) { scope.launch(Dispatchers.Main) {
// REQUIRED TO BE RUN IN THE MAIN THREAD // REQUIRED TO BE RUN IN THE MAIN THREAD
val newState = MediaControllerState.Loaded(it)
if (!it.isPlaying) { if (!it.isPlaying) {
if (keepPlayingMutex?.isPlaying == true) { if (keepPlayingMutex?.isPlaying == true) {
// There is a video playing, start this one on mute. // There is a video playing, start this one on mute.
newState.instance.volume = 0f it.volume = 0f
} else { } else {
// There is no other video playing. Use the default mute state to // There is no other video playing. Use the default mute state to
// decide if sound is on or not. // decide if sound is on or not.
newState.instance.volume = if (defaultToStart) 0f else 1f it.volume = if (defaultToStart) 0f else 1f
} }
} }
newState.instance.setMediaItem(mediaItem.value) it.setMediaItem(mediaItem.value)
newState.instance.prepare() it.prepare()
controller.value = newState controller.value = it
} }
} }
} }
} else if (controller.value is MediaControllerState.Loaded) { } else {
(controller.value as? MediaControllerState.Loaded)?.instance?.let { // has been loaded. prepare to play
controller.value?.let {
scope.launch(Dispatchers.Main) { scope.launch(Dispatchers.Main) {
if (it.playbackState == Player.STATE_IDLE || it.playbackState == Player.STATE_ENDED) { if (it.playbackState == Player.STATE_IDLE || it.playbackState == Player.STATE_ENDED) {
if (it.isPlaying) { if (it.isPlaying) {
@ -466,7 +463,10 @@ fun GetVideoController(
it.volume = if (defaultToStart) 0f else 1f it.volume = if (defaultToStart) 0f else 1f
} }
it.setMediaItem(mediaItem.value) if (mediaItem.value != it.currentMediaItem) {
it.setMediaItem(mediaItem.value)
}
it.prepare() it.prepare()
} }
} }
@ -477,11 +477,11 @@ fun GetVideoController(
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
if (!keepPlaying.value) { if (!keepPlaying.value) {
// Stops and releases the media. // Stops and releases the media.
(controller.value as? MediaControllerState.Loaded)?.instance?.let { controller.value?.let {
it.stop() it.stop()
it.release() it.release()
Log.d("PlaybackService", "Releasing Video $videoUri ") Log.d("PlaybackService", "Releasing Video $videoUri ")
controller.value = MediaControllerState.NotStarted controller.value = null
} }
} }
} }
@ -496,12 +496,9 @@ fun GetVideoController(
if (event == Lifecycle.Event.ON_RESUME) { if (event == Lifecycle.Event.ON_RESUME) {
// if the controller is null, restarts the controller with a new one // if the controller is null, restarts the controller with a new one
// if the controller is not null, just continue playing what the controller was playing // if the controller is not null, just continue playing what the controller was playing
scope.launch(Dispatchers.IO) { if (controller.value == null) {
if (controller.value == MediaControllerState.NotStarted) { scope.launch(Dispatchers.IO) {
controller.value = MediaControllerState.Loading
Log.d("PlaybackService", "Preparing Video from Resume $videoUri ") Log.d("PlaybackService", "Preparing Video from Resume $videoUri ")
PlaybackClientController.prepareController( PlaybackClientController.prepareController(
uid, uid,
videoUri, videoUri,
@ -510,25 +507,22 @@ fun GetVideoController(
) { ) {
scope.launch(Dispatchers.Main) { scope.launch(Dispatchers.Main) {
// REQUIRED TO BE RUN IN THE MAIN THREAD // REQUIRED TO BE RUN IN THE MAIN THREAD
val newState = MediaControllerState.Loaded(it)
// checks again to make sure no other thread has created a controller. // checks again to make sure no other thread has created a controller.
if (!it.isPlaying) { if (!it.isPlaying) {
if (keepPlayingMutex?.isPlaying == true) { if (keepPlayingMutex?.isPlaying == true) {
// There is a video playing, start this one on mute. // There is a video playing, start this one on mute.
newState.instance.volume = 0f it.volume = 0f
} else { } else {
// There is no other video playing. Use the default mute state to // There is no other video playing. Use the default mute state to
// decide if sound is on or not. // decide if sound is on or not.
newState.instance.volume = if (defaultToStart) 0f else 1f it.volume = if (defaultToStart) 0f else 1f
} }
} }
newState.instance.setMediaItem(mediaItem.value) it.setMediaItem(mediaItem.value)
newState.instance.prepare() it.prepare()
controller.value = newState controller.value = it
} }
} }
} }
@ -538,11 +532,11 @@ fun GetVideoController(
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
if (!keepPlaying.value) { if (!keepPlaying.value) {
// Stops and releases the media. // Stops and releases the media.
(controller.value as? MediaControllerState.Loaded)?.instance?.let { controller.value?.let {
Log.d("PlaybackService", "Releasing Video from Pause $videoUri ") Log.d("PlaybackService", "Releasing Video from Pause $videoUri ")
it.stop() it.stop()
it.release() it.release()
controller.value = MediaControllerState.NotStarted controller.value = null
} }
} }
} }
@ -553,7 +547,9 @@ fun GetVideoController(
onDispose { lifeCycleOwner.lifecycle.removeObserver(observer) } onDispose { lifeCycleOwner.lifecycle.removeObserver(observer) }
} }
(controller.value as? MediaControllerState.Loaded)?.let { inner(it.instance, keepPlaying) } controller.value?.let {
inner(it, keepPlaying)
}
} }
// background playing mutex. // background playing mutex.

Wyświetl plik

@ -34,17 +34,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable @Composable
fun ZapRaiserRequest( fun ZapRaiserRequest(
@ -59,7 +63,7 @@ fun ZapRaiserRequest(
modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp), modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp),
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.lightning), imageVector = CustomHashTagIcons.Lightning,
null, null,
modifier = Size20Modifier, modifier = Size20Modifier,
tint = Color.Unspecified, tint = Color.Unspecified,
@ -97,6 +101,9 @@ fun ZapRaiserRequest(
} else { } else {
newPostViewModel.zapRaiserAmount = it.toLongOrNull() newPostViewModel.zapRaiserAmount = it.toLongOrNull()
} }
newPostViewModel.viewModelScope.launch(Dispatchers.IO) {
newPostViewModel.saveDraft()
}
} }
}, },
placeholder = { placeholder = {

Wyświetl plik

@ -88,7 +88,23 @@ class NotificationFeedFilter(val account: Account) : AdditiveFeedFilter<Note>()
filterParams: FilterByListParams, filterParams: FilterByListParams,
): Boolean { ): Boolean {
val loggedInUserHex = account.userProfile().pubkeyHex val loggedInUserHex = account.userProfile().pubkeyHex
val loggedInUser = account.userProfile()
val noteEvent = it.event
val notifAuthor =
if (noteEvent is LnZapEvent) {
val zapRequest = noteEvent.zapRequest
if (zapRequest != null) {
if (noteEvent.zapRequest?.isPrivateZap() == true) {
zapRequest.cachedPrivateZap()?.pubKey ?: zapRequest.pubKey
} else {
zapRequest.pubKey
}
} else {
noteEvent.pubKey
}
} else {
it.author?.pubkeyHex
}
return it.event !is ChannelCreateEvent && return it.event !is ChannelCreateEvent &&
it.event !is ChannelMetadataEvent && it.event !is ChannelMetadataEvent &&
@ -96,10 +112,10 @@ class NotificationFeedFilter(val account: Account) : AdditiveFeedFilter<Note>()
it.event !is BadgeDefinitionEvent && it.event !is BadgeDefinitionEvent &&
it.event !is BadgeProfilesEvent && it.event !is BadgeProfilesEvent &&
it.event !is GiftWrapEvent && it.event !is GiftWrapEvent &&
(it.event is LnZapEvent || it.author !== loggedInUser) && (it.event is LnZapEvent || notifAuthor != loggedInUserHex) &&
(filterParams.isGlobal || filterParams.followLists?.users?.contains(it.author?.pubkeyHex) == true) && (filterParams.isGlobal || filterParams.followLists?.users?.contains(notifAuthor) == true) &&
it.event?.isTaggedUser(loggedInUserHex) ?: false && it.event?.isTaggedUser(loggedInUserHex) ?: false &&
(filterParams.isHiddenList || it.author == null || !account.isHidden(it.author!!.pubkeyHex)) && (filterParams.isHiddenList || notifAuthor == null || !account.isHidden(notifAuthor)) &&
tagsAnEventByUser(it, loggedInUserHex) tagsAnEventByUser(it, loggedInUserHex)
} }

Wyświetl plik

@ -31,7 +31,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
@ -47,7 +47,6 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
@ -185,8 +184,7 @@ private fun RenderTopRouteBar(
Route.Video.base -> StoriesTopBar(followLists, drawerState, accountViewModel, nav) Route.Video.base -> StoriesTopBar(followLists, drawerState, accountViewModel, nav)
Route.Discover.base -> DiscoveryTopBar(followLists, drawerState, accountViewModel, nav) Route.Discover.base -> DiscoveryTopBar(followLists, drawerState, accountViewModel, nav)
Route.Notification.base -> NotificationTopBar(followLists, drawerState, accountViewModel, nav) Route.Notification.base -> NotificationTopBar(followLists, drawerState, accountViewModel, nav)
Route.Settings.base -> Route.Settings.base -> TopBarWithBackButton(stringResource(id = R.string.application_preferences), navPopBack)
TopBarWithBackButton(stringResource(id = R.string.application_preferences), navPopBack)
else -> { else -> {
if (id != null) { if (id != null) {
when (currentRoute) { when (currentRoute) {
@ -495,27 +493,13 @@ fun GenericMainTopBar(
) { ) {
Column(modifier = BottomTopHeight) { Column(modifier = BottomTopHeight) {
TopAppBar( TopAppBar(
colors =
TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
),
title = { title = {
Column( Column(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) { ) {
Box(Modifier) { content()
Column(
modifier =
Modifier
.fillMaxWidth()
.fillMaxHeight(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
content()
}
}
} }
}, },
navigationIcon = { navigationIcon = {
@ -545,9 +529,7 @@ private fun LoggedInUserPictureDrawer(
val profilePicture by val profilePicture by
accountViewModel.account.userProfile().live().profilePictureChanges.observeAsState() accountViewModel.account.userProfile().live().profilePictureChanges.observeAsState()
IconButton( IconButton(onClick = onClick) {
onClick = onClick,
) {
RobohashFallbackAsyncImage( RobohashFallbackAsyncImage(
robot = accountViewModel.userProfile().pubkeyHex, robot = accountViewModel.userProfile().pubkeyHex,
model = profilePicture, model = profilePicture,

Wyświetl plik

@ -88,6 +88,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relays.RelayPool import com.vitorpamplona.amethyst.service.relays.RelayPool
import com.vitorpamplona.amethyst.service.relays.RelayPoolStatus import com.vitorpamplona.amethyst.service.relays.RelayPoolStatus
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
import com.vitorpamplona.amethyst.ui.components.ClickableText import com.vitorpamplona.amethyst.ui.components.ClickableText
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
@ -159,7 +160,10 @@ fun DrawerContent(
) )
ListContent( ListContent(
modifier = Modifier.fillMaxWidth().weight(1f), modifier =
Modifier
.fillMaxWidth()
.weight(1f),
drawerState, drawerState,
openSheet, openSheet,
accountViewModel, accountViewModel,
@ -231,7 +235,8 @@ fun ProfileContentTemplate(
model = profilePicture, model = profilePicture,
contentDescription = stringResource(id = R.string.profile_image), contentDescription = stringResource(id = R.string.profile_image),
modifier = modifier =
Modifier.width(100.dp) Modifier
.width(100.dp)
.height(100.dp) .height(100.dp)
.clip(shape = CircleShape) .clip(shape = CircleShape)
.border(3.dp, MaterialTheme.colorScheme.background, CircleShape) .border(3.dp, MaterialTheme.colorScheme.background, CircleShape)
@ -244,7 +249,10 @@ fun ProfileContentTemplate(
CreateTextWithEmoji( CreateTextWithEmoji(
text = bestDisplayName, text = bestDisplayName,
tags = tags, tags = tags,
modifier = Modifier.padding(top = 7.dp).clickable(onClick = onClick), modifier =
Modifier
.padding(top = 7.dp)
.clickable(onClick = onClick),
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
fontSize = 18.sp, fontSize = 18.sp,
maxLines = 1, maxLines = 1,
@ -454,8 +462,17 @@ fun ListContent(
val proxyPort = remember { mutableStateOf(accountViewModel.account.proxyPort.toString()) } val proxyPort = remember { mutableStateOf(accountViewModel.account.proxyPort.toString()) }
val context = LocalContext.current val context = LocalContext.current
var draftText by remember {
mutableStateOf<String?>(null)
}
var wantsToPost by remember { mutableStateOf(false) }
Column( Column(
modifier = modifier.fillMaxHeight().verticalScroll(rememberScrollState()), modifier =
modifier
.fillMaxHeight()
.verticalScroll(rememberScrollState()),
) { ) {
NavigationRow( NavigationRow(
title = stringResource(R.string.profile), title = stringResource(R.string.profile),
@ -571,6 +588,18 @@ fun ListContent(
) )
} }
if (wantsToPost) {
NewPostView(
{
wantsToPost = false
draftText = null
coroutineScope.launch { drawerState.close() }
},
accountViewModel = accountViewModel,
nav = nav,
)
}
if (disconnectTorDialog) { if (disconnectTorDialog) {
AlertDialog( AlertDialog(
title = { Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_title)) }, title = { Text(text = stringResource(R.string.do_you_really_want_to_disable_tor_title)) },
@ -662,7 +691,8 @@ fun IconRow(
) { ) {
Row( Row(
modifier = modifier =
Modifier.fillMaxWidth() Modifier
.fillMaxWidth()
.combinedClickable( .combinedClickable(
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
@ -693,10 +723,16 @@ fun IconRowRelays(
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth().clickable { onClick() }, modifier =
Modifier
.fillMaxWidth()
.clickable { onClick() },
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth().padding(vertical = 15.dp, horizontal = 25.dp), modifier =
Modifier
.fillMaxWidth()
.padding(vertical = 15.dp, horizontal = 25.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
Icon( Icon(
@ -737,7 +773,10 @@ fun BottomContent(
thickness = DividerThickness, thickness = DividerThickness,
) )
Row( Row(
modifier = Modifier.fillMaxWidth().padding(horizontal = 15.dp), modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = 15.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
ClickableText( ClickableText(

Wyświetl plik

@ -147,7 +147,7 @@ fun NormalChannelCard(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup -> LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) { showPopup ->
CheckNewAndRenderChannelCard( CheckNewAndRenderChannelCard(
baseNote, baseNote,
routeForLastRead, routeForLastRead,
@ -853,9 +853,7 @@ fun Gallery(
@Composable @Composable
fun DisplayAuthorBanner(note: Note) { fun DisplayAuthorBanner(note: Note) {
val authorState by note.live().authorChanges.observeAsState(note.author) WatchAuthor(note) {
BannerImage(it, Modifier.fillMaxSize().clip(QuoteBorder))
authorState?.let { author ->
BannerImage(author, Modifier.fillMaxSize().clip(QuoteBorder))
} }
} }

Wyświetl plik

@ -84,12 +84,15 @@ fun ChatroomHeaderCompose(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
val hasEvent by baseNote.live().hasEvent.observeAsState(baseNote.event != null) if (baseNote.event != null) {
if (hasEvent) {
ChatroomComposeChannelOrUser(baseNote, accountViewModel, nav) ChatroomComposeChannelOrUser(baseNote, accountViewModel, nav)
} else { } else {
BlankNote() val hasEvent by baseNote.live().hasEvent.observeAsState(baseNote.event != null)
if (hasEvent) {
ChatroomComposeChannelOrUser(baseNote, accountViewModel, nav)
} else {
BlankNote()
}
} }
} }

Wyświetl plik

@ -64,6 +64,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.FeatureSetType
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
@ -102,6 +103,7 @@ fun ChatroomMessageCompose(
innerQuote: Boolean = false, innerQuote: Boolean = false,
parentBackgroundColor: MutableState<Color>? = null, parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
nav: (String) -> Unit, nav: (String) -> Unit,
onWantsToReply: (Note) -> Unit, onWantsToReply: (Note) -> Unit,
) { ) {
@ -120,6 +122,7 @@ fun ChatroomMessageCompose(
canPreview, canPreview,
parentBackgroundColor, parentBackgroundColor,
accountViewModel, accountViewModel,
newPostViewModel,
nav, nav,
onWantsToReply, onWantsToReply,
) )
@ -136,6 +139,7 @@ fun NormalChatNote(
canPreview: Boolean = true, canPreview: Boolean = true,
parentBackgroundColor: MutableState<Color>? = null, parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
nav: (String) -> Unit, nav: (String) -> Unit,
onWantsToReply: (Note) -> Unit, onWantsToReply: (Note) -> Unit,
) { ) {
@ -255,6 +259,7 @@ fun NormalChatNote(
availableBubbleSize, availableBubbleSize,
showDetails, showDetails,
accountViewModel, accountViewModel,
newPostViewModel,
nav, nav,
) )
} }
@ -265,6 +270,7 @@ fun NormalChatNote(
popupExpanded = popupExpanded, popupExpanded = popupExpanded,
onDismiss = { popupExpanded = false }, onDismiss = { popupExpanded = false },
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostViewModel,
) )
} }
} }
@ -282,6 +288,7 @@ private fun RenderBubble(
availableBubbleSize: MutableState<Int>, availableBubbleSize: MutableState<Int>,
showDetails: State<Boolean>, showDetails: State<Boolean>,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
val bubbleSize = remember { mutableIntStateOf(0) } val bubbleSize = remember { mutableIntStateOf(0) }
@ -311,6 +318,7 @@ private fun RenderBubble(
canPreview, canPreview,
showDetails, showDetails,
accountViewModel, accountViewModel,
newPostViewModel,
nav, nav,
) )
} }
@ -329,6 +337,7 @@ private fun MessageBubbleLines(
canPreview: Boolean, canPreview: Boolean,
showDetails: State<Boolean>, showDetails: State<Boolean>,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
if (drawAuthorInfo) { if (drawAuthorInfo) {
@ -345,6 +354,7 @@ private fun MessageBubbleLines(
innerQuote = innerQuote, innerQuote = innerQuote,
backgroundBubbleColor = backgroundBubbleColor, backgroundBubbleColor = backgroundBubbleColor,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostViewModel,
nav = nav, nav = nav,
onWantsToReply = onWantsToReply, onWantsToReply = onWantsToReply,
) )
@ -363,6 +373,9 @@ private fun MessageBubbleLines(
bubbleSize = bubbleSize, bubbleSize = bubbleSize,
availableBubbleSize = availableBubbleSize, availableBubbleSize = availableBubbleSize,
firstColumn = { firstColumn = {
if (baseNote.isDraft()) {
DisplayDraftChat()
}
IncognitoBadge(baseNote) IncognitoBadge(baseNote)
ChatTimeAgo(baseNote) ChatTimeAgo(baseNote)
RelayBadgesHorizontal(baseNote, accountViewModel, nav = nav) RelayBadgesHorizontal(baseNote, accountViewModel, nav = nav)
@ -394,11 +407,12 @@ private fun RenderReplyRow(
innerQuote: Boolean, innerQuote: Boolean,
backgroundBubbleColor: MutableState<Color>, backgroundBubbleColor: MutableState<Color>,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
nav: (String) -> Unit, nav: (String) -> Unit,
onWantsToReply: (Note) -> Unit, onWantsToReply: (Note) -> Unit,
) { ) {
if (!innerQuote && note.replyTo?.lastOrNull() != null) { if (!innerQuote && note.replyTo?.lastOrNull() != null) {
RenderReply(note, backgroundBubbleColor, accountViewModel, nav, onWantsToReply) RenderReply(note, backgroundBubbleColor, accountViewModel, newPostViewModel, nav, onWantsToReply)
} }
} }
@ -407,6 +421,7 @@ private fun RenderReply(
note: Note, note: Note,
backgroundBubbleColor: MutableState<Color>, backgroundBubbleColor: MutableState<Color>,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
nav: (String) -> Unit, nav: (String) -> Unit,
onWantsToReply: (Note) -> Unit, onWantsToReply: (Note) -> Unit,
) { ) {
@ -425,6 +440,7 @@ private fun RenderReply(
innerQuote = true, innerQuote = true,
parentBackgroundColor = backgroundBubbleColor, parentBackgroundColor = backgroundBubbleColor,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostViewModel,
nav = nav, nav = nav,
onWantsToReply = onWantsToReply, onWantsToReply = onWantsToReply,
) )

Wyświetl plik

@ -20,8 +20,10 @@
*/ */
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import Following
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
@ -62,6 +64,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.Amethyst
import com.vitorpamplona.amethyst.commons.hashtags.Cashu
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import com.vitorpamplona.amethyst.ui.theme.Size18Modifier import com.vitorpamplona.amethyst.ui.theme.Size18Modifier
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
@ -73,7 +78,7 @@ import com.vitorpamplona.amethyst.ui.theme.subtleButton
@Composable @Composable
fun AmethystIcon(iconSize: Dp) { fun AmethystIcon(iconSize: Dp) {
Icon( Icon(
painter = painterResource(R.drawable.amethyst), imageVector = CustomHashTagIcons.Amethyst,
contentDescription = stringResource(id = R.string.app_logo), contentDescription = stringResource(id = R.string.app_logo),
modifier = Modifier.size(iconSize), modifier = Modifier.size(iconSize),
tint = Color.Unspecified, tint = Color.Unspecified,
@ -83,7 +88,7 @@ fun AmethystIcon(iconSize: Dp) {
@Composable @Composable
fun FollowingIcon(iconSize: Dp) { fun FollowingIcon(iconSize: Dp) {
Icon( Icon(
painter = painterResource(R.drawable.following), imageVector = Following,
contentDescription = stringResource(id = R.string.following), contentDescription = stringResource(id = R.string.following),
modifier = Modifier.size(iconSize), modifier = Modifier.size(iconSize),
tint = Color.Unspecified, tint = Color.Unspecified,
@ -142,11 +147,6 @@ fun HashCheckFailedIcon(iconSize: Dp) {
) )
} }
@Composable
fun LikedIcon(iconSize: Dp) {
LikedIcon(modifier = remember(iconSize) { Modifier.size(iconSize) })
}
@Composable @Composable
fun LikedIcon(modifier: Modifier) { fun LikedIcon(modifier: Modifier) {
Icon( Icon(
@ -206,6 +206,18 @@ fun ZappedIcon(modifier: Modifier) {
ZapIcon(modifier = modifier, BitcoinOrange) ZapIcon(modifier = modifier, BitcoinOrange)
} }
@Preview
@Composable
fun ReactionRowIconPreview() {
Row(verticalAlignment = Alignment.CenterVertically) {
CommentIcon(Size20Modifier, Color.Unspecified)
RepostedIcon(Size20Modifier)
LikeIcon(Size20Modifier, Color.Unspecified)
ZapIcon(Size20Modifier)
ZappedIcon(Size20Modifier)
}
}
@Composable @Composable
fun ZapIcon( fun ZapIcon(
modifier: Modifier, modifier: Modifier,
@ -223,7 +235,7 @@ fun ZapIcon(
@Composable @Composable
fun CashuIcon(modifier: Modifier) { fun CashuIcon(modifier: Modifier) {
Icon( Icon(
painter = painterResource(R.drawable.cashu), imageVector = CustomHashTagIcons.Cashu,
"Cashu", "Cashu",
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = modifier, modifier = modifier,

Wyświetl plik

@ -20,7 +20,6 @@
*/ */
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -76,8 +75,8 @@ import com.vitorpamplona.amethyst.ui.theme.HalfTopPadding
import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifier import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifier
import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifierSmaller import com.vitorpamplona.amethyst.ui.theme.NotificationIconModifierSmaller
import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.Size18dp
import com.vitorpamplona.amethyst.ui.theme.Size19dp import com.vitorpamplona.amethyst.ui.theme.Size19dp
import com.vitorpamplona.amethyst.ui.theme.Size20dp
import com.vitorpamplona.amethyst.ui.theme.Size25dp import com.vitorpamplona.amethyst.ui.theme.Size25dp
import com.vitorpamplona.amethyst.ui.theme.Size35Modifier import com.vitorpamplona.amethyst.ui.theme.Size35Modifier
import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.theme.Size35dp
@ -223,7 +222,7 @@ fun RenderLikeGallery(
) )
} else { } else {
when (val shortReaction = reactionType) { when (val shortReaction = reactionType) {
"+" -> LikedIcon(modifier.size(Size18dp)) "+" -> LikedIcon(modifier.size(Size19dp))
"-" -> Text(text = "\uD83D\uDC4E", modifier = modifier) "-" -> Text(text = "\uD83D\uDC4E", modifier = modifier)
else -> Text(text = shortReaction, modifier = modifier) else -> Text(text = shortReaction, modifier = modifier)
} }
@ -268,7 +267,7 @@ fun RenderBoostGallery(
modifier = NotificationIconModifierSmaller, modifier = NotificationIconModifierSmaller,
) { ) {
RepostedIcon( RepostedIcon(
modifier = remember { Modifier.size(Size19dp).align(Alignment.TopEnd) }, modifier = remember { Modifier.size(Size20dp).align(Alignment.TopEnd) },
) )
} }
@ -289,7 +288,7 @@ fun RenderBoostGallery(
modifier = NotificationIconModifierSmaller, modifier = NotificationIconModifierSmaller,
) { ) {
RepostedIcon( RepostedIcon(
modifier = remember { Modifier.size(Size19dp).align(Alignment.TopEnd) }, modifier = remember { Modifier.size(Size20dp).align(Alignment.TopEnd) },
) )
} }
@ -494,13 +493,11 @@ private fun BoxedAuthor(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
Box(modifier = Size35Modifier.clickable(onClick = { nav(authorRouteFor(note)) })) { Box(modifier = Size35Modifier.clickable(onClick = { nav(authorRouteFor(note)) })) {
WatchNoteAuthor(note) { targetAuthor -> WatchAuthorWithBlank(note, Size35Modifier) { author ->
Crossfade(targetState = targetAuthor, modifier = Size35Modifier) { author -> WatchUserMetadataAndFollowsAndRenderUserProfilePictureOrDefaultAuthor(
WatchUserMetadataAndFollowsAndRenderUserProfilePictureOrDefaultAuthor( author,
author, accountViewModel,
accountViewModel, )
)
}
} }
} }
} }
@ -546,16 +543,6 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture(
} }
} }
@Composable
private fun WatchNoteAuthor(
baseNote: Note,
onContent: @Composable (User?) -> Unit,
) {
val author by baseNote.live().authorChanges.observeAsState(baseNote.author)
onContent(author)
}
@Composable @Composable
private fun WatchUserMetadata( private fun WatchUserMetadata(
author: User, author: User,

Wyświetl plik

@ -45,12 +45,12 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Tunestr
import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.ui.note.LoadStatuses
import com.vitorpamplona.amethyst.ui.note.NIP05CheckingIcon import com.vitorpamplona.amethyst.ui.note.NIP05CheckingIcon
import com.vitorpamplona.amethyst.ui.note.NIP05FailedVerification import com.vitorpamplona.amethyst.ui.note.NIP05FailedVerification
import com.vitorpamplona.amethyst.ui.note.NIP05VerifiedIcon import com.vitorpamplona.amethyst.ui.note.NIP05VerifiedIcon
import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.NIP05IconSize import com.vitorpamplona.amethyst.ui.theme.NIP05IconSize
@ -116,9 +117,9 @@ fun ObserveDisplayNip05Status(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
) { ) {
val author by baseNote.live().authorChanges.observeAsState() WatchAuthor(baseNote = baseNote) {
ObserveDisplayNip05Status(it, columnModifier, accountViewModel, nav)
author?.let { ObserveDisplayNip05Status(it, columnModifier, accountViewModel, nav) } }
} }
@Composable @Composable
@ -230,7 +231,7 @@ fun DisplayStatus(
when (type) { when (type) {
"music" -> "music" ->
Icon( Icon(
painter = painterResource(id = R.drawable.tunestr), imageVector = CustomHashTagIcons.Tunestr,
null, null,
modifier = Size15Modifier.padding(end = Size5dp), modifier = Size15Modifier.padding(end = Size5dp),
tint = MaterialTheme.colorScheme.placeholderText, tint = MaterialTheme.colorScheme.placeholderText,

Wyświetl plik

@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
@ -48,6 +49,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map import androidx.lifecycle.map
@ -105,8 +107,11 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ChannelHeader import com.vitorpamplona.amethyst.ui.screen.loggedIn.ChannelHeader
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.Font12SP
import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.HalfEndPadding
import com.vitorpamplona.amethyst.ui.theme.HalfPadding import com.vitorpamplona.amethyst.ui.theme.HalfPadding
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
import com.vitorpamplona.amethyst.ui.theme.Size25dp import com.vitorpamplona.amethyst.ui.theme.Size25dp
import com.vitorpamplona.amethyst.ui.theme.Size30Modifier import com.vitorpamplona.amethyst.ui.theme.Size30Modifier
import com.vitorpamplona.amethyst.ui.theme.Size34dp import com.vitorpamplona.amethyst.ui.theme.Size34dp
@ -122,6 +127,7 @@ import com.vitorpamplona.amethyst.ui.theme.channelNotePictureModifier
import com.vitorpamplona.amethyst.ui.theme.grayText import com.vitorpamplona.amethyst.ui.theme.grayText
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
import com.vitorpamplona.amethyst.ui.theme.normalWithTopMarginNoteModifier import com.vitorpamplona.amethyst.ui.theme.normalWithTopMarginNoteModifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.amethyst.ui.theme.replyBackground import com.vitorpamplona.amethyst.ui.theme.replyBackground
import com.vitorpamplona.amethyst.ui.theme.replyModifier import com.vitorpamplona.amethyst.ui.theme.replyModifier
import com.vitorpamplona.quartz.events.AppDefinitionEvent import com.vitorpamplona.quartz.events.AppDefinitionEvent
@ -238,7 +244,7 @@ fun AcceptableNote(
nav = nav, nav = nav,
) )
else -> else ->
LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) {
showPopup, showPopup,
-> ->
CheckNewAndRenderNote( CheckNewAndRenderNote(
@ -273,7 +279,7 @@ fun AcceptableNote(
is FileHeaderEvent -> FileHeaderDisplay(baseNote, false, accountViewModel) is FileHeaderEvent -> FileHeaderDisplay(baseNote, false, accountViewModel)
is FileStorageHeaderEvent -> FileStorageHeaderDisplay(baseNote, false, accountViewModel) is FileStorageHeaderEvent -> FileStorageHeaderDisplay(baseNote, false, accountViewModel)
else -> else ->
LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) {
showPopup, showPopup,
-> ->
CheckNewAndRenderNote( CheckNewAndRenderNote(
@ -868,6 +874,29 @@ fun DisplayOtsIfInOriginal(
} }
} }
@Composable
fun DisplayDraft() {
Text(
"Draft",
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.placeholderText,
maxLines = 1,
modifier = HalfStartPadding,
)
}
@Composable
fun DisplayDraftChat() {
Text(
"Draft",
color = MaterialTheme.colorScheme.placeholderText,
modifier = HalfEndPadding,
fontWeight = FontWeight.Bold,
fontSize = Font12SP,
maxLines = 1,
)
}
@Composable @Composable
fun FirstUserInfoRow( fun FirstUserInfoRow(
baseNote: Note, baseNote: Note,
@ -910,6 +939,10 @@ fun FirstUserInfoRow(
} }
} }
if (baseNote.isDraft()) {
DisplayDraft()
}
TimeAgo(baseNote) TimeAgo(baseNote)
MoreOptionsButton(baseNote, editState, accountViewModel, nav) MoreOptionsButton(baseNote, editState, accountViewModel, nav)

Wyświetl plik

@ -40,6 +40,7 @@ import androidx.compose.material.icons.filled.AlternateEmail
import androidx.compose.material.icons.filled.Block import androidx.compose.material.icons.filled.Block
import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.FormatQuote import androidx.compose.material.icons.filled.FormatQuote
import androidx.compose.material.icons.filled.PersonAdd import androidx.compose.material.icons.filled.PersonAdd
import androidx.compose.material.icons.filled.PersonRemove import androidx.compose.material.icons.filled.PersonRemove
@ -84,6 +85,8 @@ import androidx.core.graphics.ColorUtils
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.components.SelectTextDialog import com.vitorpamplona.amethyst.ui.components.SelectTextDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog
@ -132,6 +135,7 @@ val externalLinkForNote = { note: Note ->
fun LongPressToQuickAction( fun LongPressToQuickAction(
baseNote: Note, baseNote: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
content: @Composable (() -> Unit) -> Unit, content: @Composable (() -> Unit) -> Unit,
) { ) {
val popupExpanded = remember { mutableStateOf(false) } val popupExpanded = remember { mutableStateOf(false) }
@ -140,7 +144,7 @@ fun LongPressToQuickAction(
content(showPopup) content(showPopup)
NoteQuickActionMenu(baseNote, popupExpanded.value, hidePopup, accountViewModel) NoteQuickActionMenu(baseNote, popupExpanded.value, hidePopup, accountViewModel, newPostViewModel)
} }
@Composable @Composable
@ -149,20 +153,24 @@ fun NoteQuickActionMenu(
popupExpanded: Boolean, popupExpanded: Boolean,
onDismiss: () -> Unit, onDismiss: () -> Unit,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
) { ) {
val showSelectTextDialog = remember { mutableStateOf(false) } val showSelectTextDialog = remember { mutableStateOf(false) }
val showDeleteAlertDialog = remember { mutableStateOf(false) } val showDeleteAlertDialog = remember { mutableStateOf(false) }
val showBlockAlertDialog = remember { mutableStateOf(false) } val showBlockAlertDialog = remember { mutableStateOf(false) }
val showReportDialog = remember { mutableStateOf(false) } val showReportDialog = remember { mutableStateOf(false) }
val editDraftDialog = remember { mutableStateOf(false) }
if (popupExpanded) { if (popupExpanded) {
RenderMainPopup( RenderMainPopup(
accountViewModel, accountViewModel,
newPostViewModel,
note, note,
onDismiss, onDismiss,
showBlockAlertDialog, showBlockAlertDialog,
showDeleteAlertDialog, showDeleteAlertDialog,
showReportDialog, showReportDialog,
editDraftDialog,
) )
} }
@ -199,16 +207,29 @@ fun NoteQuickActionMenu(
onDismiss() onDismiss()
} }
} }
if (editDraftDialog.value) {
NewPostView(
onClose = {
editDraftDialog.value = false
},
accountViewModel = accountViewModel,
draft = note,
nav = { },
)
}
} }
@Composable @Composable
private fun RenderMainPopup( private fun RenderMainPopup(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel?,
note: Note, note: Note,
onDismiss: () -> Unit, onDismiss: () -> Unit,
showBlockAlertDialog: MutableState<Boolean>, showBlockAlertDialog: MutableState<Boolean>,
showDeleteAlertDialog: MutableState<Boolean>, showDeleteAlertDialog: MutableState<Boolean>,
showReportDialog: MutableState<Boolean>, showReportDialog: MutableState<Boolean>,
editDraftDialog: MutableState<Boolean>,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val primaryLight = lightenColor(MaterialTheme.colorScheme.primary, 0.1f) val primaryLight = lightenColor(MaterialTheme.colorScheme.primary, 0.1f)
@ -279,6 +300,22 @@ private fun RenderMainPopup(
} }
} }
if (note.isDraft()) {
VerticalDivider(color = primaryLight)
NoteQuickActionItem(
Icons.Default.Edit,
stringResource(R.string.edit_draft),
) {
if (newPostViewModel != null) {
newPostViewModel.load(accountViewModel, null, null, null, null, note)
onDismiss()
} else {
editDraftDialog.value = true
onDismiss()
}
}
}
if (!isOwnNote) { if (!isOwnNote) {
VerticalDivider(color = primaryLight) VerticalDivider(color = primaryLight)
@ -389,14 +426,20 @@ fun NoteQuickActionItem(
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
Column( Column(
modifier = Modifier.size(70.dp).clickable { onClick() }, modifier =
Modifier
.size(70.dp)
.clickable { onClick() },
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Icon( Icon(
imageVector = icon, imageVector = icon,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(24.dp).padding(bottom = 5.dp), modifier =
Modifier
.size(24.dp)
.padding(bottom = 5.dp),
tint = Color.White, tint = Color.White,
) )
Text(text = label, fontSize = 12.sp, color = Color.White, textAlign = TextAlign.Center) Text(text = label, fontSize = 12.sp, color = Color.White, textAlign = TextAlign.Center)
@ -527,7 +570,10 @@ fun QuickActionAlertDialog(
text = { Text(textContent) }, text = { Text(textContent) },
confirmButton = { confirmButton = {
Row( Row(
modifier = Modifier.padding(all = 8.dp).fillMaxWidth(), modifier =
Modifier
.padding(all = 8.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
) { ) {
TextButton(onClick = onClickDontShowAgain) { TextButton(onClick = onClickDontShowAgain) {

Wyświetl plik

@ -99,7 +99,6 @@ import coil.request.CachePolicy
import coil.request.ImageRequest import coil.request.ImageRequest
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.zap
import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.service.ZapPaymentHandler
import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.components.GenericLoadable
@ -111,13 +110,13 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.DarkerGreen import com.vitorpamplona.amethyst.ui.theme.DarkerGreen
import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Font14SP
import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
import com.vitorpamplona.amethyst.ui.theme.Height24dpModifier import com.vitorpamplona.amethyst.ui.theme.Height24dpModifier
import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp
import com.vitorpamplona.amethyst.ui.theme.NoSoTinyBorders import com.vitorpamplona.amethyst.ui.theme.NoSoTinyBorders
import com.vitorpamplona.amethyst.ui.theme.ReactionRowExpandButton import com.vitorpamplona.amethyst.ui.theme.ReactionRowExpandButton
import com.vitorpamplona.amethyst.ui.theme.ReactionRowHeight import com.vitorpamplona.amethyst.ui.theme.ReactionRowHeight
import com.vitorpamplona.amethyst.ui.theme.ReactionRowZapraiserSize import com.vitorpamplona.amethyst.ui.theme.ReactionRowZapraiserSize
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
import com.vitorpamplona.amethyst.ui.theme.Size0dp import com.vitorpamplona.amethyst.ui.theme.Size0dp
import com.vitorpamplona.amethyst.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.ui.theme.Size16Modifier
import com.vitorpamplona.amethyst.ui.theme.Size17Modifier import com.vitorpamplona.amethyst.ui.theme.Size17Modifier
@ -229,7 +228,11 @@ private fun GenericInnerReactionRow(
five: @Composable () -> Unit, five: @Composable () -> Unit,
six: @Composable () -> Unit, six: @Composable () -> Unit,
) { ) {
Row(verticalAlignment = CenterVertically, modifier = ReactionRowHeight) { Row(
verticalAlignment = CenterVertically,
horizontalArrangement = RowColSpacing,
modifier = ReactionRowHeight,
) {
val fullWeight = remember { Modifier.weight(1f) } val fullWeight = remember { Modifier.weight(1f) }
if (showReactionDetail) { if (showReactionDetail) {
@ -241,11 +244,11 @@ private fun GenericInnerReactionRow(
} }
} }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { two() } Row(verticalAlignment = CenterVertically, horizontalArrangement = RowColSpacing, modifier = fullWeight) { two() }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { three() } Row(verticalAlignment = CenterVertically, horizontalArrangement = RowColSpacing, modifier = fullWeight) { three() }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { four() } Row(verticalAlignment = CenterVertically, horizontalArrangement = RowColSpacing, modifier = fullWeight) { four() }
Row(verticalAlignment = CenterVertically, modifier = fullWeight) { five() } Row(verticalAlignment = CenterVertically, modifier = fullWeight) { five() }
@ -307,7 +310,12 @@ fun RenderZapRaiser(
} }
LinearProgressIndicator( LinearProgressIndicator(
modifier = remember(details) { Modifier.fillMaxWidth().height(if (details) 24.dp else 4.dp) }, modifier =
remember(details) {
Modifier
.fillMaxWidth()
.height(if (details) 24.dp else 4.dp)
},
color = color, color = color,
progress = { zapraiserStatus.progress }, progress = { zapraiserStatus.progress },
) )
@ -587,6 +595,13 @@ fun ReplyReaction(
IconButton( IconButton(
modifier = iconSizeModifier, modifier = iconSizeModifier,
onClick = { onClick = {
if (baseNote.isDraft()) {
accountViewModel.toast(
R.string.draft_note,
R.string.it_s_not_possible_to_reply_to_a_draft_note,
)
return@IconButton
}
if (accountViewModel.isWriteable()) { if (accountViewModel.isWriteable()) {
onPress() onPress()
} else { } else {
@ -658,7 +673,6 @@ fun TextCount(
text = showCount(count), text = showCount(count),
fontSize = Font14SP, fontSize = Font14SP,
color = textColor, color = textColor,
modifier = HalfStartPadding,
maxLines = 1, maxLines = 1,
) )
} }
@ -774,7 +788,8 @@ fun LikeReaction(
Box( Box(
contentAlignment = Center, contentAlignment = Center,
modifier = modifier =
Modifier.size(iconSize) Modifier
.size(iconSize)
.combinedClickable( .combinedClickable(
role = Role.Button, role = Role.Button,
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
@ -782,6 +797,7 @@ fun LikeReaction(
onClick = { onClick = {
likeClick( likeClick(
accountViewModel, accountViewModel,
baseNote,
onMultipleChoices = { wantsToReact = true }, onMultipleChoices = { wantsToReact = true },
onWantsToSignReaction = { accountViewModel.reactToOrDelete(baseNote) }, onWantsToSignReaction = { accountViewModel.reactToOrDelete(baseNote) },
) )
@ -884,9 +900,17 @@ fun ObserveLikeText(
private fun likeClick( private fun likeClick(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
baseNote: Note,
onMultipleChoices: () -> Unit, onMultipleChoices: () -> Unit,
onWantsToSignReaction: () -> Unit, onWantsToSignReaction: () -> Unit,
) { ) {
if (baseNote.isDraft()) {
accountViewModel.toast(
R.string.draft_note,
R.string.it_s_not_possible_to_react_to_a_draft_note,
)
return
}
if (accountViewModel.account.reactionChoices.isEmpty()) { if (accountViewModel.account.reactionChoices.isEmpty()) {
accountViewModel.toast( accountViewModel.toast(
R.string.no_reactions_setup, R.string.no_reactions_setup,
@ -1080,6 +1104,14 @@ fun zapClick(
onError: (String, String) -> Unit, onError: (String, String) -> Unit,
onPayViaIntent: (ImmutableList<ZapPaymentHandler.Payable>) -> Unit, onPayViaIntent: (ImmutableList<ZapPaymentHandler.Payable>) -> Unit,
) { ) {
if (baseNote.isDraft()) {
accountViewModel.toast(
R.string.draft_note,
R.string.it_s_not_possible_to_zap_to_a_draft_note,
)
return
}
if (accountViewModel.account.zapAmountChoices.isEmpty()) { if (accountViewModel.account.zapAmountChoices.isEmpty()) {
accountViewModel.toast( accountViewModel.toast(
context.getString(R.string.error_dialog_zap_error), context.getString(R.string.error_dialog_zap_error),

Wyświetl plik

@ -21,7 +21,6 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
@ -77,9 +76,7 @@ fun NoteAuthorPicture(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClick: ((User) -> Unit)? = null, onClick: ((User) -> Unit)? = null,
) { ) {
val author by baseNote.live().authorChanges.observeAsState(baseNote.author) WatchAuthorWithBlank(baseNote) {
Crossfade(targetState = author, label = "NoteAuthorPicture") {
if (it == null) { if (it == null) {
DisplayBlankAuthor(size, modifier) DisplayBlankAuthor(size, modifier)
} else { } else {

Wyświetl plik

@ -49,13 +49,45 @@ import com.vitorpamplona.quartz.events.ImmutableListOfLists
fun NoteUsernameDisplay( fun NoteUsernameDisplay(
baseNote: Note, baseNote: Note,
weight: Modifier = Modifier, weight: Modifier = Modifier,
showPlayButton: Boolean = true,
textColor: Color = Color.Unspecified, textColor: Color = Color.Unspecified,
) { ) {
val authorState by baseNote.live().authorChanges.observeAsState(baseNote.author) WatchAuthor(baseNote) {
UsernameDisplay(it, weight, textColor = textColor)
}
}
Crossfade(targetState = authorState, modifier = weight, label = "NoteUsernameDisplay") { @Composable
it?.let { UsernameDisplay(it, weight, showPlayButton, textColor = textColor) } fun WatchAuthor(
baseNote: Note,
inner: @Composable (User) -> Unit,
) {
val noteAuthor = baseNote.author
if (noteAuthor != null) {
inner(noteAuthor)
} else {
val authorState by baseNote.live().metadata.observeAsState()
authorState?.note?.author?.let {
inner(it)
}
}
}
@Composable
fun WatchAuthorWithBlank(
baseNote: Note,
modifier: Modifier = Modifier,
inner: @Composable (User?) -> Unit,
) {
val noteAuthor = baseNote.author
if (noteAuthor != null) {
inner(noteAuthor)
} else {
val authorState by baseNote.live().metadata.observeAsState()
Crossfade(targetState = authorState?.note?.author, modifier = modifier, label = "WatchAuthorWithBlank") { newAuthor ->
inner(newAuthor)
}
} }
} }
@ -63,7 +95,6 @@ fun NoteUsernameDisplay(
fun UsernameDisplay( fun UsernameDisplay(
baseUser: User, baseUser: User,
weight: Modifier = Modifier, weight: Modifier = Modifier,
showPlayButton: Boolean = true,
fontWeight: FontWeight = FontWeight.Bold, fontWeight: FontWeight = FontWeight.Bold,
textColor: Color = Color.Unspecified, textColor: Color = Color.Unspecified,
) { ) {
@ -72,7 +103,7 @@ fun UsernameDisplay(
Crossfade(targetState = userMetadata, modifier = weight, label = "UsernameDisplay") { Crossfade(targetState = userMetadata, modifier = weight, label = "UsernameDisplay") {
val name = it?.bestName() val name = it?.bestName()
if (name != null) { if (name != null) {
UserDisplay(name, it.tags, weight, showPlayButton, fontWeight, textColor) UserDisplay(name, it.tags, weight, fontWeight, textColor)
} else { } else {
NPubDisplay(baseUser, weight, fontWeight, textColor) NPubDisplay(baseUser, weight, fontWeight, textColor)
} }
@ -101,7 +132,6 @@ private fun UserDisplay(
bestDisplayName: String, bestDisplayName: String,
tags: ImmutableListOfLists<String>?, tags: ImmutableListOfLists<String>?,
modifier: Modifier, modifier: Modifier,
showPlayButton: Boolean = true,
fontWeight: FontWeight = FontWeight.Bold, fontWeight: FontWeight = FontWeight.Bold,
textColor: Color = Color.Unspecified, textColor: Color = Color.Unspecified,
) { ) {

Wyświetl plik

@ -52,6 +52,7 @@ fun WatchNoteEvent(
LongPressToQuickAction( LongPressToQuickAction(
baseNote = baseNote, baseNote = baseNote,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = null,
) { showPopup -> ) { showPopup ->
BlankNote( BlankNote(
remember { remember {

Wyświetl plik

@ -179,7 +179,7 @@ fun ZapCustomDialog(
) )
ZapButton( ZapButton(
isActive = postViewModel.canSend(), isActive = postViewModel.canSend() && !baseNote.isDraft(),
) { ) {
accountViewModel.zap( accountViewModel.zap(
baseNote, baseNote,
@ -388,7 +388,7 @@ fun PayViaIntentDialog(
Column(modifier = Modifier.weight(1f)) { Column(modifier = Modifier.weight(1f)) {
if (it.user != null) { if (it.user != null) {
UsernameDisplay(it.user, showPlayButton = false) UsernameDisplay(it.user)
} else { } else {
Text( Text(
text = stringResource(id = R.string.wallet_number, index + 1), text = stringResource(id = R.string.wallet_number, index + 1),

Wyświetl plik

@ -38,6 +38,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.BaseUserPicture
import com.vitorpamplona.amethyst.ui.note.WatchAuthor
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader import com.vitorpamplona.amethyst.ui.theme.authorNotePictureForImageHeader
@ -47,14 +48,12 @@ fun DefaultImageHeader(
note: Note, note: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
val authorState by note.live().authorChanges.observeAsState(note.author) WatchAuthor(baseNote = note) {
authorState?.let { author ->
Box { Box {
BannerImage(author) BannerImage(it)
Box(authorNotePictureForImageHeader.align(Alignment.BottomStart)) { Box(authorNotePictureForImageHeader.align(Alignment.BottomStart)) {
BaseUserPicture(author, Size55dp, accountViewModel, Modifier) BaseUserPicture(it, Size55dp, accountViewModel, Modifier)
} }
} }
} }

Wyświetl plik

@ -185,6 +185,7 @@ class AddBountyAmountViewModel : ViewModel() {
root = null, root = null,
directMentions = setOf(), directMentions = setOf(),
forkedFrom = null, forkedFrom = null,
draftTag = null,
) )
nextAmount = TextFieldValue("") nextAmount = TextFieldValue("")

Wyświetl plik

@ -45,6 +45,7 @@ import androidx.core.content.ContextCompat
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.actions.EditPostView import com.vitorpamplona.amethyst.ui.actions.EditPostView
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.components.GenericLoadable
import com.vitorpamplona.amethyst.ui.note.VerticalDotsIcon import com.vitorpamplona.amethyst.ui.note.VerticalDotsIcon
import com.vitorpamplona.amethyst.ui.note.externalLinkForNote import com.vitorpamplona.amethyst.ui.note.externalLinkForNote
@ -122,6 +123,11 @@ fun NoteDropDownMenu(
mutableStateOf(false) mutableStateOf(false)
} }
val wantsToEditDraft =
remember {
mutableStateOf(false)
}
if (wantsToEditPost.value) { if (wantsToEditPost.value) {
// avoids changing while drafting a note and a new event shows up. // avoids changing while drafting a note and a new event shows up.
val versionLookingAt = val versionLookingAt =
@ -141,6 +147,18 @@ fun NoteDropDownMenu(
) )
} }
if (wantsToEditDraft.value) {
NewPostView(
onClose = {
popupExpanded.value = false
wantsToEditDraft.value = false
},
accountViewModel = accountViewModel,
draft = note,
nav = nav,
)
}
DropdownMenu( DropdownMenu(
expanded = popupExpanded.value, expanded = popupExpanded.value,
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
@ -219,7 +237,15 @@ fun NoteDropDownMenu(
}, },
) )
HorizontalDivider(thickness = DividerThickness) HorizontalDivider(thickness = DividerThickness)
if (note.event is TextNoteEvent) { if (note.isDraft()) {
DropdownMenuItem(
text = { Text(stringResource(R.string.edit_draft)) },
onClick = {
wantsToEditDraft.value = true
},
)
}
if (note.event is TextNoteEvent && !note.isDraft()) {
if (state.isLoggedUser) { if (state.isLoggedUser) {
DropdownMenuItem( DropdownMenuItem(
text = { Text(stringResource(R.string.edit_post)) }, text = { Text(stringResource(R.string.edit_post)) },

Wyświetl plik

@ -74,7 +74,7 @@ import com.vitorpamplona.quartz.events.EmptyTagList
import com.vitorpamplona.quartz.events.UserMetadata import com.vitorpamplona.quartz.events.UserMetadata
import com.vitorpamplona.quartz.events.toImmutableListOfLists import com.vitorpamplona.quartz.events.toImmutableListOfLists
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.withContext
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
@ -88,7 +88,7 @@ fun RenderAppDefinition(
var metadata by remember { mutableStateOf<UserMetadata?>(null) } var metadata by remember { mutableStateOf<UserMetadata?>(null) }
LaunchedEffect(key1 = noteEvent) { LaunchedEffect(key1 = noteEvent) {
launch(Dispatchers.Default) { metadata = noteEvent.appMetaData() } withContext(Dispatchers.Default) { metadata = noteEvent.appMetaData() }
} }
metadata?.let { metadata?.let {

Wyświetl plik

@ -38,6 +38,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
import com.vitorpamplona.amethyst.ui.note.ChatroomMessageCompose import com.vitorpamplona.amethyst.ui.note.ChatroomMessageCompose
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.theme.FeedPadding
@ -48,6 +49,7 @@ import com.vitorpamplona.amethyst.ui.theme.HalfPadding
fun RefreshingChatroomFeedView( fun RefreshingChatroomFeedView(
viewModel: FeedViewModel, viewModel: FeedViewModel,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
routeForLastRead: String, routeForLastRead: String,
onWantsToReply: (Note) -> Unit, onWantsToReply: (Note) -> Unit,
@ -59,6 +61,7 @@ fun RefreshingChatroomFeedView(
RenderChatroomFeedView( RenderChatroomFeedView(
viewModel, viewModel,
accountViewModel, accountViewModel,
newPostViewModel,
listState, listState,
nav, nav,
routeForLastRead, routeForLastRead,
@ -72,6 +75,7 @@ fun RefreshingChatroomFeedView(
fun RenderChatroomFeedView( fun RenderChatroomFeedView(
viewModel: FeedViewModel, viewModel: FeedViewModel,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel,
listState: LazyListState, listState: LazyListState,
nav: (String) -> Unit, nav: (String) -> Unit,
routeForLastRead: String, routeForLastRead: String,
@ -91,6 +95,7 @@ fun RenderChatroomFeedView(
ChatroomFeedLoaded( ChatroomFeedLoaded(
state, state,
accountViewModel, accountViewModel,
newPostViewModel,
listState, listState,
nav, nav,
routeForLastRead, routeForLastRead,
@ -108,6 +113,7 @@ fun RenderChatroomFeedView(
fun ChatroomFeedLoaded( fun ChatroomFeedLoaded(
state: FeedState.Loaded, state: FeedState.Loaded,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostViewModel: NewPostViewModel,
listState: LazyListState, listState: LazyListState,
nav: (String) -> Unit, nav: (String) -> Unit,
routeForLastRead: String, routeForLastRead: String,
@ -130,6 +136,7 @@ fun ChatroomFeedLoaded(
baseNote = item, baseNote = item,
routeForLastRead = routeForLastRead, routeForLastRead = routeForLastRead,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostViewModel,
nav = nav, nav = nav,
onWantsToReply = onWantsToReply, onWantsToReply = onWantsToReply,
) )

Wyświetl plik

@ -86,6 +86,7 @@ import com.vitorpamplona.amethyst.ui.components.ObserveDisplayNip05Status
import com.vitorpamplona.amethyst.ui.components.mockAccountViewModel import com.vitorpamplona.amethyst.ui.components.mockAccountViewModel
import com.vitorpamplona.amethyst.ui.navigation.routeToMessage import com.vitorpamplona.amethyst.ui.navigation.routeToMessage
import com.vitorpamplona.amethyst.ui.note.BlankNote import com.vitorpamplona.amethyst.ui.note.BlankNote
import com.vitorpamplona.amethyst.ui.note.DisplayDraft
import com.vitorpamplona.amethyst.ui.note.DisplayOtsIfInOriginal import com.vitorpamplona.amethyst.ui.note.DisplayOtsIfInOriginal
import com.vitorpamplona.amethyst.ui.note.HiddenNote import com.vitorpamplona.amethyst.ui.note.HiddenNote
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
@ -446,6 +447,10 @@ fun NoteMaster(
DisplayPoW(pow) DisplayPoW(pow)
} }
if (note.isDraft()) {
DisplayDraft()
}
DisplayOtsIfInOriginal(note, editState, accountViewModel) DisplayOtsIfInOriginal(note, editState, accountViewModel)
} }
} }
@ -605,7 +610,7 @@ fun NoteMaster(
ReactionsRow(note, true, editState, accountViewModel, nav) ReactionsRow(note, true, editState, accountViewModel, nav)
} }
NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel) NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel, null)
} }
} }

Wyświetl plik

@ -1209,6 +1209,14 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
baseNote: Note, baseNote: Note,
onMore: () -> Unit, onMore: () -> Unit,
) { ) {
if (baseNote.isDraft()) {
toast(
R.string.draft_note,
R.string.it_s_not_possible_to_quote_to_a_draft_note,
)
return
}
if (isWriteable()) { if (isWriteable()) {
if (hasBoosted(baseNote)) { if (hasBoosted(baseNote)) {
deleteBoostsTo(baseNote) deleteBoostsTo(baseNote)
@ -1304,6 +1312,11 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
} }
} }
suspend fun deleteDraft(draftTag: String) {
val notes = LocalCache.draftNotes(draftTag)
account.delete(notes)
}
val bechLinkCache = CachedLoadedBechLink(this) val bechLinkCache = CachedLoadedBechLink(this)
class CachedLoadedBechLink(val accountViewModel: AccountViewModel) : GenericBaseCache<String, LoadedBechLink>(20) { class CachedLoadedBechLink(val accountViewModel: AccountViewModel) : GenericBaseCache<String, LoadedBechLink>(20) {

Wyświetl plik

@ -163,12 +163,17 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.text.DateFormat import java.text.DateFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.UUID
@Composable @Composable
fun ChannelScreen( fun ChannelScreen(
@ -187,6 +192,7 @@ fun ChannelScreen(
} }
} }
@OptIn(FlowPreview::class)
@Composable @Composable
fun PrepareChannelViewModels( fun PrepareChannelViewModels(
baseChannel: Channel, baseChannel: Channel,
@ -204,8 +210,21 @@ fun PrepareChannelViewModels(
) )
val channelScreenModel: NewPostViewModel = viewModel() val channelScreenModel: NewPostViewModel = viewModel()
LaunchedEffect(Unit) {
launch(Dispatchers.IO) {
channelScreenModel.draftTextChanges
.receiveAsFlow()
.debounce(1000)
.collectLatest {
channelScreenModel.sendPost(localDraft = channelScreenModel.draftTag)
}
}
}
channelScreenModel.accountViewModel = accountViewModel channelScreenModel.accountViewModel = accountViewModel
channelScreenModel.account = accountViewModel.account channelScreenModel.account = accountViewModel.account
channelScreenModel.originalNote = LocalCache.getNoteIfExists(baseChannel.idHex)
ChannelScreen( ChannelScreen(
channel = baseChannel, channel = baseChannel,
@ -287,6 +306,7 @@ fun ChannelScreen(
RefreshingChatroomFeedView( RefreshingChatroomFeedView(
viewModel = feedViewModel, viewModel = feedViewModel,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostModel,
nav = nav, nav = nav,
routeForLastRead = "Channel/${channel.idHex}", routeForLastRead = "Channel/${channel.idHex}",
onWantsToReply = { replyTo.value = it }, onWantsToReply = { replyTo.value = it },
@ -295,7 +315,7 @@ fun ChannelScreen(
Spacer(modifier = DoubleVertSpacer) Spacer(modifier = DoubleVertSpacer)
replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, nav) { replyTo.value = null } } replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, newPostModel, nav) { replyTo.value = null } }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@ -323,6 +343,7 @@ fun ChannelScreen(
mentions = tagger.pTags, mentions = tagger.pTags,
wantsToMarkAsSensitive = false, wantsToMarkAsSensitive = false,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = null,
) )
} else if (channel is LiveActivitiesChannel) { } else if (channel is LiveActivitiesChannel) {
accountViewModel.account.sendLiveMessage( accountViewModel.account.sendLiveMessage(
@ -332,10 +353,13 @@ fun ChannelScreen(
mentions = tagger.pTags, mentions = tagger.pTags,
wantsToMarkAsSensitive = false, wantsToMarkAsSensitive = false,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = null,
) )
} }
newPostModel.message = TextFieldValue("") newPostModel.message = TextFieldValue("")
replyTo.value = null replyTo.value = null
accountViewModel.deleteDraft(newPostModel.draftTag)
newPostModel.draftTag = UUID.randomUUID().toString()
feedViewModel.sendToTop() feedViewModel.sendToTop()
} }
} }
@ -346,6 +370,7 @@ fun ChannelScreen(
fun DisplayReplyingToNote( fun DisplayReplyingToNote(
replyingNote: Note?, replyingNote: Note?,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
newPostModel: NewPostViewModel,
nav: (String) -> Unit, nav: (String) -> Unit,
onCancel: () -> Unit, onCancel: () -> Unit,
) { ) {
@ -364,6 +389,7 @@ fun DisplayReplyingToNote(
null, null,
innerQuote = true, innerQuote = true,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostModel,
nav = nav, nav = nav,
onWantsToReply = {}, onWantsToReply = {},
) )
@ -665,7 +691,12 @@ fun ShowVideoStreaming(
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
modifier = remember { Modifier.fillMaxWidth().heightIn(min = 50.dp, max = 300.dp) }, modifier =
remember {
Modifier
.fillMaxWidth()
.heightIn(min = 50.dp, max = 300.dp)
},
) { ) {
val zoomableUrlVideo = val zoomableUrlVideo =
remember(streamingInfo) { remember(streamingInfo) {

Wyświetl plik

@ -116,14 +116,21 @@ import com.vitorpamplona.amethyst.ui.theme.Size34dp
import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdPadding
import com.vitorpamplona.amethyst.ui.theme.ZeroPadding import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.encoders.Hex
import com.vitorpamplona.quartz.encoders.toNpub
import com.vitorpamplona.quartz.events.ChatMessageEvent import com.vitorpamplona.quartz.events.ChatMessageEvent
import com.vitorpamplona.quartz.events.ChatroomKey import com.vitorpamplona.quartz.events.ChatroomKey
import com.vitorpamplona.quartz.events.findURLs import com.vitorpamplona.quartz.events.findURLs
import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.UUID
@Composable @Composable
fun ChatroomScreen( fun ChatroomScreen(
@ -206,6 +213,7 @@ fun LoadRoomByAuthor(
content(room) content(room)
} }
@OptIn(FlowPreview::class)
@Composable @Composable
fun PrepareChatroomViewModels( fun PrepareChatroomViewModels(
room: ChatroomKey, room: ChatroomKey,
@ -230,8 +238,20 @@ fun PrepareChatroomViewModels(
if (newPostModel.requiresNIP24) { if (newPostModel.requiresNIP24) {
newPostModel.nip24 = true newPostModel.nip24 = true
} }
room.users.forEach {
newPostModel.toUsers = TextFieldValue(newPostModel.toUsers.text + " @${Hex.decode(it).toNpub()}")
}
LaunchedEffect(key1 = newPostModel) { LaunchedEffect(key1 = newPostModel) {
launch(Dispatchers.IO) {
newPostModel.draftTextChanges
.receiveAsFlow()
.debounce(1000)
.collectLatest {
newPostModel.sendPost(localDraft = newPostModel.draftTag)
}
}
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
val hasNIP24 = val hasNIP24 =
accountViewModel.userProfile().privateChatrooms[room]?.roomMessages?.any { accountViewModel.userProfile().privateChatrooms[room]?.roomMessages?.any {
@ -313,21 +333,28 @@ fun ChatroomScreen(
RefreshingChatroomFeedView( RefreshingChatroomFeedView(
viewModel = feedViewModel, viewModel = feedViewModel,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
newPostViewModel = newPostModel,
nav = nav, nav = nav,
routeForLastRead = "Room/${room.hashCode()}", routeForLastRead = "Room/${room.hashCode()}",
onWantsToReply = { replyTo.value = it }, onWantsToReply = {
replyTo.value = it
newPostModel.originalNote = it
},
) )
} }
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, nav) { replyTo.value = null } } replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, newPostModel, nav) { replyTo.value = null } }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
// LAST ROW // LAST ROW
PrivateMessageEditFieldRow(newPostModel, isPrivate = true, accountViewModel) { PrivateMessageEditFieldRow(newPostModel, isPrivate = true, accountViewModel) {
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.deleteDraft(newPostModel.draftTag)
newPostModel.draftTag = UUID.randomUUID().toString()
val urls = findURLs(newPostModel.message.text) val urls = findURLs(newPostModel.message.text)
val usedAttachments = newPostModel.nip94attachments.filter { it.urls().intersect(urls.toSet()).isNotEmpty() } val usedAttachments = newPostModel.nip94attachments.filter { it.urls().intersect(urls.toSet()).isNotEmpty() }
@ -339,6 +366,7 @@ fun ChatroomScreen(
mentions = null, mentions = null,
wantsToMarkAsSensitive = false, wantsToMarkAsSensitive = false,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = null,
) )
} else { } else {
accountViewModel.account.sendPrivateMessage( accountViewModel.account.sendPrivateMessage(
@ -348,6 +376,7 @@ fun ChatroomScreen(
mentions = null, mentions = null,
wantsToMarkAsSensitive = false, wantsToMarkAsSensitive = false,
nip94attachments = usedAttachments, nip94attachments = usedAttachments,
draftTag = null,
) )
} }

Wyświetl plik

@ -180,6 +180,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.math.BigDecimal import java.math.BigDecimal
@Composable @Composable
@ -1245,7 +1246,7 @@ private fun WatchApp(
var appLogo by remember(baseApp) { mutableStateOf<String?>(null) } var appLogo by remember(baseApp) { mutableStateOf<String?>(null) }
LaunchedEffect(key1 = appState) { LaunchedEffect(key1 = appState) {
launch(Dispatchers.Default) { withContext(Dispatchers.Default) {
val newAppLogo = val newAppLogo =
(appState?.note?.event as? AppDefinitionEvent)?.appMetaData()?.picture?.ifBlank { null } (appState?.note?.event as? AppDefinitionEvent)?.appMetaData()?.picture?.ifBlank { null }
if (newAppLogo != appLogo) { if (newAppLogo != appLogo) {

Wyświetl plik

@ -99,6 +99,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size39Modifier
import com.vitorpamplona.amethyst.ui.theme.Size40Modifier import com.vitorpamplona.amethyst.ui.theme.Size40Modifier
import com.vitorpamplona.amethyst.ui.theme.Size40dp import com.vitorpamplona.amethyst.ui.theme.Size40dp
import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.VideoReactionColumnPadding
import com.vitorpamplona.amethyst.ui.theme.onBackgroundColorFilter import com.vitorpamplona.amethyst.ui.theme.onBackgroundColorFilter
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.events.FileHeaderEvent import com.vitorpamplona.quartz.events.FileHeaderEvent
@ -462,7 +463,7 @@ fun ReactionsColumn(
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(bottom = 75.dp, end = 10.dp), modifier = VideoReactionColumnPadding,
) { ) {
ReplyReaction( ReplyReaction(
baseNote = baseNote, baseNote = baseNote,
@ -495,7 +496,7 @@ fun ReactionsColumn(
nav = nav, nav = nav,
iconSize = Size40dp, iconSize = Size40dp,
heartSizeModifier = Size35Modifier, heartSizeModifier = Size35Modifier,
28.sp, iconFontSize = 28.sp,
) )
ZapReaction( ZapReaction(
baseNote = baseNote, baseNote = baseNote,

Wyświetl plik

@ -89,6 +89,8 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.Amethyst
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.service.PackageUtils import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.ui.MainActivity import com.vitorpamplona.amethyst.ui.MainActivity
import com.vitorpamplona.amethyst.ui.actions.LoadingAnimation import com.vitorpamplona.amethyst.ui.actions.LoadingAnimation
@ -245,7 +247,7 @@ fun LoginPage(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Image( Image(
painterResource(id = R.drawable.amethyst), imageVector = CustomHashTagIcons.Amethyst,
contentDescription = stringResource(R.string.app_logo), contentDescription = stringResource(R.string.app_logo),
modifier = Modifier.size(150.dp), modifier = Modifier.size(150.dp),
contentScale = ContentScale.Inside, contentScale = ContentScale.Inside,

Wyświetl plik

@ -54,7 +54,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
@ -66,6 +65,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.Amethyst
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.service.PackageUtils import com.vitorpamplona.amethyst.service.PackageUtils
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
@ -116,7 +117,7 @@ fun SignUpPage(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Image( Image(
painterResource(id = R.drawable.amethyst), imageVector = CustomHashTagIcons.Amethyst,
contentDescription = stringResource(R.string.app_logo), contentDescription = stringResource(R.string.app_logo),
modifier = Modifier.size(150.dp), modifier = Modifier.size(150.dp),
contentScale = ContentScale.Inside, contentScale = ContentScale.Inside,

Wyświetl plik

@ -21,6 +21,7 @@
package com.vitorpamplona.amethyst.ui.theme package com.vitorpamplona.amethyst.ui.theme
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -92,6 +93,7 @@ val Size40dp = 40.dp
val Size55dp = 55.dp val Size55dp = 55.dp
val Size75dp = 75.dp val Size75dp = 75.dp
val HalfEndPadding = Modifier.padding(end = 5.dp)
val HalfStartPadding = Modifier.padding(start = 5.dp) val HalfStartPadding = Modifier.padding(start = 5.dp)
val StdStartPadding = Modifier.padding(start = 10.dp) val StdStartPadding = Modifier.padding(start = 10.dp)
val StdTopPadding = Modifier.padding(top = 10.dp) val StdTopPadding = Modifier.padding(top = 10.dp)
@ -101,6 +103,8 @@ val HalfPadding = Modifier.padding(5.dp)
val StdPadding = Modifier.padding(10.dp) val StdPadding = Modifier.padding(10.dp)
val BigPadding = Modifier.padding(15.dp) val BigPadding = Modifier.padding(15.dp)
val RowColSpacing = Arrangement.spacedBy(3.dp)
val HalfHorzPadding = Modifier.padding(horizontal = 5.dp) val HalfHorzPadding = Modifier.padding(horizontal = 5.dp)
val HalfVertPadding = Modifier.padding(vertical = 5.dp) val HalfVertPadding = Modifier.padding(vertical = 5.dp)
@ -136,6 +140,8 @@ val ReactionRowExpandButton = Modifier.width(65.dp).padding(start = 31.dp)
val WidthAuthorPictureModifier = Modifier.width(55.dp) val WidthAuthorPictureModifier = Modifier.width(55.dp)
val WidthAuthorPictureModifierWithPadding = Modifier.width(65.dp) val WidthAuthorPictureModifierWithPadding = Modifier.width(65.dp)
val VideoReactionColumnPadding = Modifier.padding(bottom = 75.dp)
val DividerThickness = 0.25.dp val DividerThickness = 0.25.dp
val ReactionRowHeight = Modifier.height(24.dp).padding(start = 10.dp) val ReactionRowHeight = Modifier.height(24.dp).padding(start = 10.dp)
@ -223,4 +229,4 @@ val liveStreamTag =
.padding(horizontal = Size5dp) .padding(horizontal = Size5dp)
val chatAuthorImage = Modifier.size(20.dp).clip(shape = CircleShape) val chatAuthorImage = Modifier.size(20.dp).clip(shape = CircleShape)
val AuthorInfoVideoFeed = Modifier.width(75.dp) val AuthorInfoVideoFeed = Modifier.width(75.dp).padding(end = 15.dp)

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 13 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 14 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 11 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 12 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 5.5 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 15 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 7.2 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 16 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 11 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 17 KiB

Wyświetl plik

@ -1,21 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="M93.99,8.97c-21.91,0 -29.96,22.39 -29.96,22.39s-7.94,-22.39 -30,-22.39c-16.58,0 -35.48,13.14 -28.5,43.01c6.98,29.87 58.56,67.08 58.56,67.08s51.39,-37.21 58.38,-67.08c6.98,-29.87 -10.56,-43.01 -28.48,-43.01z"
android:fillColor="#424242"/>
<path
android:pathData="M30.65,11.2c17.2,0 25.74,18.49 28.5,25.98c0.39,1.07 1.88,1.1 2.33,0.06L64,31.35C60.45,20.01 50.69,8.97 34.03,8.97c-6.9,0 -14.19,2.28 -19.86,7.09c5.01,-3.29 10.88,-4.86 16.48,-4.86z"
android:fillColor="#575757"/>
<path
android:pathData="M93.99,8.97c-5.29,0 -9.77,1.54 -13.53,3.85c2.64,-1.02 5.56,-1.62 8.8,-1.62c16.21,0 30.72,12.29 24.17,40.7c-5.62,24.39 -38.46,53.98 -48.49,65.27c-0.64,0.72 -0.86,1.88 -0.86,1.88s51.39,-37.21 58.38,-67.08c6.99,-29.86 -11.89,-43 -28.47,-43z"
android:fillColor="#575757"/>
<path
android:pathData="M17.04,24.82c3.75,-4.68 10.45,-8.55 16.13,-4.09c3.07,2.41 1.73,7.35 -1.02,9.43c-4,3.04 -7.48,4.87 -9.92,9.63c-1.46,2.86 -2.34,5.99 -2.79,9.18c-0.18,1.26 -1.83,1.57 -2.45,0.46c-4.22,-7.48 -5.42,-17.78 0.05,-24.61z"
android:fillColor="#787878"/>
<path
android:pathData="M77.16,34.66c-1.76,0 -3,-1.7 -2.36,-3.34c1.19,-3.02 2.73,-5.94 4.58,-8.54c2.74,-3.84 7.95,-6.08 11.25,-3.75c3.38,2.38 2.94,7.14 0.57,9.44c-5.09,4.93 -11.51,6.19 -14.04,6.19z"
android:fillColor="#787878"/>
</vector>

Wyświetl plik

@ -1,11 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="400dp" android:viewportHeight="400" android:viewportWidth="400" android:width="400dp">
<path android:fillColor="#d6c09a" android:pathData="M248.92,2.15V25.23h25.24v71.09h-25.24l0.23,24.77 -22.16,0.01 -0.14,69.22 22.06,-0.53v45.33h74.48v24.31h24.93v24h23.39v69.24h-23.08v23.08h-24.93v23H126.2v-23H100.5V352.45H74.96V329.68H51.8V282.9H25.95V49.24h26.08V25.16H74.57V2.15Z" android:strokeColor="#d6c09a" android:strokeWidth="1.23101"/>
<path android:fillColor="#bb9366" android:pathData="M74.39,2.27L74.39,25.27L51.85,25.27L51.85,49.35L25.77,49.35l0.41,233.66L51.71,283.02C52.43,236.9 76.75,25.19 125.24,25.35L125.38,2.27ZM51.62,283v46.79h23.16v22.77L99.94,352.57L99.94,331.11L75.16,331.11v-47.89zM100.32,354.12v21.76h25.47v-21.76zM323.6,354.5v21.38h24.85v-21.38zM126.02,377.51v21.38h197.5v-21.38z" android:strokeColor="#bb9366" android:strokeWidth="1.23101"/>
<path android:fillColor="#c4a47b" android:pathData="M74.47,25.2 L125.28,25.71V49.25H100.51V213.59h24.93v47.39h48.63v24h25.7v22.93h22.93v23h125.95v23.47h-24.85v23H125.97v-23.39h-25.85V331H75.35V283.29L51.58,283.07 51.49,49.32h22.77z" android:strokeColor="#c4a47b" android:strokeWidth="1.23101"/>
<path android:fillColor="#000000" android:pathData="m25.6,120.68v18.25h9.75v10.55h8.15v9.93h10.19v7.71h67.43v-7.98h10.01v-9.84h10.19v-20.82h17.72v20.65h10.28v9.75h7.89v7.8h67.52v-7.62h9.75v-9.84h10.37v-10.37h9.57v-17.81zM178.7,128.19h9.39v10.15l10.56,0.04v10.01h9.4v-10.15h-9.32L198.73,128.19l9.61,0.04v10.1h8.81l0.05,10.23 9.22,0.05v9.57l-9.26,-0.04 0.04,-9.57h-8.91v9.22h-9.57v-9.17l-10.63,-0.09 0.05,-10.15 -9.44,-0.04zM43.41,129.54h9.39v10.15l10.56,0.04v10.01h9.4L72.76,139.59h-9.32v-10.05l9.61,0.04v10.1h8.81l0.05,10.23 9.22,0.05v9.57l-9.26,-0.04 0.04,-9.57h-8.91v9.22h-9.57v-9.17l-10.63,-0.09 0.05,-10.15 -9.44,-0.04z" android:strokeColor="#00000000" android:strokeWidth="1.23101"/>
</vector>

Wyświetl plik

@ -1,29 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="30dp" android:viewportHeight="512" android:viewportWidth="512" android:width="30dp">
<path android:fillColor="#00ffff" android:pathData="m204.58,84.84c1.81,1.81 0.93,0.93 0,0zM366.27,85.89c1.81,1.81 0.93,0.93 0,0z" android:strokeWidth="1.04994"/>
<path android:fillColor="#e0e0e0" android:pathData="M195.83,118.87C160.28,121.55 58.06,148.41 62.84,207.68c0.81,23.29 2.03,46.55 5.06,69.67C71.12,304.53 75.5,331.75 84.25,357.83 99.45,396.09 133.39,425.8 173.08,436.37c40.81,11.15 76.45,13.42 125.26,-1.3 37.88,-10.35 71.39,-38.36 83.88,-76.19 3.45,-9.2 5.45,-18.7 7.15,-28.35 20.03,1.02 40.62,-1.27 59.85,-7.38 27.45,-9.62 55.11,-30.92 57.75,-61.92 2.01,-19.22 -3.32,-39.88 -18.9,-52.41C470.37,192.65 445.5,189.27 422.47,190.88c-5.92,-1.92 -19.27,4.39 -19.71,-4.26 -21.54,-42.19 -74.52,-63.24 -116.57,-67.4 -15.34,-1.4 -54.8,-3.05 -90.36,-0.36zM258.21,145.74c35.71,4.41 74.76,9.19 102.82,33.63 12.65,10.58 23.31,29.73 12.25,45.12 -18.88,25.81 -51.74,35.57 -81.55,42.38 -31.35,6.81 -63.84,5.8 -95.54,2.68 -33.37,-5.07 -69.43,-11.31 -95.46,-34.59C90.48,225.01 85.35,208.69 94.1,196.13 109.59,170.88 139.79,160.48 166.78,152.36 177.5,149.63 188.33,146.97 199.33,145.74m229.72,86.97c8.71,0.05 17.28,0.93 25.22,4.74 16.86,8.49 9.47,33.24 -5.05,40.17 -16.12,8.15 -34.77,10.16 -52.5,11.96 1.83,-18.91 4.28,-37.82 6.3,-56.7 8.48,0.54 17.32,-0.23 26.03,-0.17z"/>
<path android:fillColor="#6d4b41" android:pathData="M90.72,207.67a141.92,61.23 0,1 0,283.84 0a141.92,61.23 0,1 0,-283.84 0z" android:strokeColor="#6d4b41" android:strokeWidth="8.81928"/>
<path android:fillColor="#b59075" android:pathData="m251.83,158.34c-37.4,0.76 -63.37,0.1 -100.79,11.35 -16.24,6.8 -36.12,14.4 -42.83,32.06 4.78,30.85 60.55,22.12 56.07,2.79 -4.14,-14.16 14.98,-19.74 25.61,-15.9 21.73,3.91 40.06,18.16 61.95,21.12 8.81,1.94 20.57,-2.79 17.76,-13.62 -3.87,-6.98 0.16,-14.74 8.49,-14.61 25.36,-1.83 47.16,13.81 70.35,21.12 7.05,3.96 15.78,-3.15 8.55,-9.65 -28.17,-23.15 -72.37,-35.31 -105.14,-34.65z" android:strokeWidth="1.04994"/>
<path android:fillColor="#b59074" android:pathData="m293.92,199.81c-6.74,4.63 0.26,16.2 -8.58,20.25 -16.21,10.23 -35.7,0.44 -52.4,-3.62 -14.16,-3.75 -29.52,-10.91 -44.1,-6.12 -10.46,5.46 -3.97,21.89 7.35,19.42 7.85,-1.08 15.55,-2.72 23.1,1.05 22.27,6.96 45.97,11.51 69.3,8.72 10.75,-2.04 15.9,-12.26 24.15,-17.82 10.27,-2.43 22.45,12.8 30.51,1.75 3.64,-11.74 -12.07,-16.18 -20.32,-19.7 -9.31,-3.26 -19.11,-5.82 -29,-3.92z" android:strokeWidth="1.04994"/>
<path android:fillColor="#6aa5ac" android:pathData="m403.02,222.38c-0.03,0.81 0.01,9.73 0.05,10.48 34.64,-0.06 53.3,2.38 65.08,16.87 4.08,5.36 7.47,10.62 10.15,8.41 -1.56,-19.68 -20.18,-34.58 -36.44,-36.16 -12.8,-1.15 -26.08,-1.13 -38.85,0.41z" android:strokeWidth="1.04994"/>
<path android:fillColor="#bbced3" android:pathData="m460.31,242.29c10.12,17.21 -6.22,36.21 -22.95,40.03 -13.31,3.43 -26.93,6.24 -40.63,7.26 -1.51,4.61 -7.2,17.18 1.16,15.75 18.92,-0.45 38.87,-2.29 55.71,-11.66 13.42,-7.05 22.47,-20.88 24.65,-35.78 -5.45,2.16 -11.7,-14.71 -17.94,-15.61z" android:strokeWidth="1.04994"/>
<path android:fillColor="#97827b" android:pathData="m113.24,244.43c1.81,1.81 0.93,0.93 0,0zM350.52,244.43c1.81,1.81 0.93,0.93 0,0z" android:strokeWidth="1.04994"/>
<path android:fillColor="#a79691" android:pathData="m345.28,247.58c1.81,1.81 0.93,0.93 0,0zM120.59,248.63c1.81,1.81 0.93,0.93 0,0z" android:strokeWidth="1.04994"/>
<path android:fillColor="#bbced3" android:pathData="m70.19,296.93c0.63,13.99 -1.65,28.32 2.1,42 -28.14,7.44 -58.32,24.8 -66.82,54.6 -8.2,25.34 9.63,50 29.11,64.51 42.76,32.57 96.75,46.56 149.39,52.05 25.57,3.02 51.57,2.3 77.31,1.67 57.38,-3.76 116.7,-14.92 165.89,-46.49 24.11,-15.17 48.19,-40.13 45.79,-70.7 -3.39,-27.59 -31.45,-41.66 -55.24,-49 -6.86,-2.02 -13.84,-4.05 -21,-4.55 2.55,-12.39 4.11,-10.88 -7.59,-11.3 -3.15,19.86 -11.24,41.84 -22.36,58.55 -9.33,27.17 -32.88,46.95 -58.24,58.8 41.17,-5.65 76.47,-60.67 84,-91.35 21.08,4.35 45.07,10.03 58.39,28.35 9.97,15.41 -3.74,32.74 -13.88,44.07 -102.21,85.13 -293.12,73.31 -394.85,9.37 -11.24,-12.66 -26.76,-34.25 -13.84,-51.49 11.01,-15.95 29.05,-25.58 47.1,-31.34 12.87,37.17 39.6,70.25 75.07,87.9 2.31,-2 -10.94,-7.59 -14.17,-11.11C123.07,420.24 108.45,408.22 102.36,391.48 104.48,388.76 94.88,380.02 91.98,372.52 78.86,349.74 75.03,323.23 70.95,297.75Z" android:strokeWidth="1.04994"/>
<path android:fillColor="#e0e0e0" android:pathData="m392.52,355.73c-11.61,47 -52.91,84.19 -99.67,96.08 -25.96,8.69 -52.52,9.95 -79.6,8.14 -28.82,-2.72 -56.32,-11.95 -80.06,-28.48 -26.74,-18.75 -46.22,-46.56 -57.75,-76.79 -21.27,6.03 -44.59,18.66 -52.06,40.95 -4.03,54.61 91.6,82.66 133.95,89.65 55.07,8.77 123.34,7.5 172.19,-3.47 36.3,-7.73 158.11,-59.91 118.33,-103.03 -14.75,-13.87 -35.78,-19.85 -55.33,-23.05z" android:strokeWidth="1.04994"/>
<path android:fillColor="#6aa5ac" android:pathData="m366.72,388.63c-25.24,35.36 -71.86,51.22 -113.53,54.89 -24.65,3.21 -48.92,0.37 -73.1,-5.06 -29.29,-7.57 -59.67,-27.71 -79.05,-51.06 20.56,60.68 97.11,78.57 150.78,73.33 45.36,-4.71 103.34,-25.75 114.89,-72.09z" android:strokeWidth="1.04994"/>
<path android:fillAlpha="0.632035" android:fillColor="#b9cdd5" android:pathData="m335.91,14.7c6.08,8.5 9.15,22.2 -1.52,28.6 -15.58,5.87 -32.81,4.14 -49.14,6.08 -29.97,2.84 -64.82,9.68 -81.49,37.77 -5.63,8.93 -7.22,19.09 -8.77,29.39 -0.01,0 -0.03,0 -0.04,0.01 -0.05,15.85 2.98,29.87 9.47,43.37l-0.15,0c8.96,13.26 19.47,29.83 35.83,35.99 11.44,2.56 10.87,-12.15 10.96,-20.16 -0.35,-14.02 1.13,-23.58 8.29,-32.41 -0,-0 -1.71,3.22 -0,0 1.71,-3.22 6.5,-8.89 11.21,-13.75 4.71,-4.86 13.22,-8.82 20.48,-11.6 7.26,-2.78 72.31,-24.48 85.15,-42.38C390.23,49.26 375.54,12.28 348.25,1.22 338.86,-2.77 332.82,9.41 335.91,14.7Z" android:strokeWidth="1.04994"/>
</vector>

Wyświetl plik

@ -1,5 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="30dp" android:viewportHeight="236" android:viewportWidth="236" android:width="30dp">
<path android:fillColor="#e102c2" android:pathData="M172.02,18.47 L184.05,17.34C183.46,10.98 181.09,5.5 177.47,0.07M192.47,156.68c15.59,0.84 18.54,6.44 27.81,-9.06 8.36,-13.98 2.99,-28.3 6.5,-43.05 1.28,-5.38 3.72,-10.25 4.06,-15.86 0.33,-5.42 -1.49,-10.52 -2.09,-15.86 -0.56,-5.04 -0.38,-10.68 -5.27,-14.04 -5.44,-3.73 -9.84,1.11 -10.44,6.11 -0.58,4.87 0.23,9.84 -0.26,14.73 -0.42,4.27 -1.94,8.12 -2.05,12.46 -0.08,3.44 -1.44,9 -6.24,9 -8.64,0 -6.69,-13.22 -7.85,-18.06 -2.12,-8.86 -5.55,-16.83 -6.37,-26.06 -0.61,-6.81 1.68,-13.51 0.77,-20.39 -0.62,-4.66 -2.98,-11.24 -8.25,-12.86 -7.27,-2.23 -10.64,5.21 -10.75,10.6 -0.12,5.82 2.06,11.23 2.34,16.99 0.45,9.25 1.18,18.81 1.32,28 0.05,3.17 -1.3,6.19 -1.1,9.39 0.3,4.76 7.3,11.04 3.84,15.45 -4.18,5.32 -10.2,-0.54 -12.8,-4.12 -5.16,-7.1 -8.58,-15.32 -13.3,-22.63 -2.22,-3.44 -5.69,-6.28 -10.26,-5.17 -12.21,2.95 -2.34,18.13 1.65,23.28 10.47,13.53 19.59,27.62 30.78,40.78 6.23,7.32 15.1,11.08 17.96,20.39m25.26,-125.75c1.05,7.34 2.41,14.05 2.41,21.52l9.62,3.4c-0.44,-9.51 -3.84,-18.97 -12.03,-24.92m-80.59,15.86c-4.55,7.61 -6.27,16.45 -3.61,24.92 3.23,-1.54 6.07,-2.76 9.62,-3.4 -1.06,-6.79 -3.05,-15.3 -6.01,-21.52m-78.18,1.13c-1.52,6.9 -3.73,13.68 -6.01,20.39L66.18,69.45C63.78,62.51 62.59,54.31 58.96,47.92M45.73,207.66c2.62,-8.55 8.78,-9.62 13.92,-15.98 8.24,-10.19 17.12,-20.09 25,-30.46 3.56,-4.69 6.04,-10.01 9.62,-14.73 3.92,-5.15 14.26,-20.37 1.9,-23.28 -4.61,-1.08 -8.06,1.69 -10.32,5.17 -4.74,7.29 -8.19,15.57 -13.31,22.63 -2.52,3.48 -7.67,8.82 -11.94,4.3 -4.31,-4.56 2.59,-10.65 3.01,-15.63 0.28,-3.28 -1.02,-6.31 -1.07,-9.54 -0.18,-12.86 1.34,-26.46 3.26,-39.17 0.92,-6.05 -0.09,-19.43 -10.41,-16.26 -5.27,1.62 -7.63,8.2 -8.25,12.86 -0.81,6.12 1.07,12.08 0.59,18.13 -0.8,10.11 -4.17,18.64 -6.36,28.32 -1.11,4.9 1.13,17.89 -7.69,17.89 -5.48,0 -6.35,-6.21 -6.36,-9.96 -0.01,-4.02 -1.95,-7.4 -2.29,-11.33 -0.41,-4.87 0.61,-9.83 0.15,-14.73 -0.44,-4.69 -4.81,-9.94 -10.29,-6.76 -5.15,2.99 -4.94,9.81 -5.48,14.69 -0.55,4.94 -2.24,9.71 -2.14,14.73 0.12,5.62 2.27,10.53 3.8,15.86 4.38,15.24 -1.81,29.59 7.01,44.18 2.41,3.99 5.78,9.18 10.77,10.54 4.79,1.31 11.71,-1.44 16.84,-1.48M19.27,81.91C12.51,89.01 8.66,97.25 8.44,106.83c3.19,-1.41 6.2,-2.59 9.62,-3.4 0,-6.5 3.11,-15.61 1.2,-21.52m80.59,15.86c-0.33,7.13 -3.12,13.51 -4.81,20.39 3.41,1.23 6.45,2.82 9.62,4.53 2.55,-8.11 1.77,-18.72 -4.81,-24.92m92.75,69.95c-12.85,5.17 -0.98,22.19 10.58,17.44 14.95,-6.13 2.9,-22.87 -10.58,-17.44m-9.75,20.68c0,7.66 -0.57,15.04 -1.2,22.66 5.29,-5.31 10,-12.13 14.43,-18.13 -4.68,-1.02 -8.89,-2.61 -13.23,-4.53M34.91,218.46c-13.57,3.16 -4.32,20.77 7.21,17.99 7.88,-1.9 12.63,-11.14 5.51,-16.78 -3.21,-2.54 -8.91,-2.1 -12.72,-1.21" android:strokeWidth="1.16731"/>
</vector>

Wyświetl plik

@ -1,19 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="m480,190.27c-60.64,0 -115.3,16.8 -162.53,49.12l36.21,36.52c37.13,-23.2 80.03,-35.1 126.94,-35.1 66.3,0 122.62,23.21 168.98,69.61 46.37,46.4 69.57,102.76 69.57,169.06 0,47.69 -16.31,88.53 -40.31,126.09l36.29,36.64c28.23,-40.58 48.88,-84.84 53.2,-136.95L917.19,505.27v-50.55L768.36,454.73C762.19,380.26 731.62,317.56 676.64,266.64 621.67,215.72 556.12,190.27 480,190.27ZM282.81,267.38c-54.53,50.8 -85.03,113.2 -91.17,187.34L42.81,454.73v50.55h148.83c6.17,74.46 36.74,137.17 91.72,188.09 54.98,50.92 120.52,76.37 196.64,76.37 76.12,0 141.67,-25.45 196.64,-76.37 5.56,-5.15 7.91,-11.84 12.97,-17.23l-34.77,-34.92c-2.23,2.42 -2.92,5.48 -5.27,7.85 -46.4,46.73 -102.76,70.12 -169.06,70.12 -66.3,0 -122.84,-23.39 -169.57,-70.16 -46.73,-46.77 -70.12,-103.34 -70.12,-169.65 0,-66.3 23.39,-122.62 70.16,-168.98 2.64,-2.62 6.05,-3.43 8.75,-5.9zM479.57,288.4c-23.2,0 -42.85,8.47 -58.91,25.43 -5.41,5.71 -8.56,12.32 -12.15,18.75l25.59,25.86c2.44,-7.74 2.96,-16.25 8.87,-22.58 10.05,-10.77 22.37,-16.17 36.95,-16.17 14.58,0 26.92,5.4 37.03,16.17 10.11,10.77 15.16,23.58 15.16,38.44v42.7h-40l115.2,116.33v-75.7c0,-11.45 -3.89,-21.1 -11.68,-28.91 -7.79,-7.81 -17.43,-11.72 -28.95,-11.72h-3.28v-41.41c0,-23.54 -7.99,-43.96 -23.98,-61.25 -15.99,-17.29 -35.94,-25.94 -59.84,-25.94zM396.6,381.72v35.27h-3.28c-11.56,0 -21.13,3.89 -28.75,11.64 -7.62,7.75 -11.45,17.34 -11.45,28.79v128.95c0,11.45 3.87,21.03 11.56,28.71 7.7,7.68 17.3,11.52 28.83,11.52h173.01c11.53,0 21.2,-3.83 29.02,-11.45 6.49,-6.32 8.66,-14.76 9.77,-23.71L431.68,416.99h-3.79v-3.83zM480,489.41c9.09,0 16.77,3.18 23.09,9.49 6.31,6.31 9.49,14 9.49,23.09 0,9.09 -3.18,16.81 -9.49,23.13 -6.31,6.31 -14,9.45 -23.09,9.45 -9.09,0 -16.77,-3.14 -23.09,-9.45 -6.31,-6.31 -9.49,-14.04 -9.49,-23.13 0,-9.09 3.18,-16.77 9.49,-23.09 6.31,-6.31 14,-9.49 23.09,-9.49z"
android:strokeWidth="1.11437"/>
<path
android:pathData="m130.61,152.81 l657.62,662.75"
android:strokeWidth="57.2302"
android:fillColor="#000000"
android:strokeColor="#000000"/>
<path
android:pathData="m103.8,46.95 l792.46,796.27"
android:strokeWidth="57.2302"
android:fillColor="#ffffff"/>
</vector>

Wyświetl plik

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="m480,769.74q-114.18,0 -196.64,-76.38 -82.46,-76.38 -91.72,-188.07L42.82,505.29v-50.57L191.64,454.71q9.26,-111.69 91.72,-188.07 82.46,-76.38 196.64,-76.38 114.18,0 196.64,76.38 82.46,76.38 91.72,188.07h148.81v50.57L768.36,505.29q-9.26,111.69 -91.72,188.07 -82.46,76.38 -196.64,76.38zM480.49,719.16q99.46,0 169.06,-70.1 69.6,-70.1 69.6,-169.56 0,-99.46 -69.55,-169.06 -69.55,-69.6 -169,-69.6 -99.46,0 -169.61,69.55 -70.16,69.55 -70.16,169 0,99.46 70.1,169.61 70.1,70.16 169.56,70.16zM393.51,626.58h173.03q17.29,0 29.02,-11.42 11.73,-11.42 11.73,-28.6v-128.96q0,-17.18 -11.68,-28.89 -11.68,-11.71 -28.95,-11.71h-3.26v-41.4q0,-35.3 -23.99,-61.24 -23.99,-25.94 -59.85,-25.94 -34.8,0 -58.89,25.43 -24.09,25.43 -24.09,60.46v42.69h-3.26q-17.33,0 -28.77,11.62 -11.43,11.62 -11.43,28.8v128.96q0,17.18 11.54,28.7 11.54,11.52 28.84,11.52zM480,554.58q-13.63,0 -23.1,-9.47 -9.47,-9.47 -9.47,-23.1 0,-13.63 9.47,-23.1 9.47,-9.47 23.1,-9.47 13.63,0 23.1,9.47 9.47,9.47 9.47,23.1 0,13.63 -9.47,23.1 -9.47,9.47 -23.1,9.47zM427.88,416.99v-42.69q0,-22.29 15.08,-38.45 15.08,-16.16 36.95,-16.16 21.88,0 37.04,16.16 15.17,16.16 15.17,38.45v42.69zM480,522z"
android:strokeWidth="1.11437"/>
</vector>

Wyświetl plik

@ -1,31 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="30dp" android:viewportHeight="128" android:viewportWidth="128" android:width="30dp">
<path android:fillColor="#6200ee" android:pathData="M9.22,0.49C32.03,17.55 41.73,30.89 55.97,46.5 58.13,41.35 55.87,32.95 54.17,27.76 47.61,7.76 28.73,0.5 9.22,0.49Z" android:strokeWidth="1.23984"/>
<path android:fillColor="#6200ee" android:pathData="M71.43,71.77C80.15,58.93 119.83,33.38 120.81,24.04 99.67,24.48 79.22,31.77 72.71,53.8c-1.57,5.31 -1.28,12.49 -1.28,17.98z" android:strokeWidth="1.23984"/>
<path android:fillColor="#3700b3" android:pathData="M106.9,34.15C85.73,55.38 83.29,51.88 72.93,73.42 99.01,72.3 124.1,52.45 120.96,24.2c-6.39,2.87 -10.26,5.06 -14.06,9.95z" android:strokeWidth="1.23984"/>
<path android:fillColor="#3700b3" android:pathData="M8.75,0.49C9.99,16.18 11.87,33.64 26.58,42.19c8.31,4.83 18,6.14 27.28,7.89C51.37,34.85 52.38,36.2 23.79,11.48 19.47,7.83 15.87,4.35 8.75,0.49Z" android:strokeWidth="1.23984"/>
<path android:fillColor="#818181" android:pathData="m32.78,4.21 l1.24,1.24z" android:strokeWidth="1.23984"/>
<path android:fillColor="#35b458" android:pathData="m21.62,10.4c1.73,1.78 2.77,2.54 4.96,3.72 -3,0.9 -5.54,1.18 -8.68,1.24v3.72c12.33,0 18.72,3.25 26.04,13.64h-8.68v3.72c3.97,0 8.64,-0.58 11.99,1.99 5.09,3.9 6.28,10.83 7.86,16.61 4.07,14.86 6.19,30.48 6.19,45.87 0,7.1 -12.14,35.85 4.96,24.8 2.2,-11.69 -0.79,-24.1 -0.55,-34.72 3.59,-12.15 10.48,-24.1 19.15,-30.58 4.71,-1.59 11.08,2.02 12.4,-4.13L84.85,57.52C92.59,48.01 98.34,42.67 110.89,42.64v-2.48h-8.68l4.96,-6.2C99.44,34.3 94.62,42.1 88.57,46.36 88.31,42.96 88.2,42.12 84.85,41.4 84.47,54.13 72.01,71.54 63.78,79.84 63.68,68.4 61.36,55.48 56.36,45.12 53.38,38.94 48.97,33.72 45.69,27.76c-1.76,-3.21 -2.34,-6.79 -4.23,-9.92 -0.85,1.55 -0.93,1.92 -1.24,3.72C34.74,17.12 29,10.14 21.62,10.4Z" android:strokeWidth="1.23984"/>
<path android:fillColor="#818181" android:pathData="m42.7,10.4 l1.24,1.24z" android:strokeWidth="1.23984"/>
<path android:fillColor="#818181" android:pathData="m103.45,25.28 l1.24,1.24z" android:strokeWidth="1.23984"/>
<path android:fillColor="#01ff01" android:pathData="m12.94,27.76 l1.24,1.24 -1.24,-1.24m76.87,2.48 l1.24,1.24z" android:strokeWidth="1.23984"/>
<path android:fillColor="#818181" android:pathData="m73.7,48.84 l1.24,1.24z" android:strokeWidth="1.23984"/>
<path android:fillColor="#f99721" android:pathData="m0.08,127.88c9.29,0 23.31,0 33.06,-0.19 18.28,-0.22 37.95,-11.49 49.61,-18.06 -6.53,-6.66 -21.68,-9.69 -28.93,-6.42 -6.34,4.41 -16.53,6.01 -23.4,9.19 -10.62,8.43 -25.2,8.66 -30.33,15.49z" android:strokeWidth="1.18196"/>
<path android:fillColor="#857f2d" android:pathData="m61.97,101.52 l1.01,1.01z" android:strokeWidth="1.01399"/>
<path android:fillColor="#ffff01" android:pathData="m51.83,105.57 l1.01,1.01 -1.01,-1.01m23.32,0 l1.01,1.01z" android:strokeWidth="1.01399"/>
<path android:fillColor="#df7f07" android:pathData="m31.33,127.88h96.76c-5.65,-7.8 -12.98,-6.4 -22.04,-10.16 -9.52,-3.96 -14.56,-9.59 -27.04,-7.55 -9.57,1.56 -14.28,7.56 -22.67,10.01 -9.68,2.83 -17.4,1.08 -25,7.71z" android:strokeWidth="1.19243"/>
</vector>

Wyświetl plik

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="512dp" android:viewportHeight="512" android:viewportWidth="512" android:width="512dp">
<path android:fillColor="#feb804" android:pathData="M405.81,0.32C398.49,10.85 392.37,18.66 387.21,28.1 347.37,84.64 306.07,140.12 265.2,195.92c-6.72,6.21 -2.23,18.18 7.3,15.63 15.68,3.42 21.45,-10.42 21.45,-10.42 0,0 77.89,-124.01 115.84,-186.59 2.59,-5.52 4.24,-14.8 -3.99,-14.23z" android:strokeWidth="1.04238"/>
<path android:fillColor="#ffc927" android:pathData="m134.11,269.93 l84.15,-1.04 23.28,8.34 -22.14,38.79 -109.77,188.45 3.59,0.32 279.74,-251.78 45.05,-42.48 -136.78,0.48 -35.28,-0.67L406.13,0.17c0,0 -223.08,181.66 -329.74,270.15l-1.05,0.84z" android:strokeWidth="1.04238"/>
<path android:fillColor="#feb804" android:pathData="m109.66,504.46c0.64,10.48 14.14,7.32 18.78,1.43 110.11,-98.52 227.42,-195.83 322.37,-283.08 2.86,-9.82 -3.79,-12.45 -12.85,-12.17 -78.5,71.81 -160.72,147.93 -240.44,218.41 -26.97,23.78 -53.64,47.9 -80.56,71.73 -2.16,1.7 -4.6,3.11 -7.3,3.68zM233.74,290.74c6.73,-10.68 15.61,-23.14 -0.04,-21.83 -52.45,-0 -100.96,0.79 -149.97,2.26 -7.99,-0.01 -8.92,-2.35 -12.91,9.06 -4.91,14.03 13.18,11.66 21.97,11.6 42.7,-0.17 85.45,0.63 128.07,-1.04 5,-0.01 7.71,-0.11 12.88,-0.04z" android:strokeWidth="1.04238"/>
<path android:fillColor="#ffe567" android:pathData="m296,97.74c-8.58,4.87 -15.26,12.45 -23,18.53 -35.76,30.9 -71.36,61.98 -107.63,92.28C151.57,220.67 137.06,232.03 124.04,245c-4.43,3.73 -6.85,10.69 -2.84,15.61 5.44,7.37 15.93,3.73 21.79,-1.14 10.01,-8.23 19.2,-17.38 28.7,-26.18 10.02,-9.86 19.61,-20.18 30.3,-29.34 9.8,-9.67 19.3,-19.67 29.71,-28.7 9.65,-9.6 19.13,-19.36 29.35,-28.35 10.46,-10.35 20.91,-20.72 30.73,-31.68 3.95,-4.61 10.41,-8.49 10.76,-15.09 -0.53,-3.16 -4.13,-3.24 -6.55,-2.4z" android:strokeWidth="1"/>
<path android:fillColor="#ffd84b" android:pathData="m265,273.67c-10.03,4.07 -14.76,14.57 -20.73,22.92 -7.91,12 -15.59,24.15 -23.69,36.03 -6.85,10.4 -13.5,20.93 -20.45,31.26 -7.07,11.27 -14.61,22.23 -21.71,33.48 -4.09,6.76 -9.12,13.12 -11.75,20.64 -1.05,3.04 1.15,7.25 4.72,6.31 5.83,-1.77 8.7,-7.81 12.38,-12.19 29.29,-39.13 58.73,-78.14 87.92,-117.34 3.73,-5 6.11,-12.68 2.56,-18.38 -2.25,-2.58 -5.96,-3.68 -9.26,-2.73z" android:strokeWidth="1"/>
<path android:fillColor="#ffd84b" android:pathData="M276,279L276,285L276.58,283.92L276.63,283.5L276.81,282.74L276.81,281.26L276.63,280.5L276.58,280.08L276,279Z" android:strokeWidth="1"/>
</vector>

Wyświetl plik

@ -1,11 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="30dp" android:viewportHeight="512" android:viewportWidth="512" android:width="30dp">
<path android:fillColor="#226699" android:pathData="m240.08,212.39c36.87,-40.18 42.78,-59.05 41.13,-100.9C277,50.2 219.66,-13.1 154.47,3.27 98.99,29.17 78.41,76.67 87.06,130.37c3.33,19.78 11.27,38.92 23.31,55 3.8,5.07 7.79,10.56 13.1,14.15 29.58,11.55 63.27,28.18 92,32.55 49.4,5.06 16.32,4.07 24.6,-19.68z" android:strokeWidth="1"/>
<path android:fillColor="#55acee" android:pathData="m267.47,229.37c-25.72,6.13 -53.18,4.36 -76,-3.34 -20.82,-7.2 -41.71,-15.31 -62,-23.89 -13.66,-5.78 -26.84,-12.79 -42,-12.77 -10.84,0.01 -25.74,2.17 -33.79,10.21 -12.71,12.72 -10.63,39.82 0.12,52.79 8,9.65 20.69,14.76 31.67,20.25 23.9,11.95 48.7,21.9 73,32.98 10.32,4.71 26.02,8.83 33.39,17.87 8.39,10.3 7.94,31.97 8.2,44.72 9.82,0 21.75,-2.39 31.41,-4.33 25.64,-5.16 48.79,-18.57 71,-31.89 19.64,-11.78 43.51,-31.47 68,-22.64 21.49,7.75 29.19,33.23 20.1,53.04 -4.48,9.75 -12.74,16.53 -21.1,22.87 -47.95,36.4 -106.39,61.13 -167,61.13v44c0.57,13.76 -3.29,20.25 13,21.83 77.7,0.66 162.39,0.17 231,0.17 8.37,0 21.25,2.25 22.81,-9 2.18,-15.74 0.19,-33.11 0.19,-49 -0.45,-63.01 -2.27,-108.37 -12.6,-160 -2.13,-10.58 -4.93,-21.42 -13.44,-28.85 -6.41,-5.6 -18.73,2.11 -25.96,4.1 -19.39,5.35 -53.74,8.08 -62.79,-15.26 -9.33,-24.05 13.94,-39.8 28.79,-54.04 33.42,-27.88 43.86,-89.36 34.58,-125.96 -19.6,-76.14 -102.29,-105.04 -163.01,-34 -2.71,5.55 4.59,12.39 7.12,17 7.8,14.19 12.88,29.08 15.7,45 4.02,22.71 0.21,46.9 -8.81,68 -1.2,8.8 -13.79,19.12 -14.67,26 -0.54,5.91 8.62,9.85 11.49,14.09 3.23,4.77 1.6,13.38 1.6,18.91z" android:strokeWidth="1"/>
<path android:fillColor="#226699" android:pathData="m359.66,263.19c19.06,20.66 79.63,9.79 95.85,-13.82 8.68,-13.52 9.7,-39.1 -3.13,-50.67 -38.38,-27.49 -128.22,26.09 -92.72,64.49z" android:strokeWidth="1"/>
<path android:fillColor="#226699" android:pathData="m202.93,505.36c0.59,-18.53 -1.14,-37.92 -0.75,-57.16 14.33,0 28.11,-2.78 42.29,-5.14 44.72,-7.45 88.98,-29.99 125,-57.05 8.09,-6.07 16.01,-12.4 20.62,-21.63 9.25,-18.5 3.95,-45.81 -16.62,-54.07 -20,-8.03 -39.1,1.93 -56,12.07 -23.17,13.9 -46.41,28.64 -72,37.69 -10.64,2.62 -32.58,8.46 -41.85,4.71 -3.52,-16.69 -3.3,-31.8 -11.76,-42.18 -24.67,-17.17 -70.54,-35.84 -115.39,-54.99 -2.59,-1.37 -5.91,-4.18 -9,-3.97 -4.75,0.33 -8.88,7.11 -11.07,10.75 -22.39,67.4 -18.92,158.86 -18.93,219 0.22,13.62 -0.39,18.98 15,19h30c23.68,-4.03 130.22,11.25 120.46,-7.01z" android:strokeWidth="1"/>
</vector>

Wyświetl plik

@ -1,63 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="30dp" android:viewportHeight="521" android:viewportWidth="521" android:width="30dp">
<path android:fillColor="#100f0f" android:pathData="m166.04,80.02c-17.59,-6.8 -44.53,4.02 -36.94,26.7 2.1,23.63 5.97,47.17 3.47,70.99 -2.74,24.02 -32.14,35.56 -36.13,61.12 -17.98,47.59 -10.44,101.14 7.34,147.59 -5.49,19.93 -10.79,48.41 11.27,61.19 17.73,13.08 40.75,11.29 60.41,18.04 20.5,12.32 -10.44,42.99 15.69,51.95 18.1,2.85 17.83,3.66 56.46,3.83 23.29,0.37 51.14,0.26 66.03,-3.18 17.85,-3.74 39.3,-7.9 29.23,-32.48 0.75,-28.57 30.29,-42.62 54.42,-48.44 24.04,-0.98 29.12,-26.79 19.49,-44.7 -5.32,-21.48 6.12,-42.36 4.25,-64.15 9.22,-22.32 5.23,-47.01 3.79,-70.4 -3.12,-31.07 -19.99,-60.88 -47.91,-76.09 -19.16,-14.77 -41.79,-26.32 -51.95,-49.92 -13.21,-19.23 -10.24,-46.18 -25.23,-63.73 -12.88,-9.26 -34.33,6.8 -32.65,-16.3 -4.24,-18.5 -22.62,-63.83 -43.89,-35.8 -0.8,10.21 7,46.6 -3.09,20.07 -8.91,-17.61 -6.24,-23.9 -23.01,-35.87 -33.29,-3.67 -17.66,22.16 -29.25,36.91 -11.2,9.78 -1.8,29.63 -1.78,42.68z" android:strokeWidth="1.04573"/>
<path android:fillColor="#29b34a" android:pathData="m197.42,67.47c10.4,-9.94 32.5,-7.13 19.03,-25.22 -10.23,-16.23 -7.15,-34.88 -28.12,-37.02 -13.71,16.67 -8.26,27.41 3.86,41.46 2.33,6.77 3.64,13.83 5.23,20.79z" android:strokeWidth="1.04573"/>
<path android:fillColor="#136c37" android:pathData="m253.88,115.57c2.51,-17.6 -3.28,-35.98 9.78,-50.51 -6.68,-17 -8.37,-38.33 -21.78,-51.31 -23.22,-3.06 -6.87,32.18 -7.34,44.92 15.5,13.03 12.4,35.88 18.82,53.61z" android:strokeWidth="1.04573"/>
<path android:fillColor="#136c37" android:pathData="m169.18,49.39c-0.97,1.1 -1.7,6.81 6.67,43.02 6.06,18.19 12.64,46.96 24.45,57.3 2.53,-36.48 -3.51,-73.18 -18.6,-106.12 -2.68,-5.86 -9.24,2.22 -12.52,5.79z" android:strokeWidth="1.04573"/>
<path android:fillColor="#29b34a" android:pathData="m204.74,104.07c0.62,-7.84 3.93,-37.85 6.9,-19.43 -3.32,23.59 -5.05,47.14 -4.77,71.23 -0.84,28.44 -19.72,-11.42 -22.99,-22.25 -10.17,-15.42 -5.61,-50.82 -31.3,-48.37 -28.19,-1.43 -14.52,32.27 -14.95,49.15 3.38,16.6 -2.99,44.2 2.46,54.01 15.8,-3.46 -17.14,24.03 -21.74,34.01 -27.95,42.53 -22.51,97.34 -10.09,144.23 1.34,14.76 3.43,18.52 17.3,14.78 -10.15,11.19 -29.78,28.99 -13.96,47.86 14.78,25.27 46.31,12.63 66.71,26.55 16.96,5.18 5.17,30.14 22.72,23.09 9.8,7.16 9.21,22.01 19.43,5.38 19.77,-21.95 28.47,35.56 35.96,6.99 4.72,-20.5 27.27,-14.18 31.97,2.83 3.48,-14.21 17.35,-16.83 26.14,-5.23 9.61,-16.1 27.49,-17.18 35.9,-35.21 12.96,-16.26 34.62,-16.63 51.52,-25.79 17.62,-15.14 3.57,-40.19 -5.85,-56.12 17.86,12.19 9.98,-26.69 16.12,-38.69 7.23,-36.19 12.77,-76.04 -5.91,-109.9 -14.87,-32.02 -48.57,-51.65 -82.98,-54.86 -28.39,-9.94 30.2,-0.92 8.31,-16.56 -19.66,-20.98 -23.94,-50.27 -32.65,-76.3 -11.31,-10.06 -41.45,-4.62 -30.09,9.78 -0.12,11.71 -7.06,27.87 -5.35,6.94 1.89,-16.45 -3.85,-11.1 -1.64,1.76 -0.07,15.92 3.32,46.99 -3.51,53.77 -11.54,-23.03 -15.18,-49.22 -20.73,-74.16 -11.24,-22.76 -44.57,-8.54 -33.97,21.59 0.54,2.96 0.77,5.94 1.02,8.93z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m141.99,137.53c5.43,-6.56 6.77,-44.71 -3.76,-38.14 -0.11,12.72 4.24,25.29 3.76,38.14z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m190.1,178.76c-23.35,4.43 -48.58,19.13 -56.06,42.87 -2.02,30.08 23.87,1.52 32.26,-8.59 9.02,-13.1 39.17,-19.98 37.21,-34.48 -4.43,-1.08 -8.98,-0.39 -13.42,0.2z" android:strokeWidth="1.04573"/>
<path android:fillColor="#ffffff" android:pathData="m137.81,233.74c18.97,-10.81 30.28,-32.52 50.84,-42.38 10.08,-4.82 18.91,-12.58 1.88,-9.75 -23.62,5.7 -57.72,22.99 -52.71,52.13z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m176.5,382.23c-10.89,10.08 -47.39,-14.78 -33.15,10 22.96,15.3 54.04,2.59 73.06,-13.68 25.35,-20.63 34.48,-66.26 5.31,-87.73 -28.87,-23.83 -81.68,-12.07 -90.91,26.17 -5.56,28.61 14.87,63.5 45.69,65.24z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m380.42,379.09c-10.32,0 -50.27,12.13 -23.12,1.31 34.33,-13.64 44.66,-68.99 10.94,-89.15 -29.71,-20.53 -81.33,-7.62 -88.3,30.57 -5.96,36.87 22.87,76.76 61.7,76.25 13.69,-0.46 36.37,-1.58 38.78,-18.97z" android:strokeWidth="1.04573"/>
<path android:fillColor="#ffffff" android:pathData="m178.59,317.4c-1.61,19.73 20.89,-2.92 0,0z" android:strokeWidth="1.04573"/>
<path android:fillColor="#ffffff" android:pathData="m333.36,318.44c-9.35,14.82 15.03,7.85 3.2,1.02z" android:strokeWidth="1.04573"/>
<path android:fillColor="#ffffff" android:pathData="m182.78,346.68c19.05,3.54 12.91,-18.62 -0.32,-6.87 -0.44,2.36 -1.2,4.04 0.32,6.87z" android:strokeWidth="1.04573"/>
<path android:fillColor="#ffffff" android:pathData="m328.13,347.72c18.68,9.03 16.71,-14.75 1.53,-5.83l-0.71,1.92z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m261.2,452.3c-0.01,-31.75 -0.13,-63.62 -4.18,-95.16 -21.21,6.72 -22.06,34.27 -29.88,51.75 -15,21.75 1.78,51.06 28.51,43.7l2.75,-0.18z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m268.52,362.36c-5.53,25.01 1.03,50.79 1.09,76.12 2.32,33.71 45.43,-4.75 27.67,-24.31 -9.59,-16.84 -13.05,-39.45 -28.77,-51.81z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m185.91,282.89c2.81,7.36 -1.01,19.99 6.8,23.39 13.4,7.92 5.01,23.19 18.02,31.43 3.29,15.59 -20.21,16.4 -9.52,32.47 10.79,11.43 33.6,-18.83 33.28,-34.78 4.95,-24.56 -15.22,-46.82 -38.79,-50.42 -3.24,-0.81 -6.51,-1.48 -9.79,-2.09z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m174.41,283.93c-0.8,9.41 7.36,32.46 3.76,10.44 -1.91,-2.35 0.64,-11.74 -3.76,-10.44z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m316.63,378.05c3.07,-11.08 3.28,-20.16 -2.79,-29.21 -1.49,-24.51 13.44,-41.07 17.43,-62.81 -28.09,0.39 -54.7,27.47 -46.08,56.4 3.62,16.06 15.22,30.98 31.44,35.62z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m163.95,287.07c-20.93,9.04 -36.19,32.9 -27.19,55.42 6.5,19.04 24.51,34.53 44.97,35.56 -4.62,-20.38 -19.13,-36.55 -18.62,-60.58 2.35,-10.49 8.59,-19.63 0.85,-30.39z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m340.68,287.07c-4.46,8.04 -2.17,32.41 0.12,9.87 -2.31,-1.88 6.22,-11.53 -0.12,-9.87z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m351.14,289.16c-6.29,17.56 7.98,33.69 3.62,48.78 15.16,21.46 -25.38,21.09 -17.21,43.24 35.01,-1.12 60.32,-47.8 37.82,-75.93 -6.39,-7.4 -14.86,-13.21 -24.23,-16.1z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m188,358.18c-1.68,13.58 8.33,26.7 3.23,7.21 -1.15,-2.13 0.63,-8.45 -3.23,-7.21z" android:strokeWidth="1.04573"/>
<path android:fillColor="#f9a318" android:pathData="m329.18,360.27c-4.17,9.07 -2.34,32.64 0.25,10.42 -0.99,-2.22 4.74,-12.03 -0.25,-10.42z" android:strokeWidth="1.04573"/>
<path android:fillColor="#203d1b" android:pathData="m318.72,509.81c27.62,9.81 24.31,-50.6 1.55,-25.14 -4.51,7.62 -2.5,16.89 -1.55,25.14z" android:strokeWidth="1.04573"/>
<path android:fillColor="#203d1b" android:pathData="m206.83,511.9c8.1,-14.52 -14.15,-44 -19,-18.82 -4.34,14.51 5.62,21.31 19,18.82z" android:strokeWidth="1.04573"/>
<path android:fillColor="#203d1b" android:pathData="m248.66,517.13c3.68,-23.67 -27.25,-48.54 -35.51,-15.61 -7.9,22.96 23.23,17.53 35.51,15.61zM292.58,516.09c26.31,9.48 28.2,-26.17 7.34,-31.63 -11.74,5.5 -7.38,21.53 -7.34,31.63z" android:strokeWidth="1.04573"/>
<path android:fillColor="#203d1b" android:pathData="m289.06,514.96c-0,-5.44 -0.32,-10.51 -2.19,-15.69 -2.27,-5.58 -5.05,-10.71 -9.36,-14.35 -12.7,-10.59 -18.59,9.53 -21.57,18.53 -1.24,3.74 -4.54,11.24 -0.76,14.49 2.45,2.11 6.79,2.15 9.83,2.22 8.86,0.21 15.69,-3.23 24.05,-5.21z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m183.93,13.89c1.52,7.25 3.92,14.13 4.87,21.51l2.07,-0.27c-0.95,-7.41 -1.33,-14.81 -4.87,-21.51z" android:strokeWidth="1.04573"/>
<path android:fillColor="#100f0f" android:pathData="m233.23,20.94 l1.05,16.73c2.29,-5.11 2.62,-11.39 1.05,-16.73z" android:strokeWidth="1.04573"/>
</vector>

Wyświetl plik

@ -1,31 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="600dp"
android:height="600dp"
android:viewportWidth="600"
android:viewportHeight="600">
<path
android:pathData="m171.93,82.63 l405.17,-82.63 0,112.99 -405.17,82.63z"
android:fillColor="#EB3C27"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M171.93,82.54l65.23,0l0,422.37l-65.23,0z"
android:fillColor="#EB3C27"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m235.04,488.2c11.66,43.5 -25.91,91.36 -83.91,106.9 -58,15.54 -114.46,-7.12 -126.12,-50.62 -11.66,-43.5 25.91,-91.36 83.91,-106.9 58,-15.54 114.46,7.12 126.12,50.62z"
android:fillColor="#EB3C27"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M511.87,13.54l65.23,0l0,422.37l-65.23,0z"
android:fillColor="#EB3C27"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m574.98,419.21c11.66,43.5 -25.91,91.36 -83.91,106.9 -58,15.54 -114.46,-7.12 -126.12,-50.62 -11.66,-43.5 25.91,-91.36 83.91,-106.9 58,-15.54 114.46,7.12 126.12,50.62z"
android:fillColor="#EB3C27"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
</vector>

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 3.0 KiB

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="30dp" android:viewportHeight="512" android:viewportWidth="512" android:width="30dp">
<path android:fillColor="#feb804" android:pathData="M402.13,1.26C394.81,11.79 388.68,19.61 383.52,29.04 343.68,85.58 302.38,141.06 261.52,196.86c-6.72,6.21 -2.23,18.18 7.3,15.63 15.68,3.42 21.45,-10.42 21.45,-10.42 0,0 77.89,-124.01 115.84,-186.59 2.59,-5.52 4.24,-14.8 -3.99,-14.23z" android:strokeWidth="1.04238"/>
<path android:fillColor="#9c59ff" android:pathData="m130.42,270.87 l84.15,-1.04 23.28,8.34 -22.14,38.79 -109.77,188.45 3.59,0.32 279.74,-251.78 45.05,-42.48 -136.78,0.48 -35.28,-0.67L402.44,1.11c0,0 -223.08,181.66 -329.74,270.15l-1.05,0.84z" android:strokeWidth="1.04238"/>
<path android:fillColor="#feb804" android:pathData="m105.97,505.41c0.64,10.48 14.14,7.32 18.78,1.43 110.11,-98.52 227.42,-195.83 322.37,-283.08 2.86,-9.82 -3.79,-12.45 -12.85,-12.17 -78.5,71.81 -160.72,147.93 -240.44,218.41 -26.97,23.78 -53.64,47.9 -80.56,71.73 -2.16,1.7 -4.6,3.11 -7.3,3.68zM230.06,291.68c6.73,-10.68 15.61,-23.14 -0.04,-21.83 -52.45,-0 -100.96,0.79 -149.97,2.26 -7.99,-0.01 -8.92,-2.35 -12.91,9.06 -4.91,14.03 13.18,11.66 21.97,11.6 42.7,-0.17 85.45,0.63 128.07,-1.04 5,-0.01 7.71,-0.11 12.88,-0.04z" android:strokeWidth="1.04238"/>
</vector>

Wyświetl plik

@ -733,6 +733,8 @@
<string name="could_not_download_from_the_server">Could not download uploaded media from the server</string> <string name="could_not_download_from_the_server">Could not download uploaded media from the server</string>
<string name="could_not_prepare_local_file_to_upload">Could not prepare local file to upload: %1$s</string> <string name="could_not_prepare_local_file_to_upload">Could not prepare local file to upload: %1$s</string>
<string name="edit_draft">Edit draft</string>
<string name="login_with_qr_code">Login with QR Code</string> <string name="login_with_qr_code">Login with QR Code</string>
<string name="route">Route</string> <string name="route">Route</string>
<string name="route_home">Home</string> <string name="route_home">Home</string>
@ -819,4 +821,9 @@
<string name="accessibility_play_username">Play username as audio</string> <string name="accessibility_play_username">Play username as audio</string>
<string name="accessibility_scan_qr_code">Scan QR code</string> <string name="accessibility_scan_qr_code">Scan QR code</string>
<string name="accessibility_navigate_to_alby">Navigate to the third-party wallet provider Alby</string> <string name="accessibility_navigate_to_alby">Navigate to the third-party wallet provider Alby</string>
<string name="it_s_not_possible_to_reply_to_a_draft_note">It\'s not possible to reply a draft note</string>
<string name="it_s_not_possible_to_quote_to_a_draft_note">It\'s not possible to quote a draft note</string>
<string name="it_s_not_possible_to_react_to_a_draft_note">It\'s not possible to react a draft note</string>
<string name="it_s_not_possible_to_zap_to_a_draft_note">It\'s not possible to zap a draft note</string>
<string name="draft_note">Draft Note</string>
</resources> </resources>

Wyświetl plik

@ -45,7 +45,7 @@ data class ResultOrError(
) )
object LanguageTranslatorService { object LanguageTranslatorService {
var executorService = Executors.newScheduledThreadPool(5) var executorService = Executors.newCachedThreadPool()
private val options = private val options =
LanguageIdentificationOptions.Builder() LanguageIdentificationOptions.Builder()

Wyświetl plik

@ -0,0 +1,81 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.service.previews
import org.junit.Assert.assertEquals
import org.junit.Test
class MetaTagsParserTest {
@Test
fun testParse() {
val input =
"""<html>
| <head>
| <meta charset="utf-8">
| <meta http-equiv="content-type" content="text/html; charset=utf-8">
| <meta property="og:title" content=title>
| <meta property="og:description" content='description'>
| <meta property="og:image" content="https://example.com/img/foo.png">
| <!-- edge cases -->
| <meta
| name="newline"
| content="newline"
| >
| <meta name="space before gt" >
| <meta name ="space before =">
| <meta name= "space after =">
| <META NAME="CAPITAL">
| <meta name="character reference" content="&lt;meta&gt;">
| <meta name="attr value with end of head doesn't harm" content="<head>bang!</head>">
| <meta name="ignore tags with duplicated attr" name="dup">
| </head>
| <body>
| <meta name="ignore meta tags in body">
| </body>
|</html>
""".trimMargin()
val exp =
listOf(
listOf("charset" to "utf-8"),
listOf("http-equiv" to "content-type", "content" to "text/html; charset=utf-8"),
listOf("property" to "og:title", "content" to "title"),
listOf("property" to "og:description", "content" to "description"),
listOf("property" to "og:image", "content" to "https://example.com/img/foo.png"),
listOf("name" to "newline", "content" to "newline"),
listOf("name" to "space before gt"),
listOf("name" to "space before ="),
listOf("name" to "space after ="),
listOf("name" to "CAPITAL"),
listOf("name" to "character reference", "content" to "<meta>"),
listOf("name" to "attr value with end of head doesn't harm", "content" to "<head>bang!</head>"),
)
val metaTags = MetaTagsParser.parse(input).toList()
println(metaTags)
assertEquals(exp.size, metaTags.size)
metaTags.zip(exp).forEach { (meta, expAttrs) ->
expAttrs.forEach { (name, expValue) ->
assertEquals(expValue, meta.attr(name))
}
}
}
}

Wyświetl plik

@ -35,6 +35,17 @@ fun <K, V> produceCachedState(
} }
} }
@Composable
fun <K, V> produceCachedState(
cache: CachedState<K, V>,
key: String,
updateValue: K,
): State<V?> {
return produceState(initialValue = cache.cached(updateValue), key1 = key) {
value = cache.update(updateValue)
}
}
interface CachedState<K, V> { interface CachedState<K, V> {
fun cached(k: K): V? fun cached(k: K): V?
@ -53,7 +64,9 @@ abstract class GenericBaseCache<K, V>(capacity: Int) : CachedState<K, V> {
val v = compute(k) val v = compute(k)
cache.put(k, v) if (v != null) {
cache.put(k, v)
}
return v return v
} }

Wyświetl plik

@ -0,0 +1,137 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush.Companion.linearGradient
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsAmethystPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Amethyst,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Amethyst: ImageVector
get() {
if (customHashTagIconsAmethyst != null) {
return customHashTagIconsAmethyst!!
}
customHashTagIconsAmethyst =
Builder(
name = "Amethyst",
defaultWidth = 170.16.dp,
defaultHeight = 186.2.dp,
viewportWidth = 170.16f,
viewportHeight = 186.2f,
).apply {
path(
fill =
linearGradient(
0.0f to Color(0xFF652D80),
1.0f to Color(0xFF2598CF),
start = Offset(80.19f, 57.17f),
end = Offset(91.66f, 57.17f),
),
stroke = null,
strokeLineWidth = 0.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(80.19f, 57.17f)
arcToRelative(5.74f, 5.64f, 0.0f, true, false, 11.48f, 0.0f)
arcToRelative(5.74f, 5.64f, 0.0f, true, false, -11.48f, 0.0f)
close()
}
path(
fill =
linearGradient(
0.0f to Color(0xFF652D80),
1.0f to Color(0xFF2598CF),
start = Offset(7.48f, 93.92f),
end = Offset(180f, 93.92f),
),
stroke = null,
strokeLineWidth = 0.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(170.13f, 142.54f)
curveToRelative(-0.2f, -0.61f, -46.85f, -111.69f, -59.68f, -142.5f)
curveToRelative(-15.62f, 0.0f, -48.61f, 0.0f, -71.88f, 0.0f)
curveToRelative(-6.83f, 16.89f, -24.46f, 59.94f, -38.6f, 94.62f)
curveToRelative(7.75f, 18.49f, 14.71f, 35.1f, 20.08f, 47.91f)
lineToRelative(29.27f, 0.0f)
arcToRelative(2.0f, 2.0f, 0.0f, false, false, 1.87f, -2.35f)
curveToRelative(-0.25f, -5.91f, -16.34f, -27.39f, -11.54f, -50.63f)
curveToRelative(1.28f, -5.0f, 2.26f, -10.08f, 3.66f, -15.06f)
arcToRelative(175.77f, 175.77f, 0.0f, false, true, 13.44f, -34.8f)
curveToRelative(0.89f, -1.69f, 1.3f, -2.45f, 3.35f, -1.17f)
curveToRelative(4.37f, 2.72f, 9.25f, 2.56f, 14.11f, 2.21f)
curveToRelative(4.19f, -0.91f, 6.23f, -2.92f, 13.91f, -0.88f)
curveToRelative(1.52f, 0.0f, 3.0f, 0.0f, 4.55f, 0.14f)
curveToRelative(3.69f, 0.29f, 7.15f, 1.17f, 9.37f, 4.51f)
curveToRelative(2.42f, 3.65f, 2.81f, 7.78f, 2.42f, 12.0f)
curveToRelative(-0.59f, 6.31f, -0.17f, 12.19f, 5.17f, 16.64f)
arcToRelative(57.52f, 57.52f, 0.0f, false, false, 6.0f, 4.0f)
curveToRelative(2.65f, 1.7f, 5.85f, 2.44f, 8.12f, 4.8f)
curveToRelative(1.34f, 1.39f, 2.13f, 2.87f, 1.55f, 4.85f)
reflectiveCurveToRelative(-2.13f, 2.91f, -4.17f, 3.13f)
curveToRelative(-5.16f, 0.56f, -10.2f, -0.49f, -15.27f, -1.1f)
curveToRelative(-0.66f, -0.08f, -1.31f, -0.13f, -2.0f, -0.17f)
arcToRelative(11.47f, 11.47f, 0.0f, false, true, -3.81f, 0.13f)
lineToRelative(-1.19f, 0.0f)
arcToRelative(26.7f, 26.7f, 0.0f, false, false, -5.9f, 1.41f)
curveToRelative(-4.78f, 1.74f, -9.13f, 3.66f, -14.77f, 3.56f)
arcToRelative(4.32f, 4.32f, 0.0f, false, false, -2.05f, 0.89f)
curveToRelative(-4.42f, 3.93f, -7.08f, 8.89f, -4.87f, 16.14f)
curveToRelative(6.06f, 16.93f, 21.61f, 57.77f, 28.29f, 75.4f)
curveToRelative(-0.19f, -11.94f, -0.24f, -33.32f, -0.28f, -43.7f)
curveTo(125.96f, 142.56f, 166.87f, 142.54f, 170.13f, 142.54f)
close()
}
}
.build()
return customHashTagIconsAmethyst!!
}
private var customHashTagIconsAmethyst: ImageVector? = null

Wyświetl plik

@ -0,0 +1,126 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsBtcPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Btc,
),
contentDescription = "",
modifier = Modifier.size(55.dp),
)
}
public val CustomHashTagIcons.Btc: ImageVector
get() {
if (customHashTagIconsBtc != null) {
return customHashTagIconsBtc!!
}
customHashTagIconsBtc =
Builder(
name = "Btc",
defaultWidth = 64.0.dp,
defaultHeight = 64.0.dp,
viewportWidth =
64.0f,
viewportHeight = 64.0f,
).apply {
path(
fill = SolidColor(Color(0xFFf7931a)),
stroke = null,
strokeLineWidth = 1.57894f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(54.9248f, 25.7592f)
curveTo(55.9306f, 19.0361f, 50.8116f, 15.4219f, 43.8122f, 13.0109f)
lineTo(46.0827f, 3.9036f)
lineTo(40.5391f, 2.522f)
lineTo(38.3286f, 11.3893f)
curveToRelative(-1.4574f, -0.3632f, -2.9542f, -0.7058f, -4.4415f, -1.0453f)
lineToRelative(2.2263f, -8.9257f)
lineToRelative(-5.5405f, -1.3816f)
lineToRelative(-2.2721f, 9.1041f)
curveTo(27.0944f, 8.8662f, 25.9102f, 8.5946f, 24.7608f, 8.3088f)
lineToRelative(0.0063f, -0.0284f)
lineToRelative(-7.6452f, -1.9089f)
lineToRelative(-1.4747f, 5.921f)
curveToRelative(0.0f, 0.0f, 4.1131f, 0.9426f, 4.0263f, 1.001f)
curveToRelative(2.2452f, 0.5605f, 2.651f, 2.0463f, 2.5831f, 3.2242f)
lineToRelative(-2.5863f, 10.3752f)
curveToRelative(0.1547f, 0.0395f, 0.3553f, 0.0963f, 0.5763f, 0.1847f)
curveToRelative(-0.1847f, -0.0458f, -0.3821f, -0.0963f, -0.5858f, -0.1453f)
lineTo(16.0356f, 41.4665f)
curveToRelative(-0.2747f, 0.6821f, -0.971f, 1.7053f, -2.5405f, 1.3168f)
curveToRelative(0.0553f, 0.0805f, -4.0294f, -1.0058f, -4.0294f, -1.0058f)
lineToRelative(-2.7521f, 6.3457f)
lineToRelative(7.2142f, 1.7984f)
curveToRelative(1.3421f, 0.3363f, 2.6574f, 0.6884f, 3.9521f, 1.02f)
lineToRelative(-2.2942f, 9.2115f)
lineToRelative(5.5373f, 1.3816f)
lineToRelative(2.2721f, -9.1136f)
curveToRelative(1.5126f, 0.4105f, 2.981f, 0.7895f, 4.4179f, 1.1463f)
lineToRelative(-2.2642f, 9.071f)
lineToRelative(5.5436f, 1.3816f)
lineToRelative(2.2942f, -9.1941f)
curveToRelative(9.4531f, 1.7889f, 16.5615f, 1.0674f, 19.5535f, -7.4826f)
curveToRelative(2.411f, -6.8842f, -0.12f, -10.8552f, -5.0936f, -13.4446f)
curveToRelative(3.6221f, -0.8353f, 6.3505f, -3.2179f, 7.0784f, -8.1394f)
close()
moveTo(42.2585f, 43.5207f)
curveToRelative(-1.7131f, 6.8842f, -13.3041f, 3.1626f, -17.062f, 2.2295f)
lineToRelative(3.0442f, -12.2036f)
curveToRelative(3.7579f, 0.9379f, 15.8083f, 2.7947f, 14.0178f, 9.9741f)
close()
moveTo(43.9733f, 25.6597f)
curveToRelative(-1.5631f, 6.2621f, -11.2104f, 3.0805f, -14.3399f, 2.3005f)
lineToRelative(2.76f, -11.0683f)
curveToRelative(3.1295f, 0.78f, 13.2078f, 2.2358f, 11.5799f, 8.7678f)
close()
}
}
.build()
return customHashTagIconsBtc!!
}
private var customHashTagIconsBtc: ImageVector? = null

Wyświetl plik

@ -0,0 +1,282 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsCashuPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Cashu,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Cashu: ImageVector
get() {
if (customHashTagIconsCashu != null) {
return customHashTagIconsCashu!!
}
customHashTagIconsCashu =
Builder(
name = "Cashu",
defaultWidth = 400.0.dp,
defaultHeight = 400.0.dp,
viewportWidth = 400.0f,
viewportHeight = 400.0f,
).apply {
path(
fill = SolidColor(Color(0xFFd6c09a)),
stroke = SolidColor(Color(0xFFd6c09a)),
strokeLineWidth = 1.23101f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(248.917f, 2.153f)
verticalLineTo(25.235f)
horizontalLineToRelative(25.236f)
verticalLineToRelative(71.091f)
horizontalLineToRelative(-25.236f)
lineToRelative(0.227f, 24.772f)
lineToRelative(-22.156f, 0.011f)
lineToRelative(-0.135f, 69.22f)
lineToRelative(22.065f, -0.532f)
verticalLineToRelative(45.326f)
horizontalLineToRelative(74.476f)
verticalLineToRelative(24.313f)
horizontalLineToRelative(24.928f)
verticalLineToRelative(24.005f)
horizontalLineToRelative(23.389f)
verticalLineToRelative(69.245f)
horizontalLineToRelative(-23.082f)
verticalLineToRelative(23.082f)
horizontalLineToRelative(-24.928f)
verticalLineToRelative(23.005f)
horizontalLineTo(126.2f)
verticalLineToRelative(-23.005f)
horizontalLineTo(100.503f)
verticalLineTo(352.454f)
horizontalLineTo(74.959f)
verticalLineTo(329.68f)
horizontalLineTo(51.801f)
verticalLineTo(282.901f)
horizontalLineTo(25.949f)
verticalLineTo(49.239f)
horizontalLineToRelative(26.082f)
verticalLineTo(25.158f)
horizontalLineTo(74.574f)
verticalLineTo(2.153f)
close()
}
path(
fill = SolidColor(Color(0xFFbb9366)),
stroke = SolidColor(Color(0xFFbb9366)),
strokeLineWidth = 1.23101f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(74.39f, 2.268f)
lineTo(74.39f, 25.272f)
lineTo(51.847f, 25.272f)
lineTo(51.847f, 49.354f)
lineTo(25.765f, 49.354f)
lineToRelative(0.407f, 233.662f)
lineTo(51.709f, 283.016f)
curveTo(52.428f, 236.898f, 76.75f, 25.19f, 125.239f, 25.349f)
lineTo(125.384f, 2.268f)
close()
moveTo(51.616f, 283.0f)
verticalLineToRelative(46.795f)
horizontalLineToRelative(23.158f)
verticalLineToRelative(22.774f)
lineTo(99.936f, 352.568f)
lineTo(99.936f, 331.112f)
lineTo(75.162f, 331.112f)
verticalLineToRelative(-47.893f)
close()
moveTo(100.318f, 354.117f)
verticalLineToRelative(21.764f)
horizontalLineToRelative(25.469f)
verticalLineToRelative(-21.764f)
close()
moveTo(323.596f, 354.501f)
verticalLineToRelative(21.379f)
horizontalLineToRelative(24.849f)
verticalLineToRelative(-21.379f)
close()
moveTo(126.016f, 377.506f)
verticalLineToRelative(21.379f)
horizontalLineToRelative(197.501f)
verticalLineToRelative(-21.379f)
close()
}
path(
fill = SolidColor(Color(0xFFc4a47b)),
stroke = SolidColor(Color(0xFFc4a47b)),
strokeLineWidth = 1.23101f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(74.466f, 25.205f)
lineTo(125.28f, 25.706f)
verticalLineTo(49.249f)
horizontalLineTo(100.505f)
verticalLineTo(213.59f)
horizontalLineToRelative(24.928f)
verticalLineToRelative(47.394f)
horizontalLineToRelative(48.625f)
verticalLineToRelative(24.005f)
horizontalLineToRelative(25.697f)
verticalLineToRelative(22.928f)
horizontalLineToRelative(22.928f)
verticalLineToRelative(23.005f)
horizontalLineToRelative(125.948f)
verticalLineToRelative(23.466f)
horizontalLineToRelative(-24.851f)
verticalLineToRelative(23.005f)
horizontalLineTo(125.972f)
verticalLineToRelative(-23.389f)
horizontalLineToRelative(-25.851f)
verticalLineTo(330.998f)
horizontalLineTo(75.346f)
verticalLineTo(283.291f)
lineTo(51.581f, 283.072f)
lineTo(51.487f, 49.319f)
horizontalLineToRelative(22.77f)
close()
}
path(
fill = SolidColor(Color(0xFF000000)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 1.23101f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(25.598f, 120.678f)
verticalLineToRelative(18.254f)
horizontalLineToRelative(9.75f)
verticalLineToRelative(10.545f)
horizontalLineToRelative(8.151f)
verticalLineToRelative(9.925f)
horizontalLineToRelative(10.192f)
verticalLineToRelative(7.708f)
horizontalLineToRelative(67.434f)
verticalLineToRelative(-7.975f)
horizontalLineToRelative(10.012f)
verticalLineToRelative(-9.836f)
horizontalLineToRelative(10.192f)
verticalLineToRelative(-20.824f)
horizontalLineToRelative(17.722f)
verticalLineToRelative(20.648f)
horizontalLineToRelative(10.278f)
verticalLineToRelative(9.747f)
horizontalLineToRelative(7.886f)
verticalLineToRelative(7.797f)
horizontalLineToRelative(67.523f)
verticalLineToRelative(-7.619f)
horizontalLineToRelative(9.747f)
verticalLineToRelative(-9.836f)
horizontalLineToRelative(10.367f)
verticalLineToRelative(-10.37f)
horizontalLineToRelative(9.572f)
verticalLineToRelative(-17.809f)
close()
moveTo(178.698f, 128.19f)
horizontalLineToRelative(9.394f)
verticalLineToRelative(10.146f)
lineToRelative(10.557f, 0.043f)
verticalLineToRelative(10.012f)
horizontalLineToRelative(9.399f)
verticalLineToRelative(-10.151f)
horizontalLineToRelative(-9.322f)
lineTo(198.726f, 128.19f)
lineToRelative(9.615f, 0.043f)
verticalLineToRelative(10.103f)
horizontalLineToRelative(8.807f)
lineToRelative(0.053f, 10.233f)
lineToRelative(9.216f, 0.046f)
verticalLineToRelative(9.569f)
lineToRelative(-9.259f, -0.043f)
lineToRelative(0.043f, -9.572f)
horizontalLineToRelative(-8.906f)
verticalLineToRelative(9.216f)
horizontalLineToRelative(-9.569f)
verticalLineToRelative(-9.17f)
lineToRelative(-10.634f, -0.089f)
lineToRelative(0.046f, -10.146f)
lineToRelative(-9.439f, -0.043f)
close()
moveTo(43.409f, 129.541f)
horizontalLineToRelative(9.394f)
verticalLineToRelative(10.146f)
lineToRelative(10.557f, 0.043f)
verticalLineToRelative(10.012f)
horizontalLineToRelative(9.399f)
lineTo(72.759f, 139.591f)
horizontalLineToRelative(-9.322f)
verticalLineToRelative(-10.05f)
lineToRelative(9.615f, 0.043f)
verticalLineToRelative(10.103f)
horizontalLineToRelative(8.807f)
lineToRelative(0.053f, 10.233f)
lineToRelative(9.216f, 0.046f)
verticalLineToRelative(9.569f)
lineToRelative(-9.259f, -0.043f)
lineToRelative(0.043f, -9.572f)
horizontalLineToRelative(-8.906f)
verticalLineToRelative(9.216f)
horizontalLineToRelative(-9.569f)
verticalLineToRelative(-9.17f)
lineToRelative(-10.634f, -0.089f)
lineToRelative(0.046f, -10.146f)
lineToRelative(-9.439f, -0.043f)
close()
}
}
.build()
return customHashTagIconsCashu!!
}
private var customHashTagIconsCashu: ImageVector? = null

Wyświetl plik

@ -0,0 +1,352 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsCoffeePreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Coffee,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Coffee: ImageVector
get() {
if (customHashTagIconsCoffee != null) {
return customHashTagIconsCoffee!!
}
customHashTagIconsCoffee =
Builder(
name = "Coffee",
defaultWidth = 512.0.dp,
defaultHeight = 512.0.dp,
viewportWidth = 512.0f,
viewportHeight = 512.0f,
).apply {
path(
fill = SolidColor(Color(0xFF00ffff)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(204.583f, 84.841f)
curveToRelative(1.808f, 1.808f, 0.933f, 0.933f, 0.0f, 0.0f)
close()
moveTo(366.274f, 85.89f)
curveToRelative(1.808f, 1.808f, 0.933f, 0.933f, 0.0f, 0.0f)
close()
}
path(
fill = SolidColor(Color(0xFFe0e0e0)),
stroke = null,
strokeLineWidth = 0.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(195.829f, 118.866f)
curveTo(160.275f, 121.553f, 58.06f, 148.411f, 62.84f, 207.684f)
curveToRelative(0.811f, 23.285f, 2.035f, 46.555f, 5.059f, 69.667f)
curveTo(71.123f, 304.527f, 75.496f, 331.75f, 84.247f, 357.826f)
curveTo(99.454f, 396.095f, 133.387f, 425.805f, 173.084f, 436.368f)
curveToRelative(40.815f, 11.15f, 76.446f, 13.423f, 125.257f, -1.302f)
curveToRelative(37.884f, -10.354f, 71.389f, -38.361f, 83.885f, -76.191f)
curveToRelative(3.446f, -9.197f, 5.449f, -18.704f, 7.147f, -28.348f)
curveToRelative(20.026f, 1.025f, 40.624f, -1.266f, 59.847f, -7.378f)
curveToRelative(27.45f, -9.619f, 55.114f, -30.92f, 57.747f, -61.918f)
curveToRelative(2.014f, -19.218f, -3.317f, -39.883f, -18.899f, -52.411f)
curveTo(470.37f, 192.651f, 445.495f, 189.273f, 422.473f, 190.885f)
curveToRelative(-5.924f, -1.922f, -19.271f, 4.388f, -19.713f, -4.259f)
curveToRelative(-21.541f, -42.19f, -74.519f, -63.244f, -116.574f, -67.395f)
curveToRelative(-15.337f, -1.399f, -54.803f, -3.05f, -90.357f, -0.364f)
close()
moveTo(258.205f, 145.736f)
curveToRelative(35.707f, 4.411f, 74.758f, 9.193f, 102.819f, 33.628f)
curveToRelative(12.647f, 10.578f, 23.305f, 29.728f, 12.251f, 45.119f)
curveToRelative(-18.88f, 25.814f, -51.743f, 35.57f, -81.547f, 42.377f)
curveToRelative(-31.353f, 6.806f, -63.845f, 5.798f, -95.545f, 2.684f)
curveToRelative(-33.373f, -5.067f, -69.433f, -11.315f, -95.459f, -34.591f)
curveTo(90.48f, 225.01f, 85.348f, 208.691f, 94.105f, 196.134f)
curveTo(109.591f, 170.883f, 139.794f, 160.479f, 166.785f, 152.359f)
curveTo(177.505f, 149.627f, 188.334f, 146.966f, 199.333f, 145.737f)
moveToRelative(229.716f, 86.973f)
curveToRelative(8.709f, 0.053f, 17.284f, 0.926f, 25.221f, 4.741f)
curveToRelative(16.862f, 8.494f, 9.465f, 33.24f, -5.051f, 40.171f)
curveToRelative(-16.122f, 8.148f, -34.767f, 10.155f, -52.497f, 11.957f)
curveToRelative(1.831f, -18.914f, 4.279f, -37.818f, 6.3f, -56.697f)
curveToRelative(8.475f, 0.54f, 17.318f, -0.226f, 26.027f, -0.172f)
close()
}
path(
fill = SolidColor(Color(0xFF6d4b41)),
stroke = SolidColor(Color(0xFF6d4b41)),
strokeLineWidth = 8.81928f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(90.72f, 207.67f)
arcToRelative(141.919f, 61.231f, 0.0f, true, false, 283.838f, 0.0f)
arcToRelative(141.919f, 61.231f, 0.0f, true, false, -283.838f, 0.0f)
close()
}
path(
fill = SolidColor(Color(0xFFb59075)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(251.83f, 158.337f)
curveToRelative(-37.403f, 0.757f, -63.367f, 0.095f, -100.795f, 11.346f)
curveToRelative(-16.245f, 6.796f, -36.117f, 14.395f, -42.826f, 32.062f)
curveToRelative(4.78f, 30.851f, 60.554f, 22.125f, 56.067f, 2.789f)
curveToRelative(-4.141f, -14.164f, 14.984f, -19.744f, 25.607f, -15.895f)
curveToRelative(21.728f, 3.907f, 40.061f, 18.156f, 61.947f, 21.115f)
curveToRelative(8.814f, 1.936f, 20.571f, -2.794f, 17.762f, -13.62f)
curveToRelative(-3.874f, -6.982f, 0.155f, -14.741f, 8.487f, -14.612f)
curveToRelative(25.355f, -1.826f, 47.158f, 13.808f, 70.346f, 21.115f)
curveToRelative(7.046f, 3.956f, 15.783f, -3.153f, 8.545f, -9.653f)
curveToRelative(-28.173f, -23.147f, -72.369f, -35.312f, -105.14f, -34.648f)
close()
}
path(
fill = SolidColor(Color(0xFFb59074)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(293.915f, 199.809f)
curveToRelative(-6.744f, 4.634f, 0.262f, 16.203f, -8.579f, 20.246f)
curveToRelative(-16.21f, 10.232f, -35.697f, 0.44f, -52.405f, -3.622f)
curveToRelative(-14.159f, -3.75f, -29.518f, -10.912f, -44.098f, -6.124f)
curveToRelative(-10.455f, 5.464f, -3.973f, 21.891f, 7.35f, 19.424f)
curveToRelative(7.854f, -1.083f, 15.552f, -2.724f, 23.099f, 1.05f)
curveToRelative(22.268f, 6.96f, 45.971f, 11.514f, 69.296f, 8.721f)
curveToRelative(10.746f, -2.04f, 15.897f, -12.263f, 24.149f, -17.821f)
curveToRelative(10.272f, -2.429f, 22.449f, 12.795f, 30.507f, 1.75f)
curveToRelative(3.642f, -11.742f, -12.073f, -16.176f, -20.321f, -19.703f)
curveToRelative(-9.315f, -3.257f, -19.114f, -5.824f, -28.998f, -3.921f)
close()
}
path(
fill = SolidColor(Color(0xFF6aa5ac)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(403.022f, 222.383f)
curveToRelative(-0.027f, 0.814f, 0.014f, 9.727f, 0.052f, 10.476f)
curveToRelative(34.643f, -0.056f, 53.296f, 2.383f, 65.084f, 16.868f)
curveToRelative(4.078f, 5.361f, 7.465f, 10.616f, 10.15f, 8.407f)
curveToRelative(-1.559f, -19.676f, -20.181f, -34.582f, -36.438f, -36.161f)
curveToRelative(-12.802f, -1.147f, -26.08f, -1.131f, -38.848f, 0.408f)
close()
}
path(
fill = SolidColor(Color(0xFFbbced3)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(460.306f, 242.286f)
curveToRelative(10.121f, 17.211f, -6.218f, 36.214f, -22.955f, 40.032f)
curveToRelative(-13.308f, 3.429f, -26.932f, 6.237f, -40.629f, 7.262f)
curveToRelative(-1.512f, 4.605f, -7.203f, 17.175f, 1.161f, 15.749f)
curveToRelative(18.916f, -0.454f, 38.872f, -2.294f, 55.712f, -11.657f)
curveToRelative(13.424f, -7.047f, 22.474f, -20.882f, 24.652f, -35.775f)
curveToRelative(-5.446f, 2.157f, -11.704f, -14.707f, -17.942f, -15.61f)
close()
}
path(
fill = SolidColor(Color(0xFF97827b)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(113.238f, 244.432f)
curveToRelative(1.808f, 1.808f, 0.933f, 0.933f, 0.0f, 0.0f)
close()
moveTo(350.525f, 244.432f)
curveToRelative(1.808f, 1.808f, 0.933f, 0.933f, 0.0f, 0.0f)
close()
}
path(
fill = SolidColor(Color(0xFFa79691)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(345.275f, 247.582f)
curveToRelative(1.808f, 1.808f, 0.933f, 0.933f, 0.0f, 0.0f)
close()
moveTo(120.587f, 248.632f)
curveToRelative(1.808f, 1.808f, 0.933f, 0.933f, 0.0f, 0.0f)
close()
}
path(
fill = SolidColor(Color(0xFFbbced3)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(70.19f, 296.929f)
curveToRelative(0.63f, 13.988f, -1.646f, 28.325f, 2.1f, 41.998f)
curveToRelative(-28.14f, 7.44f, -58.322f, 24.801f, -66.817f, 54.597f)
curveToRelative(-8.199f, 25.343f, 9.633f, 50.004f, 29.111f, 64.51f)
curveToRelative(42.757f, 32.57f, 96.75f, 46.56f, 149.387f, 52.053f)
curveToRelative(25.565f, 3.024f, 51.567f, 2.3f, 77.309f, 1.671f)
curveToRelative(57.383f, -3.76f, 116.697f, -14.922f, 165.891f, -46.489f)
curveToRelative(24.111f, -15.167f, 48.186f, -40.127f, 45.789f, -70.696f)
curveToRelative(-3.387f, -27.595f, -31.449f, -41.659f, -55.239f, -48.998f)
curveToRelative(-6.858f, -2.016f, -13.845f, -4.048f, -20.999f, -4.549f)
curveToRelative(2.547f, -12.394f, 4.107f, -10.878f, -7.592f, -11.302f)
curveToRelative(-3.148f, 19.859f, -11.241f, 41.844f, -22.361f, 58.549f)
curveToRelative(-9.335f, 27.17f, -32.881f, 46.946f, -58.242f, 58.797f)
curveToRelative(41.174f, -5.651f, 76.469f, -60.671f, 83.995f, -91.345f)
curveToRelative(21.082f, 4.352f, 45.071f, 10.026f, 58.388f, 28.348f)
curveToRelative(9.974f, 15.413f, -3.736f, 32.736f, -13.882f, 44.068f)
curveToRelative(-102.215f, 85.133f, -293.119f, 73.315f, -394.849f, 9.366f)
curveToRelative(-11.24f, -12.658f, -26.761f, -34.252f, -13.844f, -51.488f)
curveToRelative(11.011f, -15.95f, 29.052f, -25.575f, 47.104f, -31.345f)
curveToRelative(12.867f, 37.173f, 39.595f, 70.253f, 75.071f, 87.903f)
curveToRelative(2.313f, -1.995f, -10.941f, -7.591f, -14.174f, -11.112f)
curveTo(123.074f, 420.237f, 108.45f, 408.223f, 102.359f, 391.483f)
curveTo(104.483f, 388.761f, 94.882f, 380.021f, 91.976f, 372.525f)
curveTo(78.856f, 349.743f, 75.034f, 323.229f, 70.948f, 297.746f)
close()
}
path(
fill = SolidColor(Color(0xFFe0e0e0)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(392.523f, 355.726f)
curveToRelative(-11.611f, 47.0f, -52.915f, 84.188f, -99.673f, 96.085f)
curveToRelative(-25.958f, 8.69f, -52.515f, 9.949f, -79.602f, 8.14f)
curveToRelative(-28.816f, -2.721f, -56.323f, -11.953f, -80.06f, -28.483f)
curveToRelative(-26.745f, -18.753f, -46.217f, -46.561f, -57.747f, -76.792f)
curveToRelative(-21.268f, 6.033f, -44.593f, 18.658f, -52.059f, 40.948f)
curveToRelative(-4.034f, 54.612f, 91.596f, 82.662f, 133.955f, 89.654f)
curveToRelative(55.068f, 8.766f, 123.339f, 7.499f, 172.191f, -3.471f)
curveToRelative(36.304f, -7.727f, 158.106f, -59.911f, 118.328f, -103.029f)
curveToRelative(-14.746f, -13.873f, -35.783f, -19.848f, -55.332f, -23.051f)
close()
}
path(
fill = SolidColor(Color(0xFF6aa5ac)),
stroke = null,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(366.723f, 388.627f)
curveToRelative(-25.239f, 35.357f, -71.86f, 51.221f, -113.533f, 54.886f)
curveToRelative(-24.65f, 3.208f, -48.923f, 0.367f, -73.095f, -5.062f)
curveToRelative(-29.288f, -7.565f, -59.668f, -27.713f, -79.046f, -51.061f)
curveToRelative(20.561f, 60.682f, 97.111f, 78.574f, 150.782f, 73.331f)
curveToRelative(45.365f, -4.706f, 103.34f, -25.754f, 114.893f, -72.093f)
close()
}
path(
fill = SolidColor(Color(0xFFb9cdd5)),
stroke = null,
fillAlpha = 0.632035f,
strokeLineWidth = 1.04994f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(335.914f, 14.7f)
curveToRelative(6.079f, 8.502f, 9.15f, 22.2f, -1.522f, 28.597f)
curveToRelative(-15.584f, 5.865f, -32.814f, 4.136f, -49.138f, 6.08f)
curveToRelative(-29.968f, 2.843f, -64.819f, 9.676f, -81.487f, 37.769f)
curveToRelative(-5.635f, 8.926f, -7.22f, 19.092f, -8.767f, 29.392f)
curveToRelative(-0.014f, 0.002f, -0.027f, 0.004f, -0.041f, 0.006f)
curveToRelative(-0.052f, 15.851f, 2.979f, 29.867f, 9.472f, 43.368f)
lineToRelative(-0.15f, 0.004f)
curveToRelative(8.964f, 13.262f, 19.474f, 29.828f, 35.825f, 35.985f)
curveToRelative(11.442f, 2.558f, 10.867f, -12.151f, 10.957f, -20.164f)
curveToRelative(-0.349f, -14.022f, 1.126f, -23.577f, 8.287f, -32.411f)
curveToRelative(-0.001f, -0.0f, -1.713f, 3.224f, -0.004f, 0.0f)
curveToRelative(1.709f, -3.224f, 6.5f, -8.891f, 11.209f, -13.746f)
curveToRelative(4.709f, -4.855f, 13.22f, -8.825f, 20.482f, -11.601f)
curveToRelative(7.262f, -2.776f, 72.306f, -24.482f, 85.154f, -42.383f)
curveTo(390.225f, 49.263f, 375.539f, 12.278f, 348.251f, 1.225f)
curveTo(338.856f, -2.773f, 332.82f, 9.412f, 335.914f, 14.7f)
close()
}
}
.build()
return customHashTagIconsCoffee!!
}
private var customHashTagIconsCoffee: ImageVector? = null

Wyświetl plik

@ -0,0 +1,52 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.ui.graphics.vector.ImageVector
import kotlin.collections.List as ____KtList
public object CustomHashTagIcons
private var customHashTagIconsAllIconsCache: ____KtList<ImageVector>? = null
public val CustomHashTagIcons.AllIcons: ____KtList<ImageVector>
get() {
if (customHashTagIconsAllIconsCache != null) {
return customHashTagIconsAllIconsCache!!
}
customHashTagIconsAllIconsCache =
listOf(
Lightning,
Mate,
Skull,
Coffee,
Plebs,
Weed,
Cashu,
Grownostr,
Footstr,
Btc,
Zap,
Tunestr,
Nostr,
)
return customHashTagIconsAllIconsCache!!
}

Wyświetl plik

@ -0,0 +1,162 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsFootstrPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Footstr,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Footstr: ImageVector
get() {
if (customHashTagIconsFootStr != null) {
return customHashTagIconsFootStr!!
}
customHashTagIconsFootStr =
Builder(
name = "Footstr",
defaultWidth = 236.0.dp,
defaultHeight = 236.0.dp,
viewportWidth = 236.0f,
viewportHeight = 236.0f,
).apply {
path(
fill = SolidColor(Color(0xFFe102c2)),
stroke = null,
strokeLineWidth = 1.16731f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(172.024f, 18.47f)
lineTo(184.052f, 17.337f)
curveTo(183.463f, 10.976f, 181.095f, 5.502f, 177.469f, 0.069f)
moveTo(192.472f, 156.68f)
curveToRelative(15.586f, 0.841f, 18.539f, 6.439f, 27.813f, -9.063f)
curveToRelative(8.364f, -13.977f, 2.988f, -28.3f, 6.501f, -43.049f)
curveToRelative(1.282f, -5.383f, 3.715f, -10.25f, 4.063f, -15.86f)
curveToRelative(0.334f, -5.423f, -1.494f, -10.524f, -2.089f, -15.86f)
curveToRelative(-0.564f, -5.045f, -0.376f, -10.678f, -5.273f, -14.038f)
curveToRelative(-5.438f, -3.733f, -9.84f, 1.109f, -10.437f, 6.11f)
curveToRelative(-0.582f, 4.874f, 0.226f, 9.842f, -0.256f, 14.726f)
curveToRelative(-0.422f, 4.273f, -1.943f, 8.124f, -2.05f, 12.462f)
curveToRelative(-0.084f, 3.439f, -1.441f, 8.999f, -6.245f, 8.999f)
curveToRelative(-8.641f, 0.0f, -6.692f, -13.224f, -7.853f, -18.062f)
curveToRelative(-2.124f, -8.857f, -5.552f, -16.829f, -6.371f, -26.056f)
curveToRelative(-0.605f, -6.811f, 1.684f, -13.506f, 0.771f, -20.392f)
curveToRelative(-0.618f, -4.663f, -2.976f, -11.245f, -8.249f, -12.861f)
curveToRelative(-7.27f, -2.228f, -10.639f, 5.207f, -10.751f, 10.596f)
curveToRelative(-0.119f, 5.818f, 2.058f, 11.23f, 2.336f, 16.993f)
curveToRelative(0.445f, 9.246f, 1.175f, 18.807f, 1.322f, 27.999f)
curveToRelative(0.051f, 3.174f, -1.301f, 6.191f, -1.097f, 9.387f)
curveToRelative(0.304f, 4.758f, 7.302f, 11.044f, 3.842f, 15.448f)
curveToRelative(-4.18f, 5.317f, -10.196f, -0.538f, -12.803f, -4.121f)
curveToRelative(-5.162f, -7.099f, -8.576f, -15.319f, -13.304f, -22.635f)
curveToRelative(-2.224f, -3.438f, -5.693f, -6.276f, -10.262f, -5.173f)
curveToRelative(-12.213f, 2.948f, -2.336f, 18.13f, 1.648f, 23.277f)
curveToRelative(10.468f, 13.526f, 19.591f, 27.625f, 30.784f, 40.783f)
curveToRelative(6.229f, 7.322f, 15.101f, 11.077f, 17.959f, 20.392f)
moveToRelative(25.259f, -125.748f)
curveToRelative(1.05f, 7.343f, 2.406f, 14.051f, 2.406f, 21.524f)
lineToRelative(9.622f, 3.399f)
curveToRelative(-0.44f, -9.512f, -3.839f, -18.966f, -12.028f, -24.923f)
moveToRelative(-80.587f, 15.86f)
curveToRelative(-4.545f, 7.606f, -6.269f, 16.447f, -3.608f, 24.923f)
curveToRelative(3.228f, -1.535f, 6.071f, -2.76f, 9.622f, -3.399f)
curveToRelative(-1.064f, -6.786f, -3.047f, -15.302f, -6.014f, -21.524f)
moveToRelative(-78.182f, 1.133f)
curveToRelative(-1.517f, 6.905f, -3.735f, 13.678f, -6.014f, 20.392f)
lineTo(66.178f, 69.449f)
curveTo(63.783f, 62.514f, 62.59f, 54.306f, 58.961f, 47.925f)
moveTo(45.731f, 207.659f)
curveToRelative(2.62f, -8.546f, 8.778f, -9.623f, 13.924f, -15.984f)
curveToRelative(8.239f, -10.187f, 17.116f, -20.089f, 25.003f, -30.464f)
curveToRelative(3.56f, -4.686f, 6.036f, -10.011f, 9.622f, -14.727f)
curveToRelative(3.915f, -5.147f, 14.26f, -20.373f, 1.903f, -23.277f)
curveToRelative(-4.614f, -1.084f, -8.062f, 1.695f, -10.322f, 5.173f)
curveToRelative(-4.74f, 7.292f, -8.192f, 15.572f, -13.305f, 22.635f)
curveToRelative(-2.521f, 3.482f, -7.669f, 8.817f, -11.941f, 4.298f)
curveToRelative(-4.307f, -4.555f, 2.592f, -10.65f, 3.011f, -15.626f)
curveToRelative(0.277f, -3.275f, -1.021f, -6.315f, -1.066f, -9.543f)
curveToRelative(-0.179f, -12.863f, 1.339f, -26.465f, 3.26f, -39.17f)
curveToRelative(0.915f, -6.054f, -0.085f, -19.425f, -10.413f, -16.26f)
curveToRelative(-5.273f, 1.617f, -7.629f, 8.197f, -8.249f, 12.861f)
curveToRelative(-0.811f, 6.116f, 1.066f, 12.084f, 0.589f, 18.126f)
curveToRelative(-0.796f, 10.107f, -4.172f, 18.642f, -6.357f, 28.322f)
curveToRelative(-1.105f, 4.896f, 1.127f, 17.891f, -7.686f, 17.891f)
curveToRelative(-5.485f, 0.0f, -6.35f, -6.214f, -6.357f, -9.961f)
curveToRelative(-0.007f, -4.018f, -1.955f, -7.399f, -2.287f, -11.329f)
curveToRelative(-0.413f, -4.87f, 0.609f, -9.83f, 0.153f, -14.726f)
curveToRelative(-0.437f, -4.689f, -4.81f, -9.935f, -10.285f, -6.762f)
curveToRelative(-5.149f, 2.986f, -4.939f, 9.806f, -5.485f, 14.691f)
curveToRelative(-0.552f, 4.945f, -2.241f, 9.713f, -2.136f, 14.727f)
curveToRelative(0.117f, 5.621f, 2.272f, 10.533f, 3.802f, 15.86f)
curveToRelative(4.381f, 15.243f, -1.813f, 29.587f, 7.01f, 44.182f)
curveToRelative(2.41f, 3.988f, 5.784f, 9.177f, 10.775f, 10.539f)
curveToRelative(4.794f, 1.31f, 11.713f, -1.435f, 16.838f, -1.476f)
moveTo(19.269f, 81.911f)
curveTo(12.507f, 89.006f, 8.661f, 97.251f, 8.444f, 106.834f)
curveToRelative(3.191f, -1.408f, 6.204f, -2.592f, 9.622f, -3.399f)
curveToRelative(0.0f, -6.502f, 3.112f, -15.605f, 1.203f, -21.524f)
moveToRelative(80.587f, 15.86f)
curveToRelative(-0.331f, 7.133f, -3.121f, 13.512f, -4.811f, 20.392f)
curveToRelative(3.415f, 1.23f, 6.452f, 2.819f, 9.622f, 4.531f)
curveToRelative(2.546f, -8.112f, 1.766f, -18.722f, -4.811f, -24.923f)
moveToRelative(92.745f, 69.945f)
curveToRelative(-12.846f, 5.17f, -0.975f, 22.186f, 10.583f, 17.445f)
curveToRelative(14.948f, -6.131f, 2.896f, -22.87f, -10.583f, -17.445f)
moveToRelative(-9.752f, 20.684f)
curveToRelative(0.0f, 7.665f, -0.565f, 15.042f, -1.203f, 22.657f)
curveToRelative(5.293f, -5.307f, 10.001f, -12.128f, 14.434f, -18.126f)
curveToRelative(-4.675f, -1.022f, -8.892f, -2.614f, -13.231f, -4.531f)
moveTo(34.912f, 218.458f)
curveToRelative(-13.565f, 3.164f, -4.322f, 20.77f, 7.211f, 17.989f)
curveToRelative(7.881f, -1.9f, 12.632f, -11.136f, 5.51f, -16.777f)
curveToRelative(-3.211f, -2.542f, -8.913f, -2.1f, -12.721f, -1.212f)
}
}
.build()
return customHashTagIconsFootStr!!
}
private var customHashTagIconsFootStr: ImageVector? = null

Wyświetl plik

@ -0,0 +1,297 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsGrownostrPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Grownostr,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Grownostr: ImageVector
get() {
if (customHashTagIconsGrowNostr != null) {
return customHashTagIconsGrowNostr!!
}
customHashTagIconsGrowNostr =
Builder(
name = "Grownostr",
defaultWidth = 128.0.dp,
defaultHeight = 128.0.dp,
viewportWidth = 128.0f,
viewportHeight = 128.0f,
).apply {
path(
fill = SolidColor(Color(0xFF6200ee)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(9.224f, 0.486f)
curveTo(32.035f, 17.55f, 41.727f, 30.892f, 55.972f, 46.502f)
curveTo(58.127f, 41.355f, 55.87f, 32.947f, 54.169f, 27.762f)
curveTo(47.608f, 7.761f, 28.73f, 0.498f, 9.224f, 0.486f)
close()
}
path(
fill = SolidColor(Color(0xFF6200ee)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(71.434f, 71.774f)
curveTo(80.152f, 58.93f, 119.83f, 33.376f, 120.809f, 24.042f)
curveTo(99.67f, 24.479f, 79.224f, 31.773f, 72.715f, 53.799f)
curveToRelative(-1.57f, 5.311f, -1.279f, 12.494f, -1.28f, 17.975f)
close()
}
path(
fill = SolidColor(Color(0xFF3700b3)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(106.897f, 34.151f)
curveTo(85.728f, 55.379f, 83.294f, 51.88f, 72.931f, 73.418f)
curveTo(99.006f, 72.295f, 124.096f, 52.448f, 120.96f, 24.204f)
curveToRelative(-6.391f, 2.874f, -10.261f, 5.064f, -14.063f, 9.946f)
close()
}
path(
fill = SolidColor(Color(0xFF3700b3)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(8.753f, 0.486f)
curveTo(9.992f, 16.183f, 11.87f, 33.641f, 26.582f, 42.19f)
curveToRelative(8.311f, 4.828f, 18.0f, 6.141f, 27.276f, 7.889f)
curveTo(51.373f, 34.848f, 52.381f, 36.195f, 23.789f, 11.482f)
curveTo(19.47f, 7.834f, 15.869f, 4.353f, 8.753f, 0.486f)
close()
}
path(
fill = SolidColor(Color(0xFF818181)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(32.781f, 4.205f)
lineToRelative(1.24f, 1.24f)
close()
}
path(
fill = SolidColor(Color(0xFF35b458)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(21.622f, 10.404f)
curveToRelative(1.727f, 1.778f, 2.769f, 2.535f, 4.959f, 3.72f)
curveToRelative(-2.998f, 0.895f, -5.545f, 1.175f, -8.679f, 1.24f)
verticalLineToRelative(3.72f)
curveToRelative(12.329f, 0.0f, 18.717f, 3.247f, 26.037f, 13.638f)
horizontalLineToRelative(-8.679f)
verticalLineToRelative(3.72f)
curveToRelative(3.974f, 0.004f, 8.635f, -0.583f, 11.99f, 1.987f)
curveToRelative(5.095f, 3.903f, 6.276f, 10.83f, 7.861f, 16.61f)
curveToRelative(4.072f, 14.857f, 6.186f, 30.48f, 6.186f, 45.874f)
curveToRelative(0.0f, 7.101f, -12.143f, 35.848f, 4.959f, 24.797f)
curveToRelative(2.201f, -11.686f, -0.793f, -24.101f, -0.55f, -34.716f)
curveToRelative(3.591f, -12.146f, 10.482f, -24.099f, 19.148f, -30.583f)
curveToRelative(4.709f, -1.594f, 11.079f, 2.021f, 12.398f, -4.132f)
lineTo(84.854f, 57.518f)
curveTo(92.594f, 48.012f, 98.343f, 42.675f, 110.891f, 42.64f)
verticalLineToRelative(-2.48f)
horizontalLineToRelative(-8.679f)
lineToRelative(4.959f, -6.199f)
curveTo(99.438f, 34.305f, 94.621f, 42.1f, 88.573f, 46.36f)
curveTo(88.312f, 42.964f, 88.199f, 42.117f, 84.854f, 41.4f)
curveTo(84.466f, 54.133f, 72.011f, 71.537f, 63.777f, 79.835f)
curveTo(63.682f, 68.403f, 61.36f, 55.477f, 56.361f, 45.12f)
curveTo(53.377f, 38.937f, 48.971f, 33.724f, 45.694f, 27.762f)
curveToRelative(-1.764f, -3.211f, -2.345f, -6.791f, -4.234f, -9.919f)
curveToRelative(-0.849f, 1.547f, -0.929f, 1.919f, -1.24f, 3.72f)
curveTo(34.743f, 17.118f, 28.995f, 10.143f, 21.622f, 10.404f)
close()
}
path(
fill = SolidColor(Color(0xFF818181)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(42.699f, 10.404f)
lineToRelative(1.24f, 1.24f)
close()
}
path(
fill = SolidColor(Color(0xFF818181)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(103.452f, 25.282f)
lineToRelative(1.24f, 1.24f)
close()
}
path(
fill = SolidColor(Color(0xFF01ff01)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(12.943f, 27.762f)
lineToRelative(1.24f, 1.24f)
lineToRelative(-1.24f, -1.24f)
moveToRelative(76.87f, 2.48f)
lineToRelative(1.24f, 1.24f)
close()
}
path(
fill = SolidColor(Color(0xFF818181)),
stroke = null,
strokeLineWidth = 1.23984f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(73.695f, 48.839f)
lineToRelative(1.24f, 1.24f)
close()
}
path(
fill = SolidColor(Color(0xFFf99721)),
stroke = null,
strokeLineWidth = 1.18196f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(0.081f, 127.881f)
curveToRelative(9.289f, 0.0f, 23.307f, 0.004f, 33.058f, -0.192f)
curveToRelative(18.284f, -0.22f, 37.955f, -11.486f, 49.607f, -18.06f)
curveToRelative(-6.533f, -6.661f, -21.685f, -9.693f, -28.933f, -6.422f)
curveToRelative(-6.339f, 4.411f, -16.531f, 6.015f, -23.401f, 9.187f)
curveToRelative(-10.618f, 8.433f, -25.203f, 8.662f, -30.331f, 15.487f)
close()
}
path(
fill = SolidColor(Color(0xFF857f2d)),
stroke = null,
strokeLineWidth = 1.01399f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(61.97f, 101.518f)
lineToRelative(1.014f, 1.014f)
close()
}
path(
fill = SolidColor(Color(0xFFffff01)),
stroke = null,
strokeLineWidth = 1.01399f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(51.83f, 105.574f)
lineToRelative(1.014f, 1.014f)
lineToRelative(-1.014f, -1.014f)
moveToRelative(23.322f, 0.0f)
lineToRelative(1.014f, 1.014f)
close()
}
path(
fill = SolidColor(Color(0xFFdf7f07)),
stroke = null,
strokeLineWidth = 1.19243f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(31.334f, 127.881f)
horizontalLineToRelative(96.757f)
curveToRelative(-5.648f, -7.803f, -12.978f, -6.398f, -22.037f, -10.163f)
curveToRelative(-9.516f, -3.956f, -14.557f, -9.591f, -27.043f, -7.551f)
curveToRelative(-9.571f, 1.564f, -14.284f, 7.555f, -22.675f, 10.005f)
curveToRelative(-9.678f, 2.827f, -17.397f, 1.076f, -25.003f, 7.709f)
close()
}
}
.build()
return customHashTagIconsGrowNostr!!
}
private var customHashTagIconsGrowNostr: ImageVector? = null

Wyświetl plik

@ -0,0 +1,201 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsLightningPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Lightning,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Lightning: ImageVector
get() {
if (customHashTagIconsLightning != null) {
return customHashTagIconsLightning!!
}
customHashTagIconsLightning =
Builder(
name = "Lightning",
defaultWidth = 512.0.dp,
defaultHeight = 512.0.dp,
viewportWidth = 512.0f,
viewportHeight = 512.0f,
).apply {
path(
fill = SolidColor(Color(0xFFfeb804)),
stroke = null,
strokeLineWidth = 1.04238f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(405.814f, 0.318f)
curveTo(398.493f, 10.851f, 392.367f, 18.665f, 387.207f, 28.095f)
curveTo(347.366f, 84.635f, 306.066f, 140.12f, 265.203f, 195.919f)
curveToRelative(-6.717f, 6.205f, -2.232f, 18.181f, 7.303f, 15.634f)
curveToRelative(15.682f, 3.42f, 21.453f, -10.422f, 21.453f, -10.422f)
curveToRelative(0.0f, 0.0f, 77.893f, -124.006f, 115.841f, -186.586f)
curveToRelative(2.589f, -5.525f, 4.24f, -14.798f, -3.986f, -14.226f)
close()
}
path(
fill = SolidColor(Color(0xFFffc927)),
stroke = null,
strokeLineWidth = 1.04238f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(134.106f, 269.928f)
lineToRelative(84.145f, -1.043f)
lineToRelative(23.28f, 8.339f)
lineToRelative(-22.137f, 38.786f)
lineToRelative(-109.766f, 188.455f)
lineToRelative(3.586f, 0.316f)
lineToRelative(279.741f, -251.785f)
lineToRelative(45.052f, -42.484f)
lineToRelative(-136.776f, 0.479f)
lineToRelative(-35.283f, -0.668f)
lineTo(406.128f, 0.168f)
curveToRelative(0.0f, 0.0f, -223.081f, 181.661f, -329.737f, 270.145f)
lineToRelative(-1.05f, 0.837f)
close()
}
path(
fill = SolidColor(Color(0xFFfeb804)),
stroke = null,
strokeLineWidth = 1.04238f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(109.658f, 504.464f)
curveToRelative(0.641f, 10.482f, 14.136f, 7.316f, 18.777f, 1.428f)
curveToRelative(110.113f, -98.518f, 227.418f, -195.827f, 322.374f, -283.083f)
curveToRelative(2.864f, -9.815f, -3.787f, -12.451f, -12.851f, -12.166f)
curveToRelative(-78.496f, 71.808f, -160.716f, 147.927f, -240.441f, 218.409f)
curveToRelative(-26.97f, 23.781f, -53.639f, 47.901f, -80.56f, 71.73f)
curveToRelative(-2.157f, 1.697f, -4.601f, 3.112f, -7.299f, 3.683f)
close()
moveTo(233.742f, 290.738f)
curveToRelative(6.731f, -10.679f, 15.607f, -23.143f, -0.042f, -21.833f)
curveToRelative(-52.452f, -0.003f, -100.964f, 0.787f, -149.966f, 2.256f)
curveToRelative(-7.988f, -0.012f, -8.925f, -2.348f, -12.914f, 9.06f)
curveToRelative(-4.908f, 14.035f, 13.177f, 11.664f, 21.968f, 11.597f)
curveToRelative(42.7f, -0.17f, 85.448f, 0.628f, 128.072f, -1.042f)
curveToRelative(4.996f, -0.006f, 7.714f, -0.11f, 12.882f, -0.037f)
close()
}
path(
fill = SolidColor(Color(0xFFffe567)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(295.999f, 97.743f)
curveToRelative(-8.582f, 4.871f, -15.257f, 12.447f, -22.999f, 18.528f)
curveToRelative(-35.757f, 30.897f, -71.357f, 61.981f, -107.631f, 92.275f)
curveTo(151.571f, 220.667f, 137.064f, 232.031f, 124.044f, 245.0f)
curveToRelative(-4.429f, 3.727f, -6.853f, 10.687f, -2.838f, 15.612f)
curveToRelative(5.438f, 7.373f, 15.928f, 3.727f, 21.794f, -1.137f)
curveToRelative(10.009f, -8.23f, 19.205f, -17.381f, 28.703f, -26.179f)
curveToRelative(10.022f, -9.859f, 19.614f, -20.178f, 30.297f, -29.335f)
curveToRelative(9.805f, -9.67f, 19.298f, -19.671f, 29.707f, -28.698f)
curveToRelative(9.648f, -9.595f, 19.134f, -19.361f, 29.354f, -28.349f)
curveToRelative(10.458f, -10.354f, 20.912f, -20.716f, 30.727f, -31.678f)
curveToRelative(3.954f, -4.612f, 10.405f, -8.489f, 10.761f, -15.087f)
curveToRelative(-0.53f, -3.162f, -4.126f, -3.243f, -6.55f, -2.405f)
close()
}
path(
fill = SolidColor(Color(0xFFffd84b)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(265.0f, 273.668f)
curveToRelative(-10.032f, 4.073f, -14.755f, 14.571f, -20.726f, 22.922f)
curveToRelative(-7.915f, 11.998f, -15.59f, 24.152f, -23.688f, 36.032f)
curveToRelative(-6.853f, 10.398f, -13.505f, 20.926f, -20.449f, 31.265f)
curveToRelative(-7.068f, 11.266f, -14.611f, 22.226f, -21.705f, 33.476f)
curveToRelative(-4.087f, 6.761f, -9.122f, 13.119f, -11.751f, 20.637f)
curveToRelative(-1.054f, 3.042f, 1.146f, 7.25f, 4.719f, 6.307f)
curveToRelative(5.831f, -1.77f, 8.704f, -7.808f, 12.382f, -12.187f)
curveToRelative(29.287f, -39.128f, 58.731f, -78.141f, 87.916f, -117.344f)
curveToRelative(3.727f, -5.003f, 6.11f, -12.684f, 2.56f, -18.382f)
curveToRelative(-2.25f, -2.576f, -5.963f, -3.682f, -9.258f, -2.726f)
close()
}
path(
fill = SolidColor(Color(0xFFffd84b)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(276.0f, 279.0f)
lineTo(276.0f, 285.0f)
lineTo(276.582f, 283.918f)
lineTo(276.628f, 283.502f)
lineTo(276.806f, 282.738f)
lineTo(276.806f, 281.262f)
lineTo(276.628f, 280.498f)
lineTo(276.582f, 280.082f)
lineTo(276.0f, 279.0f)
close()
}
}
.build()
return customHashTagIconsLightning!!
}
private var customHashTagIconsLightning: ImageVector? = null

Wyświetl plik

@ -0,0 +1,240 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsMatePreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Mate,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Mate: ImageVector
get() {
if (customHashTagIconsMate != null) {
return customHashTagIconsMate!!
}
customHashTagIconsMate =
Builder(
name = "Mate",
defaultWidth = 800.0.dp,
defaultHeight = 800.0.dp,
viewportWidth = 128.0f,
viewportHeight = 128.0f,
).apply {
path(
fill = SolidColor(Color(0xFF865c52)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(31.448f, 53.887f)
curveToRelative(0.0f, 0.0f, -12.564f, 15.55f, -11.963f, 32.693f)
curveToRelative(0.601f, 17.143f, 10.37f, 40.868f, 44.856f, 41.66f)
curveTo(98.827f, 129.041f, 112.024f, 99.44f, 107.203f, 78.805f)
curveTo(102.308f, 57.843f, 91.653f, 51.092f, 91.653f, 51.092f)
close()
}
path(
fill = SolidColor(Color(0xFFb0b0b0)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(30.625f, 55.037f)
curveToRelative(0.0f, 0.0f, 0.084f, -1.783f, 0.77f, -3.945f)
curveToRelative(0.622f, -1.983f, 1.793f, -3.977f, 1.793f, -3.977f)
curveToRelative(24.589f, 17.122f, 31.545f, 15.636f, 56.059f, 5.349f)
curveToRelative(1.192f, -0.433f, 1.502f, -7.396f, 1.502f, -7.396f)
curveToRelative(0.0f, 0.0f, 3.077f, 3.619f, 3.889f, 6.605f)
curveToRelative(0.475f, 1.73f, 0.454f, 3.756f, 0.454f, 3.756f)
curveToRelative(0.0f, 0.0f, 0.696f, 6.161f, -11.362f, 13.704f)
curveTo(71.609f, 76.706f, 50.036f, 75.018f, 39.592f, 67.401f)
curveTo(31.585f, 61.546f, 30.625f, 55.037f, 30.625f, 55.037f)
close()
}
path(
fill = SolidColor(Color(0xFFe0e0e0)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(32.692f, 49.889f)
curveTo(32.503f, 58.867f, 48.77f, 66.547f, 62.094f, 66.631f)
curveTo(79.943f, 66.736f, 92.813f, 58.223f, 92.813f, 50.079f)
curveTo(87.333f, 24.888f, 34.137f, 29.554f, 32.692f, 49.889f)
close()
}
path(
fill = SolidColor(Color(0xFF858585)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(79.447f, 42.188f)
curveToRelative(-4.954f, -6.746f, -36.696f, -8.061f, -36.955f, 5.591f)
curveToRelative(0.19f, 7.3f, 9.642f, 8.302f, 9.642f, 8.302f)
lineToRelative(24.38f, -3.745f)
close()
}
path(
fill = SolidColor(Color(0xFF96a520)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(75.47f, 47.589f)
curveToRelative(0.0f, 0.0f, -3.597f, -3.123f, -13.746f, -3.123f)
curveToRelative(-10.149f, 0.0f, -15.729f, 3.407f, -16.204f, 6.825f)
curveToRelative(-0.274f, 1.973f, 0.285f, 2.469f, 0.285f, 2.469f)
curveToRelative(0.0f, 0.0f, 5.686f, 4.357f, 17.438f, 4.167f)
curveToRelative(11.752f, -0.19f, 13.461f, -2.279f, 13.461f, -2.279f)
close()
}
path(
fill = SolidColor(Color(0xFFe0e0e0)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(69.594f, 58.582f)
curveToRelative(0.0f, 0.0f, 15.824f, -30.519f, 17.248f, -32.028f)
curveTo(88.267f, 25.045f, 111.567f, 0.039f, 111.567f, 0.039f)
lineToRelative(3.597f, 3.218f)
lineToRelative(-6.537f, 7.473f)
curveToRelative(0.0f, 0.0f, -17.628f, 19.527f, -17.913f, 20.371f)
curveToRelative(-0.285f, 0.854f, -9.568f, 19.801f, -9.948f, 20.466f)
curveToRelative(-0.38f, 0.665f, -2.089f, 7.3f, -2.469f, 7.395f)
curveToRelative(-0.369f, 0.095f, -8.703f, -0.38f, -8.703f, -0.38f)
close()
}
path(
fill = SolidColor(Color(0xFFb0b0b0)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(76.135f, 56.018f)
curveToRelative(0.0f, 0.0f, 13.081f, -25.392f, 13.841f, -26.627f)
curveTo(90.735f, 28.157f, 114.51f, 2.645f, 114.51f, 2.645f)
lineToRelative(1.793f, 1.593f)
curveToRelative(0.0f, 0.0f, -22.973f, 25.798f, -23.67f, 26.758f)
curveToRelative(-0.992f, 1.361f, -11.921f, 22.776f, -11.921f, 22.776f)
curveToRelative(0.0f, 0.0f, -1.076f, 0.77f, -1.888f, 1.192f)
curveToRelative(-1.477f, 0.76f, -2.69f, 1.055f, -2.69f, 1.055f)
close()
}
path(
fill = SolidColor(Color(0xFFb0b0b0)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(95.841f, 15.277f)
curveToRelative(-0.475f, -0.105f, -3.882f, 3.407f, -3.692f, 3.977f)
curveToRelative(0.19f, 0.57f, 5.486f, 5.57f, 6.34f, 5.855f)
curveToRelative(0.854f, 0.285f, 3.692f, -3.313f, 3.787f, -3.692f)
curveToRelative(0.095f, -0.38f, -5.581f, -5.95f, -6.435f, -6.14f)
close()
}
path(
fill = SolidColor(Color(0xFFffffff)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(95.651f, 16.88f)
curveToRelative(-1.15f, 0.0f, -1.582f, 0.992f, -1.614f, 1.994f)
curveToRelative(-0.032f, 1.139f, 0.475f, 1.994f, 1.614f, 1.994f)
curveToRelative(1.139f, 0.0f, 1.614f, -1.139f, 1.614f, -2.089f)
curveToRelative(0.0f, -0.949f, -0.57f, -1.899f, -1.614f, -1.899f)
close()
}
path(
fill = SolidColor(Color(0xFFb78859)),
stroke = null,
strokeLineWidth = 1.05494f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(30.762f, 67.285f)
curveToRelative(-1.435f, -0.116f, -5.939f, 7.131f, -6.171f, 15.286f)
curveToRelative(-0.243f, 8.155f, 1.857f, 14.147f, 3.355f, 14.326f)
curveToRelative(1.983f, 0.243f, 3.123f, -6.351f, 5.697f, -11.509f)
curveToRelative(2.553f, -5.116f, 6.773f, -8.513f, 6.709f, -10.075f)
curveToRelative(-0.063f, -1.561f, -3.239f, -2.88f, -5.275f, -4.557f)
curveToRelative(-2.036f, -1.667f, -3.397f, -3.386f, -4.315f, -3.471f)
close()
}
}
.build()
return customHashTagIconsMate!!
}
private var customHashTagIconsMate: ImageVector? = null

Wyświetl plik

@ -0,0 +1,151 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsNostrPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Nostr,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Nostr: ImageVector
get() {
if (customHashTagIconsNostr != null) {
return customHashTagIconsNostr!!
}
customHashTagIconsNostr =
Builder(
name = "Nostr",
defaultWidth = 256.0.dp,
defaultHeight = 256.0.dp,
viewportWidth = 256.0f,
viewportHeight = 256.0f,
).apply {
path(
fill = SolidColor(Color(0xFF9d5aff)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 0.488346f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(59.661f, 98.547f)
curveToRelative(-3.007f, -0.988f, -5.63f, -2.705f, -8.79f, -3.204f)
curveToRelative(-9.733f, -1.536f, -20.022f, 2.618f, -26.776f, 9.596f)
curveToRelative(-3.489f, 3.604f, -6.176f, 8.376f, -7.721f, 13.141f)
curveToRelative(-0.436f, 1.344f, -1.365f, 4.295f, 0.119f, 5.337f)
curveToRelative(2.359f, 1.655f, 8.252f, -3.372f, 11.426f, -2.895f)
curveToRelative(-1.501f, 3.387f, -3.098f, 7.468f, -2.907f, 11.232f)
curveToRelative(0.108f, 2.137f, 1.374f, 4.428f, 3.883f, 3.603f)
curveToRelative(4.417f, -1.452f, 6.135f, -7.225f, 11.232f, -7.998f)
curveToRelative(-0.81f, 2.489f, -4.209f, 10.816f, -0.821f, 12.632f)
curveToRelative(2.253f, 1.208f, 6.274f, -2.466f, 8.147f, -3.46f)
curveToRelative(5.717f, -3.037f, 13.492f, -5.564f, 20.022f, -5.725f)
curveToRelative(4.769f, -0.118f, 9.389f, 4.766f, 13.674f, 6.6f)
curveToRelative(9.014f, 3.857f, 18.45f, 5.866f, 27.836f, 8.51f)
curveToRelative(-5.549f, 8.157f, -12.991f, 15.022f, -20.999f, 20.758f)
curveToRelative(-3.104f, 2.223f, -6.98f, 2.751f, -9.663f, 5.658f)
curveToRelative(-3.017f, 3.269f, -3.081f, 8.023f, -5.478f, 11.675f)
curveToRelative(-7.682f, 11.702f, -15.816f, 23.585f, -24.366f, 34.671f)
curveToRelative(-4.329f, 5.614f, -12.746f, 3.903f, -16.651f, 10.259f)
curveToRelative(-2.622f, 4.27f, -0.247f, 6.045f, 3.904f, 4.881f)
curveToRelative(-2.736f, 4.934f, -6.406f, 10.19f, -6.222f, 16.115f)
curveToRelative(0.05f, 1.59f, 0.543f, 5.759f, 2.779f, 5.759f)
curveToRelative(2.164f, 0.0f, 4.639f, -7.04f, 5.847f, -8.689f)
curveToRelative(3.137f, -4.28f, 7.228f, -7.629f, 10.552f, -11.72f)
curveToRelative(3.062f, -3.768f, 5.291f, -8.248f, 8.111f, -12.209f)
curveToRelative(8.287f, -11.637f, 16.547f, -24.861f, 26.627f, -35.027f)
curveToRelative(2.386f, -2.407f, 6.005f, -2.902f, 8.361f, -5.527f)
curveToRelative(1.995f, -2.223f, 2.178f, -5.462f, 4.159f, -7.566f)
curveToRelative(2.812f, -2.986f, 6.83f, -5.276f, 10.107f, -7.734f)
curveToRelative(7.554f, -5.666f, 14.832f, -11.354f, 24.417f, -13.003f)
curveToRelative(-1.823f, 3.395f, -3.652f, 6.661f, -5.078f, 10.255f)
curveToRelative(-2.06f, 5.191f, -6.035f, 18.045f, 4.102f, 17.527f)
curveToRelative(3.787f, -0.193f, 6.345f, -3.143f, 9.767f, -4.321f)
curveToRelative(8.992f, -3.096f, 18.219f, -5.857f, 27.347f, -8.53f)
curveToRelative(3.83f, -1.122f, 8.137f, -3.336f, 12.206f, -3.164f)
curveToRelative(5.052f, 0.214f, 2.044f, 7.862f, 6.837f, 9.154f)
curveToRelative(2.993f, 0.806f, 2.123f, -4.518f, 2.444f, -6.272f)
horizontalLineToRelative(0.977f)
curveToRelative(1.795f, 3.46f, 5.276f, 6.668f, 8.79f, 8.382f)
curveToRelative(1.126f, 0.549f, 3.41f, 1.458f, 4.36f, 0.113f)
curveToRelative(1.265f, -1.789f, -1.49f, -5.133f, -2.407f, -6.542f)
curveToRelative(-3.31f, -5.087f, -6.927f, -14.399f, -13.185f, -16.287f)
curveToRelative(-5.581f, -1.684f, -12.344f, 1.201f, -17.58f, 2.939f)
curveToRelative(-10.983f, 3.644f, -22.076f, 7.259f, -33.208f, 10.418f)
curveToRelative(3.008f, -6.434f, 7.233f, -8.024f, 12.105f, -12.467f)
curveToRelative(1.697f, -1.548f, 2.297f, -4.404f, 4.545f, -5.307f)
curveToRelative(3.951f, -1.587f, 10.787f, -0.53f, 15.093f, -0.827f)
curveToRelative(7.661f, -0.528f, 15.199f, -2.598f, 21.976f, -6.198f)
curveToRelative(8.972f, -4.766f, 13.782f, -12.659f, 14.999f, -22.57f)
curveToRelative(0.42f, -3.42f, -1.094f, -8.668f, 0.703f, -11.694f)
curveToRelative(2.713f, -4.568f, 11.302f, -7.601f, 15.552f, -10.833f)
curveToRelative(9.871f, -7.51f, 17.983f, -19.995f, 18.538f, -32.656f)
curveToRelative(0.468f, -10.684f, -3.262f, -19.679f, -11.232f, -26.859f)
curveToRelative(-4.153f, -3.741f, -13.686f, -8.055f, -14.511f, -14.162f)
curveToRelative(-0.469f, -3.475f, 3.193f, -4.011f, 5.74f, -4.742f)
curveToRelative(6.568f, -1.886f, 13.618f, 0.286f, 20.022f, -1.607f)
verticalLineToRelative(-0.977f)
lineToRelative(-6.837f, -2.93f)
lineToRelative(6.837f, -0.488f)
verticalLineTo(12.598f)
curveTo(234.765f, 10.283f, 229.423f, 9.599f, 224.722f, 7.462f)
curveTo(216.79f, 3.856f, 206.396f, -5.601f, 200.733f, 7.226f)
curveToRelative(-8.514f, 19.283f, 8.555f, 30.24f, 20.552f, 41.592f)
curveToRelative(6.761f, 6.397f, 8.068f, 17.66f, 2.564f, 25.31f)
curveToRelative(-6.537f, 9.087f, -14.684f, 6.861f, -24.032f, 6.876f)
curveToRelative(-2.628f, 0.004f, -5.212f, 1.652f, -7.814f, 1.216f)
curveToRelative(-3.827f, -0.641f, -7.492f, -3.968f, -10.744f, -5.919f)
curveToRelative(-5.155f, -3.093f, -10.679f, -5.645f, -16.604f, -6.837f)
curveToRelative(-15.82f, -3.183f, -32.068f, -0.627f, -46.881f, 5.374f)
curveToRelative(-9.526f, 3.859f, -18.321f, 9.347f, -27.836f, 13.232f)
curveToRelative(-7.302f, 2.981f, -15.15f, 3.639f, -22.952f, 3.639f)
curveToRelative(-2.1f, 0.0f, -7.822f, -0.993f, -9.263f, 0.851f)
curveToRelative(-1.387f, 1.776f, 0.99f, 4.574f, 1.938f, 5.986f)
close()
}
}
.build()
return customHashTagIconsNostr!!
}
private var customHashTagIconsNostr: ImageVector? = null

Wyświetl plik

@ -0,0 +1,174 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsPlebsPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Plebs,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Plebs: ImageVector
get() {
if (customHashTagIconsPlebs != null) {
return customHashTagIconsPlebs!!
}
customHashTagIconsPlebs =
Builder(
name = "Plebs",
defaultWidth = 512.0.dp,
defaultHeight = 512.0.dp,
viewportWidth = 512.0f,
viewportHeight = 512.0f,
).apply {
path(
fill = SolidColor(Color(0xFF226699)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(240.077f, 212.39f)
curveToRelative(36.868f, -40.178f, 42.776f, -59.05f, 41.127f, -100.9f)
curveTo(277.003f, 50.197f, 219.658f, -13.101f, 154.473f, 3.27f)
curveTo(98.991f, 29.166f, 78.406f, 76.673f, 87.059f, 130.375f)
curveToRelative(3.326f, 19.783f, 11.266f, 38.916f, 23.309f, 55.0f)
curveToRelative(3.8f, 5.075f, 7.79f, 10.561f, 13.105f, 14.15f)
curveToRelative(29.583f, 11.547f, 63.268f, 28.18f, 92.0f, 32.55f)
curveToRelative(49.403f, 5.055f, 16.317f, 4.066f, 24.603f, -19.685f)
close()
}
path(
fill = SolidColor(Color(0xFF55acee)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(267.474f, 229.375f)
curveToRelative(-25.724f, 6.127f, -53.175f, 4.359f, -76.0f, -3.344f)
curveToRelative(-20.816f, -7.201f, -41.714f, -15.31f, -62.0f, -23.887f)
curveToRelative(-13.664f, -5.778f, -26.841f, -12.787f, -42.0f, -12.769f)
curveToRelative(-10.835f, 0.013f, -25.743f, 2.166f, -33.787f, 10.213f)
curveToRelative(-12.713f, 12.718f, -10.628f, 39.822f, 0.116f, 52.786f)
curveToRelative(7.998f, 9.651f, 20.694f, 14.759f, 31.671f, 20.248f)
curveToRelative(23.899f, 11.95f, 48.7f, 21.898f, 73.0f, 32.984f)
curveToRelative(10.316f, 4.706f, 26.02f, 8.833f, 33.387f, 17.874f)
curveToRelative(8.391f, 10.296f, 7.94f, 31.972f, 8.203f, 44.715f)
curveToRelative(9.824f, 0.0f, 21.748f, -2.388f, 31.41f, -4.334f)
curveToRelative(25.64f, -5.163f, 48.792f, -18.568f, 71.0f, -31.886f)
curveToRelative(19.64f, -11.777f, 43.51f, -31.471f, 68.0f, -22.638f)
curveToRelative(21.493f, 7.752f, 29.192f, 33.234f, 20.099f, 53.038f)
curveToRelative(-4.477f, 9.75f, -12.742f, 16.526f, -21.099f, 22.87f)
curveToRelative(-47.953f, 36.402f, -106.388f, 61.13f, -167.0f, 61.13f)
verticalLineToRelative(44.0f)
curveToRelative(0.572f, 13.763f, -3.286f, 20.249f, 13.0f, 21.83f)
curveToRelative(77.697f, 0.656f, 162.39f, 0.17f, 231.0f, 0.17f)
curveToRelative(8.367f, 0.0f, 21.25f, 2.254f, 22.811f, -9.0f)
curveToRelative(2.183f, -15.737f, 0.189f, -33.106f, 0.189f, -49.0f)
curveToRelative(-0.454f, -63.006f, -2.273f, -108.366f, -12.6f, -160.0f)
curveToRelative(-2.129f, -10.578f, -4.935f, -21.419f, -13.44f, -28.848f)
curveToRelative(-6.41f, -5.599f, -18.729f, 2.108f, -25.96f, 4.103f)
curveToRelative(-19.393f, 5.349f, -53.736f, 8.081f, -62.79f, -15.255f)
curveToRelative(-9.333f, -24.054f, 13.943f, -39.798f, 28.789f, -54.039f)
curveToRelative(33.42f, -27.883f, 43.86f, -89.356f, 34.576f, -125.961f)
curveToRelative(-19.6f, -76.144f, -102.286f, -105.041f, -163.006f, -34.0f)
curveToRelative(-2.71f, 5.553f, 4.587f, 12.392f, 7.119f, 17.0f)
curveToRelative(7.798f, 14.19f, 12.877f, 29.076f, 15.697f, 45.0f)
curveToRelative(4.022f, 22.71f, 0.21f, 46.903f, -8.812f, 68.0f)
curveToRelative(-1.202f, 8.804f, -13.792f, 19.122f, -14.666f, 26.0f)
curveToRelative(-0.543f, 5.907f, 8.62f, 9.855f, 11.49f, 14.09f)
curveToRelative(3.233f, 4.77f, 1.603f, 13.383f, 1.603f, 18.91f)
close()
}
path(
fill = SolidColor(Color(0xFF226699)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(359.659f, 263.19f)
curveToRelative(19.058f, 20.658f, 79.633f, 9.792f, 95.853f, -13.816f)
curveToRelative(8.684f, -13.517f, 9.701f, -39.101f, -3.132f, -50.67f)
curveToRelative(-38.377f, -27.49f, -128.225f, 26.091f, -92.721f, 64.486f)
close()
}
path(
fill = SolidColor(Color(0xFF226699)),
stroke = null,
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(202.93f, 505.36f)
curveToRelative(0.592f, -18.533f, -1.138f, -37.925f, -0.752f, -57.165f)
curveToRelative(14.334f, 0.0f, 28.111f, -2.78f, 42.295f, -5.144f)
curveToRelative(44.725f, -7.454f, 88.978f, -29.993f, 125.0f, -57.051f)
curveToRelative(8.087f, -6.074f, 16.01f, -12.398f, 20.623f, -21.625f)
curveToRelative(9.25f, -18.499f, 3.946f, -45.809f, -16.623f, -54.07f)
curveToRelative(-19.995f, -8.031f, -39.101f, 1.93f, -56.0f, 12.07f)
curveToRelative(-23.173f, 13.905f, -46.408f, 28.636f, -72.0f, 37.691f)
curveToRelative(-10.636f, 2.618f, -32.577f, 8.464f, -41.852f, 4.706f)
curveToRelative(-3.523f, -16.694f, -3.297f, -31.795f, -11.761f, -42.184f)
curveToRelative(-24.67f, -17.172f, -70.541f, -35.836f, -115.387f, -54.994f)
curveToRelative(-2.592f, -1.367f, -5.913f, -4.179f, -9.0f, -3.967f)
curveToRelative(-4.748f, 0.327f, -8.884f, 7.105f, -11.07f, 10.748f)
curveToRelative(-22.391f, 67.401f, -18.925f, 158.864f, -18.93f, 219.0f)
curveToRelative(0.219f, 13.623f, -0.386f, 18.984f, 15.0f, 19.0f)
horizontalLineToRelative(30.0f)
curveToRelative(23.685f, -4.025f, 130.22f, 11.249f, 120.457f, -7.015f)
close()
}
}
.build()
return customHashTagIconsPlebs!!
}
private var customHashTagIconsPlebs: ImageVector? = null

Wyświetl plik

@ -0,0 +1,556 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
public val CustomHashTagIcons.Skull: ImageVector
get() {
if (customHashTagIconsSkull != null) {
return customHashTagIconsSkull!!
}
customHashTagIconsSkull =
Builder(
name = "Skull",
defaultWidth = 521.0.dp,
defaultHeight = 521.0.dp,
viewportWidth = 521.0f,
viewportHeight = 521.0f,
).apply {
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(166.043f, 80.017f)
curveToRelative(-17.589f, -6.803f, -44.532f, 4.017f, -36.944f, 26.703f)
curveToRelative(2.102f, 23.626f, 5.968f, 47.166f, 3.466f, 70.986f)
curveToRelative(-2.736f, 24.018f, -32.144f, 35.563f, -36.128f, 61.121f)
curveToRelative(-17.98f, 47.592f, -10.437f, 101.14f, 7.34f, 147.588f)
curveToRelative(-5.494f, 19.929f, -10.791f, 48.409f, 11.267f, 61.19f)
curveToRelative(17.725f, 13.076f, 40.748f, 11.293f, 60.405f, 18.039f)
curveToRelative(20.504f, 12.317f, -10.44f, 42.989f, 15.691f, 51.945f)
curveToRelative(18.095f, 2.854f, 17.827f, 3.664f, 56.455f, 3.83f)
curveToRelative(23.285f, 0.371f, 51.137f, 0.264f, 66.031f, -3.178f)
curveToRelative(17.85f, -3.738f, 39.299f, -7.904f, 29.227f, -32.481f)
curveToRelative(0.752f, -28.566f, 30.293f, -42.617f, 54.417f, -48.439f)
curveToRelative(24.039f, -0.976f, 29.123f, -26.788f, 19.494f, -44.696f)
curveToRelative(-5.32f, -21.481f, 6.117f, -42.357f, 4.253f, -64.147f)
curveToRelative(9.219f, -22.321f, 5.234f, -47.011f, 3.786f, -70.404f)
curveToRelative(-3.119f, -31.072f, -19.988f, -60.885f, -47.911f, -76.091f)
curveToRelative(-19.16f, -14.769f, -41.795f, -26.32f, -51.946f, -49.919f)
curveToRelative(-13.211f, -19.23f, -10.244f, -46.183f, -25.23f, -63.732f)
curveToRelative(-12.877f, -9.258f, -34.33f, 6.801f, -32.652f, -16.298f)
curveToRelative(-4.238f, -18.497f, -22.619f, -63.827f, -43.895f, -35.805f)
curveToRelative(-0.798f, 10.205f, 6.997f, 46.603f, -3.089f, 20.067f)
curveToRelative(-8.914f, -17.607f, -6.239f, -23.9f, -23.011f, -35.866f)
curveToRelative(-33.287f, -3.665f, -17.661f, 22.157f, -29.248f, 36.91f)
curveToRelative(-11.198f, 9.777f, -1.801f, 29.625f, -1.778f, 42.677f)
close()
}
path(
fill = SolidColor(Color(0xFF29b34a)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(197.415f, 67.468f)
curveToRelative(10.404f, -9.938f, 32.503f, -7.129f, 19.032f, -25.224f)
curveToRelative(-10.229f, -16.227f, -7.149f, -34.882f, -28.123f, -37.024f)
curveToRelative(-13.71f, 16.666f, -8.256f, 27.409f, 3.864f, 41.459f)
curveToRelative(2.333f, 6.769f, 3.635f, 13.825f, 5.226f, 20.789f)
close()
}
path(
fill = SolidColor(Color(0xFF136c37)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(253.885f, 115.571f)
curveToRelative(2.506f, -17.598f, -3.283f, -35.978f, 9.784f, -50.514f)
curveToRelative(-6.679f, -17.003f, -8.374f, -38.331f, -21.776f, -51.311f)
curveToRelative(-23.222f, -3.057f, -6.865f, 32.18f, -7.339f, 44.922f)
curveToRelative(15.503f, 13.029f, 12.399f, 35.878f, 18.82f, 53.612f)
close()
}
path(
fill = SolidColor(Color(0xFF136c37)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(169.184f, 49.392f)
curveToRelative(-0.974f, 1.101f, -1.704f, 6.811f, 6.669f, 43.023f)
curveToRelative(6.056f, 18.193f, 12.642f, 46.965f, 24.448f, 57.302f)
curveToRelative(2.53f, -36.482f, -3.511f, -73.178f, -18.599f, -106.116f)
curveToRelative(-2.683f, -5.857f, -9.241f, 2.216f, -12.518f, 5.791f)
close()
}
path(
fill = SolidColor(Color(0xFF29b34a)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(204.735f, 104.068f)
curveToRelative(0.625f, -7.842f, 3.927f, -37.846f, 6.899f, -19.429f)
curveToRelative(-3.324f, 23.587f, -5.05f, 47.144f, -4.767f, 71.229f)
curveToRelative(-0.842f, 28.442f, -19.717f, -11.418f, -22.985f, -22.25f)
curveToRelative(-10.169f, -15.42f, -5.614f, -50.82f, -31.301f, -48.375f)
curveToRelative(-28.193f, -1.433f, -14.516f, 32.27f, -14.95f, 49.151f)
curveToRelative(3.377f, 16.605f, -2.993f, 44.197f, 2.46f, 54.009f)
curveToRelative(15.805f, -3.46f, -17.136f, 24.032f, -21.739f, 34.012f)
curveToRelative(-27.954f, 42.526f, -22.507f, 97.338f, -10.089f, 144.233f)
curveToRelative(1.337f, 14.758f, 3.425f, 18.522f, 17.299f, 14.775f)
curveToRelative(-10.154f, 11.186f, -29.782f, 28.985f, -13.96f, 47.862f)
curveToRelative(14.781f, 25.267f, 46.309f, 12.627f, 66.711f, 26.555f)
curveToRelative(16.958f, 5.175f, 5.17f, 30.138f, 22.723f, 23.089f)
curveToRelative(9.803f, 7.155f, 9.208f, 22.008f, 19.428f, 5.38f)
curveToRelative(19.77f, -21.954f, 28.472f, 35.563f, 35.96f, 6.99f)
curveToRelative(4.723f, -20.5f, 27.271f, -14.175f, 31.971f, 2.826f)
curveToRelative(3.478f, -14.209f, 17.353f, -16.833f, 26.143f, -5.229f)
curveToRelative(9.612f, -16.096f, 27.492f, -17.179f, 35.903f, -35.211f)
curveToRelative(12.955f, -16.257f, 34.621f, -16.627f, 51.515f, -25.791f)
curveToRelative(17.619f, -15.141f, 3.569f, -40.186f, -5.852f, -56.119f)
curveToRelative(17.858f, 12.186f, 9.98f, -26.685f, 16.119f, -38.692f)
curveToRelative(7.231f, -36.187f, 12.769f, -76.041f, -5.908f, -109.896f)
curveToRelative(-14.865f, -32.017f, -48.573f, -51.652f, -82.978f, -54.865f)
curveToRelative(-28.394f, -9.939f, 30.195f, -0.921f, 8.313f, -16.557f)
curveToRelative(-19.659f, -20.983f, -23.944f, -50.275f, -32.649f, -76.299f)
curveToRelative(-11.311f, -10.062f, -41.455f, -4.621f, -30.088f, 9.78f)
curveToRelative(-0.115f, 11.714f, -7.056f, 27.874f, -5.351f, 6.936f)
curveToRelative(1.89f, -16.451f, -3.848f, -11.097f, -1.641f, 1.757f)
curveToRelative(-0.075f, 15.923f, 3.317f, 46.987f, -3.507f, 53.766f)
curveToRelative(-11.535f, -23.034f, -15.183f, -49.22f, -20.725f, -74.156f)
curveToRelative(-11.236f, -22.76f, -44.567f, -8.538f, -33.969f, 21.585f)
curveToRelative(0.542f, 2.957f, 0.77f, 5.943f, 1.016f, 8.934f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(141.992f, 137.532f)
curveToRelative(5.433f, -6.563f, 6.768f, -44.708f, -3.759f, -38.139f)
curveToRelative(-0.113f, 12.72f, 4.244f, 25.288f, 3.759f, 38.139f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(190.095f, 178.763f)
curveToRelative(-23.353f, 4.429f, -48.582f, 19.127f, -56.055f, 42.868f)
curveToRelative(-2.024f, 30.081f, 23.868f, 1.519f, 32.26f, -8.593f)
curveToRelative(9.022f, -13.104f, 39.168f, -19.981f, 37.211f, -34.476f)
curveToRelative(-4.434f, -1.085f, -8.984f, -0.392f, -13.416f, 0.201f)
close()
}
path(
fill = SolidColor(Color(0xFFffffff)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(137.809f, 233.739f)
curveToRelative(18.974f, -10.812f, 30.284f, -32.523f, 50.837f, -42.381f)
curveToRelative(10.081f, -4.822f, 18.905f, -12.577f, 1.877f, -9.752f)
curveToRelative(-23.615f, 5.699f, -57.72f, 22.986f, -52.714f, 52.132f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(176.501f, 382.232f)
curveToRelative(-10.891f, 10.084f, -47.394f, -14.781f, -33.154f, 10.003f)
curveToRelative(22.963f, 15.302f, 54.036f, 2.594f, 73.061f, -13.679f)
curveToRelative(25.349f, -20.634f, 34.476f, -66.262f, 5.31f, -87.733f)
curveToRelative(-28.868f, -23.834f, -81.683f, -12.071f, -90.905f, 26.166f)
curveToRelative(-5.558f, 28.613f, 14.865f, 63.502f, 45.688f, 65.243f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(380.418f, 379.095f)
curveToRelative(-10.317f, 0.003f, -50.27f, 12.128f, -23.121f, 1.307f)
curveToRelative(34.329f, -13.642f, 44.659f, -68.986f, 10.941f, -89.151f)
curveToRelative(-29.709f, -20.531f, -81.334f, -7.617f, -88.304f, 30.567f)
curveToRelative(-5.964f, 36.873f, 22.869f, 76.762f, 61.704f, 76.249f)
curveToRelative(13.693f, -0.457f, 36.367f, -1.58f, 38.78f, -18.972f)
close()
}
path(
fill = SolidColor(Color(0xFFffffff)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(178.592f, 317.397f)
curveToRelative(-1.612f, 19.729f, 20.895f, -2.92f, 0.0f, 0.0f)
close()
}
path(
fill = SolidColor(Color(0xFFffffff)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(333.36f, 318.443f)
curveToRelative(-9.346f, 14.816f, 15.03f, 7.845f, 3.202f, 1.021f)
close()
}
path(
fill = SolidColor(Color(0xFFffffff)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(182.775f, 346.677f)
curveToRelative(19.051f, 3.541f, 12.908f, -18.621f, -0.321f, -6.868f)
curveToRelative(-0.441f, 2.36f, -1.198f, 4.037f, 0.321f, 6.868f)
close()
}
path(
fill = SolidColor(Color(0xFFffffff)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(328.131f, 347.723f)
curveToRelative(18.676f, 9.029f, 16.713f, -14.754f, 1.534f, -5.831f)
lineToRelative(-0.715f, 1.921f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(261.205f, 452.296f)
curveToRelative(-0.01f, -31.751f, -0.131f, -63.617f, -4.183f, -95.161f)
curveToRelative(-21.21f, 6.715f, -22.059f, 34.273f, -29.883f, 51.747f)
curveToRelative(-14.996f, 21.746f, 1.779f, 51.062f, 28.507f, 43.698f)
lineToRelative(2.754f, -0.175f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(268.525f, 362.363f)
curveToRelative(-5.532f, 25.009f, 1.026f, 50.791f, 1.095f, 76.12f)
curveToRelative(2.316f, 33.709f, 45.428f, -4.749f, 27.671f, -24.311f)
curveToRelative(-9.589f, -16.836f, -13.047f, -39.454f, -28.766f, -51.809f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(185.912f, 282.888f)
curveToRelative(2.812f, 7.364f, -1.009f, 19.985f, 6.798f, 23.39f)
curveToRelative(13.403f, 7.924f, 5.009f, 23.188f, 18.017f, 31.428f)
curveToRelative(3.286f, 15.59f, -20.209f, 16.404f, -9.522f, 32.471f)
curveToRelative(10.79f, 11.433f, 33.598f, -18.826f, 33.283f, -34.778f)
curveToRelative(4.946f, -24.56f, -15.221f, -46.819f, -38.787f, -50.423f)
curveToRelative(-3.238f, -0.808f, -6.508f, -1.478f, -9.789f, -2.088f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(174.409f, 283.934f)
curveToRelative(-0.802f, 9.414f, 7.357f, 32.461f, 3.761f, 10.435f)
curveToRelative(-1.913f, -2.349f, 0.636f, -11.744f, -3.761f, -10.435f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(316.628f, 378.049f)
curveToRelative(3.075f, -11.085f, 3.285f, -20.165f, -2.786f, -29.212f)
curveToRelative(-1.487f, -24.509f, 13.443f, -41.074f, 17.426f, -62.812f)
curveToRelative(-28.09f, 0.389f, -54.698f, 27.468f, -46.08f, 56.402f)
curveToRelative(3.617f, 16.059f, 15.22f, 30.985f, 31.439f, 35.622f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(163.952f, 287.071f)
curveToRelative(-20.933f, 9.04f, -36.187f, 32.897f, -27.189f, 55.421f)
curveToRelative(6.503f, 19.036f, 24.512f, 34.534f, 44.967f, 35.557f)
curveToRelative(-4.624f, -20.378f, -19.128f, -36.549f, -18.624f, -60.584f)
curveToRelative(2.351f, -10.495f, 8.589f, -19.63f, 0.847f, -30.394f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(340.68f, 287.071f)
curveToRelative(-4.457f, 8.035f, -2.168f, 32.414f, 0.122f, 9.871f)
curveToRelative(-2.314f, -1.879f, 6.217f, -11.529f, -0.122f, -9.871f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(351.137f, 289.162f)
curveToRelative(-6.293f, 17.563f, 7.981f, 33.691f, 3.62f, 48.783f)
curveToRelative(15.158f, 21.457f, -25.383f, 21.09f, -17.214f, 43.241f)
curveToRelative(35.013f, -1.124f, 60.324f, -47.798f, 37.825f, -75.927f)
curveToRelative(-6.395f, -7.397f, -14.86f, -13.213f, -24.23f, -16.097f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(188.004f, 358.18f)
curveToRelative(-1.683f, 13.577f, 8.332f, 26.695f, 3.23f, 7.21f)
curveToRelative(-1.151f, -2.128f, 0.632f, -8.445f, -3.23f, -7.21f)
close()
}
path(
fill = SolidColor(Color(0xFFf9a318)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(329.177f, 360.272f)
curveToRelative(-4.168f, 9.067f, -2.34f, 32.64f, 0.249f, 10.422f)
curveToRelative(-0.99f, -2.221f, 4.738f, -12.028f, -0.249f, -10.422f)
close()
}
path(
fill = SolidColor(Color(0xFF203d1b)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(318.72f, 509.811f)
curveToRelative(27.619f, 9.81f, 24.306f, -50.605f, 1.551f, -25.143f)
curveToRelative(-4.515f, 7.619f, -2.502f, 16.89f, -1.551f, 25.143f)
close()
}
path(
fill = SolidColor(Color(0xFF203d1b)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(206.827f, 511.902f)
curveToRelative(8.105f, -14.523f, -14.147f, -44.0f, -18.997f, -18.823f)
curveToRelative(-4.344f, 14.514f, 5.617f, 21.311f, 18.997f, 18.823f)
close()
}
path(
fill = SolidColor(Color(0xFF203d1b)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(248.656f, 517.131f)
curveToRelative(3.679f, -23.672f, -27.249f, -48.536f, -35.512f, -15.612f)
curveToRelative(-7.898f, 22.958f, 23.234f, 17.531f, 35.512f, 15.612f)
close()
moveTo(292.577f, 516.085f)
curveToRelative(26.315f, 9.481f, 28.204f, -26.173f, 7.336f, -31.631f)
curveToRelative(-11.741f, 5.503f, -7.375f, 21.531f, -7.336f, 31.631f)
close()
}
path(
fill = SolidColor(Color(0xFF203d1b)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(289.062f, 514.957f)
curveToRelative(-0.003f, -5.436f, -0.324f, -10.515f, -2.186f, -15.686f)
curveToRelative(-2.274f, -5.577f, -5.053f, -10.71f, -9.359f, -14.348f)
curveToRelative(-12.703f, -10.594f, -18.586f, 9.534f, -21.57f, 18.531f)
curveToRelative(-1.24f, 3.742f, -4.543f, 11.236f, -0.763f, 14.494f)
curveToRelative(2.449f, 2.11f, 6.787f, 2.152f, 9.827f, 2.222f)
curveToRelative(8.863f, 0.207f, 15.69f, -3.227f, 24.052f, -5.213f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(183.928f, 13.894f)
curveToRelative(1.519f, 7.249f, 3.919f, 14.134f, 4.873f, 21.515f)
lineToRelative(2.074f, -0.267f)
curveToRelative(-0.953f, -7.414f, -1.329f, -14.808f, -4.873f, -21.515f)
close()
}
path(
fill = SolidColor(Color(0xFF100f0f)),
stroke = null,
strokeLineWidth = 1.04573f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(233.231f, 20.945f)
lineToRelative(1.046f, 16.732f)
curveToRelative(2.294f, -5.109f, 2.624f, -11.389f, 1.046f, -16.732f)
close()
}
}
.build()
return customHashTagIconsSkull!!
}
private var customHashTagIconsSkull: ImageVector? = null

Wyświetl plik

@ -0,0 +1,144 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsTunestrPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Tunestr,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Tunestr: ImageVector
get() {
if (customHashTagIconsTunestr != null) {
return customHashTagIconsTunestr!!
}
customHashTagIconsTunestr =
Builder(
name = "Tunestr",
defaultWidth = 600.0.dp,
defaultHeight = 600.0.dp,
viewportWidth = 600.0f,
viewportHeight = 600.0f,
).apply {
path(
fill = SolidColor(Color(0xFFeb3c27)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(171.93f, 82.63f)
lineTo(577.1f, 0.0f)
lineTo(577.1f, 112.99f)
lineTo(171.93f, 195.62f)
close()
}
path(
fill = SolidColor(Color(0xFFeb3c27)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(171.93f, 82.54f)
lineTo(237.16f, 82.54f)
lineTo(237.16f, 504.91f)
lineTo(171.93f, 504.91f)
close()
}
path(
fill = SolidColor(Color(0xFFeb3c27)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(235.04f, 488.2f)
curveTo(246.7f, 531.7f, 209.13f, 579.56f, 151.13f, 595.1f)
curveTo(93.13f, 610.64f, 36.67f, 587.98f, 25.01f, 544.48f)
curveTo(13.35f, 500.98f, 50.92f, 453.12f, 108.92f, 437.58f)
curveTo(166.92f, 422.04f, 223.38f, 444.7f, 235.04f, 488.2f)
close()
}
path(
fill = SolidColor(Color(0xFFeb3c27)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(511.87f, 13.54f)
lineTo(577.1f, 13.54f)
lineTo(577.1f, 435.91f)
lineTo(511.87f, 435.91f)
close()
}
path(
fill = SolidColor(Color(0xFFeb3c27)),
stroke = SolidColor(Color(0x00000000)),
strokeLineWidth = 1.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(574.98f, 419.21f)
curveTo(586.64f, 462.71f, 549.07f, 510.57f, 491.07f, 526.11f)
curveTo(433.07f, 541.65f, 376.61f, 518.99f, 364.95f, 475.49f)
curveTo(353.29f, 431.99f, 390.86f, 384.13f, 448.86f, 368.59f)
curveTo(506.86f, 353.05f, 563.32f, 375.71f, 574.98f, 419.21f)
close()
}
}
.build()
return customHashTagIconsTunestr!!
}
private var customHashTagIconsTunestr: ImageVector? = null

Wyświetl plik

@ -0,0 +1,550 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsWeedPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Weed,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Weed: ImageVector
get() {
if (customHashTagIconsWeed != null) {
return customHashTagIconsWeed!!
}
customHashTagIconsWeed =
Builder(
name = "Weed",
defaultWidth = 512.0.dp,
defaultHeight = 512.0.dp,
viewportWidth = 512.0f,
viewportHeight = 512.0f,
).apply {
path(
fill = SolidColor(Color(0xFF00bf00)),
stroke = null,
strokeLineWidth = 0.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(255.539f, 30.66f)
curveToRelative(-170.359f, -0.44f, -85.18f, -0.22f, 0.0f, 0.0f)
close()
moveTo(255.561f, 30.641f)
curveToRelative(-0.16f, 1.3f, -0.7f, 4.54f, -1.51f, 8.92f)
curveToRelative(-1.56f, 8.54f, -4.271f, 21.57f, -7.781f, 33.9f)
curveToRelative(-0.86f, 3.08f, -1.949f, 6.49f, -3.189f, 10.27f)
curveToRelative(-0.002f, 0.006f, -0.004f, 0.014f, -0.006f, 0.02f)
lineToRelative(-0.035f, -0.029f)
lineToRelative(-2.158f, -1.891f)
lineToRelative(-1.512f, 12.869f)
curveToRelative(-0.943f, 3.119f, -2.055f, 6.243f, -2.889f, 8.881f)
curveToRelative(-0.001f, 0.002f, -0.001f, 0.004f, -0.002f, 0.006f)
lineToRelative(-0.029f, -0.016f)
lineToRelative(-7.35f, -3.73f)
lineToRelative(1.68f, 21.52f)
lineToRelative(0.006f, 0.066f)
curveToRelative(-1.345f, 4.473f, -2.691f, 9.104f, -4.035f, 13.895f)
lineToRelative(-0.02f, -0.01f)
lineToRelative(-8.65f, -3.84f)
lineToRelative(2.699f, 28.379f)
lineToRelative(0.008f, 0.088f)
curveToRelative(-0.644f, 2.949f, -1.232f, 5.955f, -1.768f, 9.012f)
curveToRelative(-0.0f, 0.001f, 0.0f, 0.003f, 0.0f, 0.004f)
lineToRelative(-0.029f, -0.014f)
lineToRelative(-11.25f, -5.779f)
lineToRelative(7.189f, 35.09f)
lineToRelative(0.031f, 0.148f)
curveToRelative(-0.373f, 4.064f, -0.644f, 8.231f, -0.861f, 12.451f)
curveToRelative(-0.0f, 0.006f, 0.0f, 0.013f, 0.0f, 0.02f)
lineToRelative(-0.029f, -0.02f)
lineToRelative(-12.221f, -8.109f)
lineToRelative(13.189f, 51.629f)
curveToRelative(0.298f, 2.798f, 0.545f, 5.692f, 0.791f, 8.111f)
curveToRelative(0.001f, 0.005f, 0.001f, 0.009f, 0.002f, 0.014f)
lineToRelative(-0.031f, -0.014f)
lineToRelative(-6.381f, -2.65f)
lineToRelative(-7.57f, -3.189f)
lineToRelative(15.887f, 32.271f)
lineToRelative(-0.025f, 0.049f)
lineToRelative(-1.5f, 2.836f)
curveToRelative(-1.187f, -1.945f, -2.424f, -3.881f, -3.721f, -5.826f)
curveToRelative(-0.028f, -0.043f, -0.06f, -0.088f, -0.088f, -0.131f)
lineToRelative(-18.043f, -39.051f)
lineToRelative(-2.91f, 10.348f)
curveToRelative(-2.206f, -2.645f, -4.473f, -5.291f, -6.689f, -7.826f)
curveToRelative(-0.022f, -0.025f, -0.044f, -0.047f, -0.066f, -0.072f)
lineToRelative(-13.414f, -25.969f)
lineToRelative(-3.557f, 8.402f)
curveToRelative(-1.887f, -1.837f, -3.725f, -3.555f, -5.563f, -5.232f)
curveToRelative(-4.205f, -6.524f, -8.374f, -13.106f, -12.551f, -19.66f)
lineToRelative(-3.02f, 6.09f)
curveToRelative(-3.19f, -2.65f, -6.32f, -5.14f, -9.35f, -7.52f)
curveToRelative(-0.016f, -0.013f, -0.031f, -0.022f, -0.047f, -0.035f)
lineTo(127.5f, 190.609f)
lineToRelative(-2.262f, 5.441f)
curveToRelative(-2.16f, -1.62f, -4.209f, -3.191f, -6.158f, -4.65f)
curveToRelative(-0.032f, -0.024f, -0.058f, -0.043f, -0.09f, -0.066f)
lineToRelative(-7.17f, -7.703f)
lineToRelative(-0.318f, 2.143f)
curveToRelative(-2.537f, -1.997f, -4.864f, -3.775f, -6.912f, -5.453f)
curveToRelative(-12.32f, -10.06f, -24.38f, -21.901f, -26.65f, -24.221f)
curveToRelative(1.62f, 2.81f, 9.73f, 17.511f, 16.0f, 31.951f)
curveToRelative(1.03f, 2.38f, 2.111f, 5.03f, 3.301f, 8.0f)
curveToRelative(0.001f, 0.003f, 0.003f, 0.007f, 0.004f, 0.01f)
lineToRelative(-2.104f, -0.32f)
lineToRelative(5.398f, 8.742f)
curveToRelative(0.87f, 2.32f, 1.841f, 4.808f, 2.871f, 7.348f)
curveToRelative(0.002f, 0.006f, 0.005f, 0.013f, 0.008f, 0.02f)
lineToRelative(-6.059f, 0.6f)
lineToRelative(11.68f, 13.352f)
curveToRelative(1.398f, 3.504f, 2.965f, 7.176f, 4.691f, 10.898f)
curveToRelative(0.003f, 0.007f, 0.007f, 0.014f, 0.01f, 0.022f)
lineToRelative(-6.871f, 1.029f)
lineToRelative(15.73f, 17.57f)
lineToRelative(0.023f, 0.027f)
curveToRelative(1.073f, 2.204f, 2.205f, 4.347f, 3.387f, 6.602f)
curveToRelative(0.004f, 0.007f, 0.008f, 0.013f, 0.012f, 0.02f)
lineToRelative(-0.012f, 0.002f)
lineToRelative(-9.25f, 0.809f)
lineToRelative(21.68f, 20.17f)
lineToRelative(0.057f, 0.053f)
curveToRelative(1.768f, 2.835f, 3.701f, 5.623f, 5.684f, 8.469f)
curveToRelative(0.005f, 0.007f, 0.011f, 0.013f, 0.016f, 0.02f)
horizontalLineToRelative(-0.025f)
lineToRelative(-11.029f, -0.27f)
lineToRelative(33.199f, 28.379f)
lineToRelative(0.125f, 0.105f)
curveToRelative(1.465f, 1.62f, 2.939f, 3.25f, 4.404f, 4.822f)
verticalLineToRelative(0.002f)
verticalLineToRelative(0.111f)
lineToRelative(0.006f, 0.051f)
lineToRelative(-7.676f, 1.34f)
lineToRelative(-0.059f, -0.041f)
lineToRelative(-30.221f, -20.92f)
lineToRelative(2.971f, 8.33f)
lineToRelative(0.002f, 0.006f)
curveToRelative(-0.004f, -0.002f, -0.008f, -0.004f, -0.012f, -0.006f)
curveToRelative(-3.021f, -1.296f, -6.043f, -2.532f, -9.004f, -3.719f)
lineToRelative(-0.018f, -0.012f)
lineToRelative(-22.979f, -14.811f)
lineToRelative(1.51f, 7.031f)
curveToRelative(-2.27f, -0.75f, -4.481f, -1.46f, -6.701f, -2.16f)
lineToRelative(-19.25f, -10.541f)
lineToRelative(0.76f, 5.24f)
curveToRelative(-3.73f, -0.98f, -7.3f, -1.89f, -10.76f, -2.76f)
lineToRelative(-14.65f, -7.789f)
lineToRelative(0.971f, 4.6f)
curveToRelative(-2.38f, -0.6f, -4.7f, -1.08f, -6.92f, -1.57f)
curveToRelative(-0.024f, -0.006f, -0.043f, -0.01f, -0.066f, -0.016f)
lineToRelative(-9.174f, -3.484f)
lineToRelative(0.799f, 1.549f)
curveToRelative(-2.915f, -0.649f, -5.502f, -1.3f, -7.879f, -1.889f)
curveToRelative(-14.255f, -3.676f, -29.14f, -8.685f, -32.033f, -9.723f)
curveToRelative(-0.486f, -0.278f, -0.595f, -0.337f, -0.256f, -0.117f)
curveToRelative(-0.146f, -0.045f, -0.22f, -0.064f, -0.229f, -0.063f)
curveToRelative(0.02f, 0.013f, 0.181f, 0.072f, 0.459f, 0.172f)
curveToRelative(2.65f, 1.51f, 16.008f, 9.73f, 27.898f, 18.27f)
curveToRelative(1.94f, 1.41f, 4.1f, 3.03f, 6.43f, 4.76f)
curveToRelative(0.002f, 0.002f, 0.005f, 0.004f, 0.008f, 0.006f)
lineToRelative(-0.027f, 0.006f)
lineToRelative(-1.779f, 0.379f)
lineToRelative(8.6f, 4.871f)
lineToRelative(0.139f, 0.078f)
curveToRelative(1.742f, 1.333f, 3.536f, 2.755f, 5.441f, 4.23f)
curveToRelative(0.001f, 0.001f, 0.002f, 0.003f, 0.004f, 0.004f)
lineToRelative(-0.014f, 0.006f)
lineToRelative(-4.221f, 2.111f)
lineToRelative(15.35f, 6.219f)
lineToRelative(0.08f, 0.033f)
curveToRelative(2.794f, 2.096f, 5.8f, 4.242f, 8.859f, 6.447f)
lineToRelative(-0.018f, 0.01f)
lineToRelative(-4.602f, 2.701f)
lineToRelative(20.711f, 8.16f)
lineToRelative(0.051f, 0.02f)
curveToRelative(1.88f, 1.233f, 3.76f, 2.416f, 5.699f, 3.6f)
lineToRelative(-0.02f, 0.01f)
lineToRelative(-6.602f, 3.301f)
curveToRelative(12.864f, 3.87f, 23.452f, 7.891f, 34.791f, 12.699f)
horizontalLineToRelative(-0.02f)
lineToRelative(-8.432f, 2.92f)
curveToRelative(14.812f, 4.474f, 30.991f, 8.293f, 44.988f, 13.197f)
lineToRelative(-0.008f, 0.004f)
lineToRelative(-7.189f, 4.43f)
curveToRelative(11.356f, 1.924f, 22.792f, 2.67f, 32.447f, 4.596f)
lineToRelative(-2.268f, 6.424f)
lineToRelative(7.57f, 0.33f)
horizontalLineToRelative(0.022f)
lineToRelative(0.379f, 0.32f)
lineToRelative(0.006f, 0.008f)
curveToRelative(-0.009f, 0.001f, -0.017f, 0.001f, -0.025f, 0.002f)
curveToRelative(-11.529f, 1.088f, -24.241f, 0.811f, -34.48f, 0.959f)
lineToRelative(5.24f, 3.352f)
horizontalLineToRelative(0.049f)
lineToRelative(0.01f, 0.006f)
curveToRelative(-0.006f, 0.001f, -0.013f, 0.003f, -0.02f, 0.004f)
horizontalLineToRelative(-0.049f)
curveToRelative(-9.972f, 1.372f, -18.923f, 2.05f, -27.191f, 2.43f)
curveToRelative(5.579f, 4.212f, 3.756f, 3.194f, -0.981f, 4.76f)
curveToRelative(-5.419f, 0.595f, -10.84f, 1.187f, -16.26f, 1.779f)
lineToRelative(2.699f, 2.648f)
curveToRelative(-0.002f, 0.001f, -0.005f, 0.001f, -0.008f, 0.002f)
curveToRelative(-6.406f, 2.869f, -13.553f, 3.441f, -19.891f, 4.221f)
lineToRelative(2.531f, 2.104f)
curveToRelative(-3.89f, 1.778f, -8.189f, 2.709f, -12.002f, 3.627f)
lineToRelative(1.184f, 0.535f)
curveToRelative(-2.043f, 0.807f, -3.929f, 1.505f, -5.604f, 2.104f)
curveToRelative(-2.49f, 0.87f, -5.029f, 1.73f, -7.459f, 2.49f)
curveToRelative(-7.68f, 2.43f, -14.491f, 4.33f, -16.111f, 4.76f)
curveToRelative(1.95f, -0.16f, 10.711f, -0.699f, 20.061f, -0.809f)
curveToRelative(1.52f, -0.05f, 3.09f, -0.051f, 4.6f, -0.051f)
curveToRelative(1.76f, 0.0f, 3.743f, 0.058f, 5.934f, 0.107f)
lineToRelative(-0.924f, 0.912f)
lineToRelative(7.605f, -0.742f)
curveToRelative(1.56f, 0.102f, 3.168f, 0.165f, 4.877f, 0.213f)
lineToRelative(-1.672f, 2.85f)
lineToRelative(12.018f, -2.635f)
curveToRelative(0.058f, 0.001f, 0.104f, 0.003f, 0.162f, 0.004f)
curveToRelative(2.528f, 0.05f, 5.216f, 0.051f, 7.963f, 0.051f)
lineToRelative(-1.662f, 3.33f)
curveToRelative(6.882f, -1.965f, 14.196f, -3.301f, 21.051f, -3.92f)
curveToRelative(0.001f, -0.0f, 0.003f, 0.0f, 0.004f, 0.0f)
lineToRelative(-2.615f, 4.43f)
curveToRelative(13.31f, -3.974f, 16.099f, -5.067f, 26.494f, -6.701f)
lineToRelative(-3.854f, 4.941f)
curveToRelative(10.81f, -3.418f, 22.148f, -7.947f, 32.869f, -10.455f)
lineToRelative(-2.459f, 5.295f)
lineToRelative(19.838f, -9.822f)
curveToRelative(0.02f, -0.006f, 0.042f, -0.012f, 0.063f, -0.018f)
curveToRelative(0.604f, -0.141f, 1.226f, -0.333f, 1.752f, -0.482f)
lineToRelative(1.338f, 4.473f)
curveToRelative(9.459f, -7.189f, 21.169f, -11.545f, 31.328f, -15.826f)
curveToRelative(1.686f, 28.193f, 4.388f, 58.01f, 7.361f, 83.355f)
lineToRelative(12.891f, -0.32f)
curveToRelative(0.0f, 0.0f, -0.19f, -5.31f, -0.51f, -14.6f)
curveToRelative(-0.21f, -4.65f, -0.46f, -10.28f, -0.74f, -16.75f)
curveToRelative(-0.08f, -3.23f, -0.171f, -6.669f, -0.271f, -10.299f)
curveToRelative(-0.14f, -3.63f, -0.289f, -7.44f, -0.449f, -11.42f)
curveToRelative(-0.15f, -3.97f, -0.299f, -8.12f, -0.459f, -12.41f)
curveToRelative(-0.09f, -4.29f, -0.191f, -8.731f, -0.291f, -13.291f)
curveToRelative(-0.084f, -4.023f, -0.18f, -8.452f, -0.27f, -12.654f)
curveToRelative(0.003f, -0.003f, 0.007f, -0.003f, 0.01f, -0.006f)
curveToRelative(11.32f, -91.67f, 22.474f, -231.573f, 0.08f, -339.539f)
curveToRelative(-0.27f, -1.35f, -0.54f, -2.6f, -0.76f, -3.84f)
curveToRelative(-0.27f, -1.45f, -0.54f, -2.811f, -0.76f, -4.051f)
curveToRelative(-0.16f, -0.81f, -0.322f, -1.57f, -0.432f, -2.27f)
curveToRelative(-0.05f, -0.54f, -0.16f, -1.08f, -0.27f, -1.51f)
curveToRelative(-0.11f, -0.38f, -0.169f, -0.711f, -0.219f, -1.031f)
curveToRelative(-0.22f, -1.41f, -0.38f, -2.489f, -0.49f, -3.139f)
close()
moveTo(77.66f, 155.711f)
verticalLineToRelative(0.109f)
curveToRelative(0.0f, 0.0f, 0.051f, -0.001f, 0.051f, 0.049f)
lineToRelative(0.219f, 0.221f)
curveToRelative(-0.01f, -0.014f, -0.02f, -0.026f, -0.029f, -0.039f)
curveToRelative(-0.009f, -0.013f, -0.017f, -0.027f, -0.025f, -0.039f)
curveToRelative(-0.101f, -0.145f, -0.151f, -0.23f, -0.195f, -0.279f)
curveToRelative(-0.002f, -0.002f, -0.002f, -0.004f, -0.004f, -0.006f)
curveToRelative(-0.002f, -0.002f, -0.004f, -0.004f, -0.006f, -0.006f)
curveToRelative(-0.002f, -0.002f, -0.002f, -0.004f, -0.004f, -0.006f)
curveToRelative(-0.002f, -0.002f, -0.004f, -0.002f, -0.006f, -0.004f)
close()
moveTo(83.125f, 158.975f)
curveToRelative(-0.0f, 0.011f, 0.034f, 0.09f, 0.105f, 0.236f)
curveToRelative(-0.12f, -0.112f, -0.185f, -0.167f, -0.195f, -0.17f)
curveToRelative(0.01f, 0.023f, 0.139f, 0.167f, 0.375f, 0.42f)
curveToRelative(-0.169f, -0.304f, -0.267f, -0.47f, -0.285f, -0.486f)
close()
moveTo(76.029f, 161.527f)
curveToRelative(-0.001f, 0.01f, 0.036f, 0.086f, 0.111f, 0.232f)
curveToRelative(-0.32f, -0.3f, -0.24f, -0.19f, 0.18f, 0.24f)
curveToRelative(-0.187f, -0.325f, -0.29f, -0.49f, -0.291f, -0.473f)
close()
moveTo(56.129f, 391.533f)
lineTo(56.127f, 391.535f)
curveToRelative(0.005f, 0.005f, 0.061f, 0.016f, 0.174f, 0.035f)
curveToRelative(-0.103f, 0.011f, -0.158f, 0.018f, -0.168f, 0.022f)
curveToRelative(0.017f, 0.002f, 0.146f, -0.005f, 0.377f, -0.022f)
curveToRelative(-0.231f, -0.028f, -0.362f, -0.041f, -0.381f, -0.037f)
close()
moveTo(56.359f, 419.289f)
curveToRelative(-0.236f, 0.023f, -0.368f, 0.041f, -0.385f, 0.047f)
curveToRelative(0.006f, 0.003f, 0.063f, 0.002f, 0.176f, -0.006f)
curveToRelative(-0.105f, 0.032f, -0.157f, 0.052f, -0.164f, 0.057f)
curveToRelative(0.019f, -0.001f, 0.148f, -0.036f, 0.373f, -0.098f)
close()
moveTo(54.75f, 425.199f)
curveToRelative(-0.236f, 0.017f, -0.368f, 0.029f, -0.385f, 0.033f)
curveToRelative(0.01f, 0.002f, 0.066f, 0.002f, 0.174f, -0.002f)
curveToRelative(-0.105f, 0.032f, -0.157f, 0.051f, -0.164f, 0.057f)
curveToRelative(0.019f, -0.0f, 0.15f, -0.032f, 0.375f, -0.088f)
close()
}
path(
fill = SolidColor(Color(0xFF00a900)),
stroke = null,
strokeAlpha = 0.06f,
strokeLineWidth = 0.0f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(477.166f, 296.266f)
lineToRelative(-0.05f, 0.05f)
lineToRelative(1.78f, 0.32f)
lineToRelative(-8.6f, 4.86f)
lineToRelative(-0.05f, 0.05f)
curveToRelative(-1.73f, 1.35f, -3.57f, 2.76f, -5.51f, 4.27f)
lineToRelative(4.22f, 2.11f)
lineToRelative(-15.35f, 6.22f)
lineToRelative(-0.05f, 0.05f)
curveToRelative(-2.87f, 2.11f, -5.78f, 4.22f, -8.87f, 6.43f)
lineToRelative(4.6f, 2.7f)
lineToRelative(-20.55f, 8.11f)
curveToRelative(-0.32f, 0.22f, -0.65f, 0.43f, -1.03f, 0.65f)
curveToRelative(-1.57f, 1.03f, -3.19f, 2.0f, -4.81f, 3.03f)
lineToRelative(6.54f, 3.3f)
lineToRelative(-26.06f, 8.11f)
lineToRelative(-0.05f, 0.05f)
horizontalLineToRelative(-0.05f)
curveToRelative(-0.05f, 0.0f, -0.05f, 0.05f, -0.11f, 0.05f)
curveToRelative(-2.76f, 1.57f, -5.62f, 2.97f, -8.49f, 4.49f)
lineToRelative(8.43f, 2.92f)
lineToRelative(-39.09f, 10.87f)
curveToRelative(-0.05f, 0.05f, -0.16f, 0.05f, -0.22f, 0.05f)
curveToRelative(-1.89f, 0.76f, -3.79f, 1.57f, -5.68f, 2.27f)
lineToRelative(7.24f, 4.43f)
lineToRelative(-30.01f, 3.78f)
horizontalLineToRelative(-0.05f)
curveToRelative(-0.87f, 0.27f, -1.62f, 0.54f, -2.43f, 0.81f)
lineToRelative(0.97f, 2.65f)
lineToRelative(16.76f, -0.16f)
lineToRelative(-5.19f, 3.51f)
curveToRelative(2.38f, 0.43f, 4.7f, 0.87f, 7.08f, 1.35f)
horizontalLineToRelative(0.11f)
lineToRelative(20.11f, 0.38f)
lineToRelative(-3.84f, 3.41f)
curveToRelative(1.62f, 0.43f, 3.24f, 0.87f, 4.87f, 1.3f)
curveToRelative(0.05f, 0.05f, 0.05f, 0.05f, 0.11f, 0.05f)
lineToRelative(16.22f, 1.41f)
lineToRelative(-2.6f, 2.65f)
curveToRelative(1.35f, 0.43f, 2.65f, 0.87f, 3.95f, 1.3f)
curveToRelative(1.24f, 0.43f, 2.49f, 0.81f, 3.73f, 1.24f)
horizontalLineToRelative(0.16f)
lineToRelative(12.16f, 1.19f)
lineToRelative(-2.49f, 2.22f)
curveToRelative(1.68f, 0.6f, 3.3f, 1.19f, 4.81f, 1.73f)
horizontalLineToRelative(0.05f)
lineToRelative(7.19f, 1.57f)
lineToRelative(-1.13f, 0.59f)
curveToRelative(2.0f, 0.7f, 3.95f, 1.35f, 5.62f, 1.95f)
curveToRelative(10.33f, 3.3f, 21.57f, 6.16f, 23.73f, 6.7f)
curveToRelative(-2.22f, -0.16f, -13.84f, -0.6f, -24.65f, -0.32f)
curveToRelative(-1.78f, 0.05f, -3.78f, 0.16f, -5.95f, 0.27f)
lineToRelative(0.92f, 0.87f)
lineToRelative(-7.14f, -0.49f)
horizontalLineToRelative(-0.16f)
curveToRelative(-1.68f, 0.05f, -3.41f, 0.16f, -5.19f, 0.27f)
lineToRelative(1.73f, 2.81f)
lineToRelative(-12.0f, -2.32f)
horizontalLineToRelative(-0.05f)
curveToRelative(-1.3f, 0.05f, -2.65f, 0.11f, -3.95f, 0.16f)
curveToRelative(-1.4f, 0.05f, -2.76f, 0.05f, -4.16f, 0.11f)
lineToRelative(1.73f, 3.3f)
lineToRelative(-15.84f, -3.24f)
lineToRelative(-0.16f, -0.05f)
horizontalLineToRelative(-0.22f)
curveToRelative(-1.62f, 0.0f, -3.24f, -0.05f, -4.92f, -0.11f)
lineToRelative(2.7f, 4.38f)
lineToRelative(-19.52f, -5.35f)
curveToRelative(-0.97f, -0.11f, -2.0f, -0.22f, -3.03f, -0.32f)
curveToRelative(-1.35f, -0.11f, -2.76f, -0.27f, -4.11f, -0.43f)
lineToRelative(4.0f, 4.87f)
lineToRelative(-28.6f, -8.76f)
curveToRelative(-0.32f, -0.05f, -0.65f, -0.11f, -0.92f, -0.22f)
curveToRelative(-1.24f, -0.22f, -2.43f, -0.49f, -3.62f, -0.7f)
lineToRelative(2.6f, 5.3f)
lineToRelative(-20.11f, -9.35f)
curveToRelative(-0.05f, 0.0f, -0.05f, 0.0f, -0.11f, -0.05f)
curveToRelative(-0.54f, -0.11f, -1.13f, -0.27f, -1.68f, -0.43f)
lineToRelative(-1.19f, 4.54f)
lineToRelative(-17.95f, -10.11f)
lineToRelative(-0.05f, -0.05f)
horizontalLineToRelative(-0.05f)
curveToRelative(-5.78f, -1.89f, -10.92f, -3.73f, -15.19f, -5.46f)
curveToRelative(0.05f, 2.7f, 0.11f, 5.51f, 0.16f, 8.16f)
curveToRelative(0.11f, 4.54f, 0.22f, 8.98f, 0.27f, 13.3f)
curveToRelative(0.16f, 4.27f, 0.32f, 8.43f, 0.49f, 12.38f)
curveToRelative(0.16f, 4.0f, 0.32f, 7.79f, 0.43f, 11.46f)
curveToRelative(0.11f, 3.62f, 0.22f, 7.03f, 0.27f, 10.27f)
curveToRelative(0.27f, 6.49f, 0.54f, 12.11f, 0.76f, 16.76f)
curveToRelative(0.32f, 9.3f, 0.49f, 14.6f, 0.49f, 14.6f)
lineToRelative(-5.35f, 0.11f)
verticalLineTo(33.345f)
curveToRelative(0.16f, 0.81f, 0.32f, 1.78f, 0.49f, 2.87f)
curveToRelative(0.32f, 1.78f, 0.7f, 3.95f, 1.19f, 6.33f)
curveToRelative(0.22f, 1.24f, 0.49f, 2.49f, 0.76f, 3.84f)
curveToRelative(1.62f, 7.84f, 3.78f, 17.57f, 6.43f, 26.98f)
curveToRelative(0.49f, 1.73f, 1.03f, 3.57f, 1.68f, 5.51f)
curveToRelative(0.27f, 0.97f, 0.6f, 2.0f, 0.97f, 3.03f)
curveToRelative(0.16f, 0.54f, 0.32f, 1.08f, 0.54f, 1.68f)
lineToRelative(2.11f, -1.84f)
lineToRelative(1.51f, 12.7f)
verticalLineToRelative(0.11f)
curveToRelative(0.97f, 2.81f, 1.95f, 5.84f, 2.97f, 8.92f)
lineToRelative(7.35f, -3.73f)
lineToRelative(-1.68f, 21.46f)
verticalLineToRelative(0.05f)
curveToRelative(1.35f, 4.54f, 2.7f, 9.14f, 4.05f, 13.95f)
lineToRelative(8.65f, -3.84f)
lineToRelative(-2.7f, 28.38f)
verticalLineToRelative(0.16f)
curveToRelative(0.6f, 2.92f, 1.19f, 5.89f, 1.73f, 8.92f)
horizontalLineToRelative(0.05f)
lineToRelative(11.25f, -5.78f)
lineToRelative(-7.19f, 35.09f)
curveToRelative(0.16f, 2.11f, 0.38f, 4.16f, 0.49f, 6.27f)
curveToRelative(0.11f, 1.78f, 0.22f, 3.62f, 0.32f, 5.41f)
curveToRelative(0.0f, 0.32f, 0.05f, 0.6f, 0.05f, 0.92f)
lineToRelative(12.22f, -8.11f)
lineToRelative(-13.19f, 51.42f)
lineToRelative(-0.05f, 0.16f)
verticalLineToRelative(0.22f)
curveToRelative(-0.22f, 2.7f, -0.43f, 5.3f, -0.7f, 7.95f)
lineToRelative(13.95f, -5.84f)
lineToRelative(-15.52f, 31.36f)
verticalLineToRelative(0.05f)
lineToRelative(2.0f, 3.73f)
curveToRelative(1.19f, -1.89f, 2.38f, -3.78f, 3.62f, -5.68f)
lineToRelative(0.11f, -0.16f)
lineToRelative(18.11f, -39.14f)
lineToRelative(2.92f, 10.33f)
curveToRelative(2.27f, -2.7f, 4.49f, -5.3f, 6.76f, -7.84f)
lineToRelative(0.05f, -0.05f)
lineToRelative(13.35f, -26.01f)
lineToRelative(3.57f, 8.49f)
curveToRelative(1.84f, -1.78f, 3.62f, -3.46f, 5.46f, -5.14f)
lineToRelative(0.05f, -0.05f)
lineToRelative(12.6f, -19.79f)
lineToRelative(3.03f, 6.11f)
curveToRelative(3.19f, -2.65f, 6.27f, -5.14f, 9.3f, -7.52f)
lineToRelative(9.79f, -14.76f)
lineToRelative(2.33f, 5.46f)
curveToRelative(2.11f, -1.62f, 4.16f, -3.14f, 6.11f, -4.65f)
lineToRelative(7.24f, -7.78f)
lineToRelative(0.32f, 2.11f)
curveToRelative(1.3f, -0.97f, 2.49f, -1.89f, 3.62f, -2.81f)
curveToRelative(1.19f, -0.92f, 2.27f, -1.78f, 3.3f, -2.6f)
curveToRelative(6.49f, -5.3f, 12.98f, -11.14f, 17.9f, -15.79f)
curveToRelative(4.43f, -4.11f, 7.68f, -7.35f, 8.76f, -8.43f)
curveToRelative(-0.81f, 1.35f, -3.14f, 5.57f, -6.0f, 11.19f)
curveToRelative(-3.08f, 5.89f, -6.76f, 13.35f, -10.0f, 20.76f)
curveToRelative(-1.03f, 2.38f, -2.16f, 5.03f, -3.3f, 8.0f)
verticalLineToRelative(0.05f)
lineToRelative(2.16f, -0.38f)
lineToRelative(-5.41f, 8.81f)
lineToRelative(-0.05f, 0.11f)
lineToRelative(-0.11f, 0.11f)
curveToRelative(0.0f, 0.05f, -0.05f, 0.05f, -0.05f, 0.11f)
curveToRelative(-0.81f, 2.16f, -1.68f, 4.43f, -2.6f, 6.76f)
curveToRelative(-0.05f, 0.05f, -0.05f, 0.16f, -0.11f, 0.22f)
horizontalLineToRelative(0.05f)
lineToRelative(6.0f, 0.6f)
lineToRelative(-11.57f, 13.3f)
lineToRelative(-0.11f, 0.11f)
curveToRelative(-1.35f, 3.24f, -2.76f, 6.54f, -4.22f, 9.95f)
curveToRelative(-0.16f, 0.32f, -0.32f, 0.59f, -0.43f, 0.92f)
lineToRelative(6.87f, 1.03f)
lineToRelative(-15.68f, 17.46f)
verticalLineToRelative(0.05f)
lineToRelative(-0.11f, 0.11f)
curveToRelative(-1.13f, 2.16f, -2.27f, 4.38f, -3.46f, 6.54f)
horizontalLineToRelative(0.05f)
lineToRelative(9.24f, 0.87f)
lineToRelative(-21.63f, 20.11f)
curveToRelative(0.0f, 0.0f, 0.0f, 0.05f, -0.05f, 0.05f)
curveToRelative(-1.3f, 2.11f, -2.7f, 4.16f, -4.16f, 6.27f)
curveToRelative(-0.49f, 0.76f, -1.03f, 1.51f, -1.57f, 2.27f)
horizontalLineToRelative(0.05f)
lineToRelative(11.03f, -0.27f)
lineToRelative(-33.25f, 28.33f)
lineToRelative(-0.11f, 0.11f)
lineToRelative(-0.05f, 0.05f)
curveToRelative(-0.7f, 0.81f, -1.41f, 1.62f, -2.16f, 2.38f)
curveToRelative(-0.7f, 0.81f, -1.4f, 1.57f, -2.22f, 2.38f)
verticalLineToRelative(0.22f)
lineToRelative(7.73f, 1.35f)
horizontalLineToRelative(0.05f)
lineToRelative(30.17f, -20.92f)
lineToRelative(-2.92f, 8.27f)
curveToRelative(2.97f, -1.3f, 6.0f, -2.54f, 8.98f, -3.73f)
lineToRelative(22.98f, -14.76f)
lineToRelative(-1.51f, 7.03f)
curveToRelative(2.22f, -0.76f, 4.43f, -1.46f, 6.6f, -2.11f)
lineToRelative(0.11f, -0.05f)
lineToRelative(19.25f, -10.54f)
lineToRelative(-0.76f, 5.24f)
curveToRelative(3.73f, -0.97f, 7.3f, -1.89f, 10.76f, -2.76f)
lineToRelative(14.65f, -7.79f)
lineToRelative(-0.97f, 4.6f)
curveToRelative(2.33f, -0.54f, 4.65f, -1.08f, 6.81f, -1.57f)
curveToRelative(0.05f, 0.0f, 0.05f, 0.0f, 0.11f, 0.0f)
lineToRelative(0.11f, -0.05f)
lineToRelative(9.14f, -3.46f)
lineToRelative(-0.81f, 1.57f)
curveToRelative(0.7f, -0.16f, 1.41f, -0.32f, 2.11f, -0.49f)
curveToRelative(0.7f, -0.16f, 1.4f, -0.32f, 2.05f, -0.49f)
curveToRelative(1.3f, -0.32f, 2.6f, -0.6f, 3.73f, -0.92f)
curveToRelative(14.27f, -3.68f, 29.19f, -8.7f, 32.06f, -9.73f)
curveToRelative(-2.6f, 1.51f, -15.95f, 9.73f, -27.84f, 18.27f)
curveToRelative(-1.99f, 1.4f, -4.1f, 3.02f, -6.42f, 4.75f)
close()
}
}
.build()
return customHashTagIconsWeed!!
}
private var customHashTagIconsWeed: ImageVector? = null

Wyświetl plik

@ -0,0 +1,135 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.commons.hashtags
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap.Companion.Butt
import androidx.compose.ui.graphics.StrokeJoin.Companion.Miter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.ImageVector.Builder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun CustomHashTagIconsZapPreview() {
Image(
painter =
rememberVectorPainter(
CustomHashTagIcons.Zap,
),
contentDescription = "",
)
}
public val CustomHashTagIcons.Zap: ImageVector
get() {
if (customHashTagIconsZap != null) {
return customHashTagIconsZap!!
}
customHashTagIconsZap =
Builder(
name = "Zap",
defaultWidth = 512.0.dp,
defaultHeight = 512.0.dp,
viewportWidth = 512.0f,
viewportHeight = 512.0f,
).apply {
path(
fill = SolidColor(Color(0xFFfeb804)),
stroke = null,
strokeLineWidth = 1.04238f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveTo(402.129f, 1.262f)
curveTo(394.807f, 11.794f, 388.681f, 19.608f, 383.521f, 29.039f)
curveTo(343.68f, 85.579f, 302.38f, 141.064f, 261.518f, 196.862f)
curveToRelative(-6.717f, 6.205f, -2.232f, 18.181f, 7.303f, 15.634f)
curveToRelative(15.682f, 3.42f, 21.453f, -10.422f, 21.453f, -10.422f)
curveToRelative(0.0f, 0.0f, 77.893f, -124.006f, 115.841f, -186.586f)
curveToRelative(2.589f, -5.525f, 4.24f, -14.798f, -3.986f, -14.226f)
close()
}
path(
fill = SolidColor(Color(0xFF9c59ff)),
stroke = null,
strokeLineWidth = 1.04238f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(130.421f, 270.872f)
lineToRelative(84.145f, -1.043f)
lineToRelative(23.28f, 8.339f)
lineToRelative(-22.137f, 38.786f)
lineToRelative(-109.766f, 188.455f)
lineToRelative(3.586f, 0.316f)
lineToRelative(279.741f, -251.785f)
lineToRelative(45.052f, -42.484f)
lineToRelative(-136.776f, 0.479f)
lineToRelative(-35.283f, -0.668f)
lineTo(402.443f, 1.112f)
curveToRelative(0.0f, 0.0f, -223.081f, 181.661f, -329.737f, 270.145f)
lineToRelative(-1.05f, 0.837f)
close()
}
path(
fill = SolidColor(Color(0xFFfeb804)),
stroke = null,
strokeLineWidth = 1.04238f,
strokeLineCap = Butt,
strokeLineJoin = Miter,
strokeLineMiter = 4.0f,
pathFillType = NonZero,
) {
moveToRelative(105.973f, 505.407f)
curveToRelative(0.641f, 10.482f, 14.136f, 7.316f, 18.777f, 1.428f)
curveToRelative(110.113f, -98.518f, 227.418f, -195.827f, 322.374f, -283.083f)
curveToRelative(2.864f, -9.815f, -3.787f, -12.451f, -12.851f, -12.166f)
curveToRelative(-78.496f, 71.808f, -160.716f, 147.927f, -240.441f, 218.409f)
curveToRelative(-26.97f, 23.781f, -53.639f, 47.901f, -80.56f, 71.73f)
curveToRelative(-2.157f, 1.697f, -4.601f, 3.112f, -7.299f, 3.683f)
close()
moveTo(230.057f, 291.682f)
curveToRelative(6.731f, -10.679f, 15.607f, -23.143f, -0.042f, -21.833f)
curveToRelative(-52.452f, -0.003f, -100.964f, 0.787f, -149.966f, 2.256f)
curveToRelative(-7.988f, -0.012f, -8.925f, -2.348f, -12.914f, 9.06f)
curveToRelative(-4.908f, 14.035f, 13.177f, 11.664f, 21.968f, 11.597f)
curveToRelative(42.7f, -0.17f, 85.448f, 0.628f, 128.072f, -1.042f)
curveToRelative(4.996f, -0.006f, 7.714f, -0.11f, 12.882f, -0.037f)
close()
}
}
.build()
return customHashTagIconsZap!!
}
private var customHashTagIconsZap: ImageVector? = null

Wyświetl plik

@ -0,0 +1,131 @@
/**
* Copyright (c) 2024 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Preview
@Composable
private fun VectorPreview() {
Image(Following, null)
}
private var labelsFollowing: ImageVector? = null
public val Following: ImageVector
get() {
if (labelsFollowing != null) {
return labelsFollowing!!
}
labelsFollowing =
ImageVector.Builder(
name = "Following",
defaultWidth = 30.dp,
defaultHeight = 30.dp,
viewportWidth = 30f,
viewportHeight = 30f,
).apply {
path(
fill = SolidColor(Color(0xFF7F2EFF)),
fillAlpha = 1.0f,
stroke = null,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero,
) {
moveTo(27.8f, 12.8f)
lineTo(27.8f, 12.8f)
curveTo(27.8f, 5f, 27.2f, 0f, 24.4f, 0f)
reflectiveCurveTo(15f, 0f, 15f, 0f)
reflectiveCurveTo(8.4f, 0f, 5.6f, 0f)
curveTo(2.8f, 0f, 2.2f, 5f, 2.2f, 12.8f)
verticalLineToRelative(0f)
lineToRelative(0f, 0f)
curveToRelative(0f, 0f, 0f, 0f, 0f, 0f)
curveTo(2.2f, 24.9f, 15f, 30f, 15f, 30f)
reflectiveCurveTo(27.8f, 24.9f, 27.8f, 12.8f)
curveTo(27.8f, 12.8f, 27.8f, 12.8f, 27.8f, 12.8f)
lineTo(27.8f, 12.8f)
close()
}
path(
fill = SolidColor(Color(0xFFFFFFFF)),
fillAlpha = 1.0f,
stroke = SolidColor(Color(0xFF7F2EFF)),
strokeAlpha = 1.0f,
strokeLineWidth = 0.5f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero,
) {
moveTo(15.1f, 24f)
lineToRelative(-0.5f, -0.2f)
curveToRelative(-0.2f, -0.1f, -4.5f, -2f, -6.8f, -6.4f)
curveToRelative(-0.3f, -0.6f, -0.1f, -1.4f, 0.6f, -1.7f)
curveToRelative(0.6f, -0.3f, 1.4f, -0.1f, 1.7f, 0.6f)
curveToRelative(1.4f, 2.8f, 3.9f, 4.4f, 5f, 4.9f)
curveToRelative(1.1f, -0.6f, 3.6f, -2.2f, 5f, -4.9f)
curveToRelative(0.3f, -0.6f, 1.1f, -0.9f, 1.7f, -0.6f)
curveToRelative(0.6f, 0.3f, 0.9f, 1.1f, 0.6f, 1.7f)
curveToRelative(-2.2f, 4.4f, -6.6f, 6.3f, -6.8f, 6.4f)
lineTo(15.1f, 24f)
close()
}
path(
fill = SolidColor(Color(0xFFFFFFFF)),
fillAlpha = 1.0f,
stroke = SolidColor(Color(0xFF7F2EFF)),
strokeAlpha = 1.0f,
strokeLineWidth = 0.5f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero,
) {
moveTo(15f, 15f)
curveToRelative(-2.9f, 0f, -5.2f, -2.3f, -5.2f, -5.2f)
reflectiveCurveToRelative(2.3f, -5.2f, 5.2f, -5.2f)
reflectiveCurveToRelative(5.2f, 2.3f, 5.2f, 5.2f)
reflectiveCurveTo(17.8f, 15f, 15f, 15f)
close()
moveTo(15f, 7.2f)
curveToRelative(-1.4f, 0f, -2.6f, 1.2f, -2.6f, 2.6f)
reflectiveCurveToRelative(1.2f, 2.6f, 2.6f, 2.6f)
reflectiveCurveToRelative(2.6f, -1.2f, 2.6f, -2.6f)
reflectiveCurveTo(16.4f, 7.2f, 15f, 7.2f)
close()
}
}.build()
return labelsFollowing!!
}

Wyświetl plik

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 170.16 186.2"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}</style><linearGradient id="linear-gradient" x1="80.19" y1="57.17" x2="91.66" y2="57.17" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#652d80"/><stop offset="1" stop-color="#2598cf"/></linearGradient><linearGradient id="linear-gradient-2" x1="335.87" y1="297.64" x2="506.02" y2="297.64" xlink:href="#linear-gradient"/></defs><title>Amethyst_svg_monogram</title><ellipse class="cls-1" cx="85.93" cy="57.17" rx="5.74" ry="5.64"/><path class="cls-2" d="M506,347.08c-.2-.61-46.85-111.69-59.68-142.5-15.62,0-48.61,0-71.88,0-6.83,16.89-24.46,59.94-38.6,94.62,7.75,18.49,14.71,35.1,20.08,47.91l29.27,0a2,2,0,0,0,1.87-2.35c-.25-5.91-16.34-27.39-11.54-50.63,1.28-5,2.26-10.08,3.66-15.06a175.77,175.77,0,0,1,13.44-34.8c.89-1.69,1.3-2.45,3.35-1.17,4.37,2.72,9.25,2.56,14.11,2.21,4.19-.91,6.23-2.92,13.91-.88,1.52,0,3,0,4.55.14,3.69.29,7.15,1.17,9.37,4.51,2.42,3.65,2.81,7.78,2.42,12-.59,6.31-.17,12.19,5.17,16.64a57.52,57.52,0,0,0,6,4c2.65,1.7,5.85,2.44,8.12,4.8,1.34,1.39,2.13,2.87,1.55,4.85s-2.13,2.91-4.17,3.13c-5.16.56-10.2-.49-15.27-1.1-.66-.08-1.31-.13-2-.17a11.47,11.47,0,0,1-3.81.13l-1.19,0a26.7,26.7,0,0,0-5.9,1.41c-4.78,1.74-9.13,3.66-14.77,3.56a4.32,4.32,0,0,0-2.05.89c-4.42,3.93-7.08,8.89-4.87,16.14,6.06,16.93,21.61,57.77,28.29,75.4-.19-11.94-.24-33.32-.28-43.7C461.83,347.1,502.74,347.08,506,347.08Z" transform="translate(-335.87 -204.54)"/></svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 1.6 KiB

Wyświetl plik

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
height="64"
width="64"
version="1.1"
id="svg2142"
sodipodi:docname="Bitcoin.svg"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2146" />
<sodipodi:namedview
id="namedview2144"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="11.346854"
inkscape:cx="25.68994"
inkscape:cy="34.150435"
inkscape:window-width="2216"
inkscape:window-height="1205"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="g2140" />
<g
transform="translate(0.00630876,-0.00301984)"
id="g2140">
<path
fill="#FFF"
d="M 54.918461,25.762243 C 55.924243,19.039132 50.805332,15.424946 43.805907,13.013911 L 46.076418,3.9066072 40.532772,2.5250379 38.322261,11.392343 c -1.457358,-0.363155 -2.95419,-0.705784 -4.441548,-1.045254 l 2.2263,-8.9257278 -5.540488,-1.38156955 -2.27209,9.10414775 C 27.088128,8.8692044 25.903926,8.5976271 24.75446,8.3118397 l 0.0063,-0.028421 -7.64521,-1.9089341 -1.474727,5.9210104 c 0,0 4.11313,0.942625 4.026288,1.001046 2.245248,0.560522 2.651034,2.046301 2.583139,3.224188 l -2.586297,10.37519 c 0.154736,0.03947 0.35526,0.09632 0.576312,0.184736 -0.184736,-0.04579 -0.382103,-0.09632 -0.585786,-0.145262 L 16.02928,41.469502 c -0.274735,0.6821 -0.971045,1.705252 -2.540508,1.316834 0.05526,0.08052 -4.0294458,-1.005784 -4.0294458,-1.005784 l -2.752086,6.345746 7.2141598,1.798409 c 1.342097,0.336313 2.657351,0.688415 3.952079,1.019993 l -2.294195,9.211515 5.537329,1.381569 2.272089,-9.113621 c 1.512622,0.410523 2.981033,0.789468 4.417864,1.146307 l -2.264194,9.070991 5.543646,1.381568 2.294195,-9.194146 c 9.453092,1.788935 16.561463,1.067361 19.553547,-7.482579 2.411037,-6.884163 -0.119999,-10.855189 -5.093648,-13.444643 3.622079,-0.835258 6.350482,-3.217873 7.078371,-8.139418 z M 42.252234,43.523698 c -1.713147,6.884164 -13.304119,3.16261 -17.061987,2.229459 l 3.044189,-12.2036 c 3.757869,0.937889 15.808312,2.794718 14.017798,9.974141 z m 1.714725,-17.860927 c -1.563148,6.262061 -11.210449,3.080504 -14.339901,2.30051 l 2.759981,-11.068345 c 3.129451,0.779995 13.207802,2.235775 11.57992,8.767835 z"
id="path2138"
style="fill:#f7931a;fill-opacity:1;stroke-width:1.57894" />
</g>
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.8 KiB

Wyświetl plik

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 400 400"
id="vector"
version="1.1"
sodipodi:docname="cashu.svg"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs5208" />
<sodipodi:namedview
id="namedview5206"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
showguides="true"
inkscape:zoom="1.2279006"
inkscape:cx="194.23397"
inkscape:cy="52.528684"
inkscape:window-width="1390"
inkscape:window-height="1205"
inkscape:window-x="1026"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="vector" />
<path
style="opacity:1;fill:#d6c09a;fill-opacity:1;stroke:#d6c09a;stroke-width:1.23101;stroke-dasharray:none;stroke-opacity:1"
d="M 248.91677,2.1531106 V 25.234624 h 25.23579 v 71.091062 h -25.23579 l 0.22718,24.771794 -22.15643,0.0111 -0.13525,69.22013 22.0645,-0.53167 v 45.32551 h 74.47635 v 24.31252 h 24.92803 v 24.00478 h 23.38927 v 69.24454 h -23.08151 v 23.08151 h -24.92804 v 23.00458 H 126.20005 v -23.0046 H 100.50264 V 352.45355 H 74.959093 V 329.67979 H 51.800641 V 282.90126 H 25.949346 V 49.239398 h 26.08211 V 25.157686 H 74.574401 V 2.1531106 Z"
id="path5450"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc" />
<path
id="path5450-2"
style="fill:#bb9366;fill-opacity:1;stroke:#bb9366;stroke-width:1.23101;stroke-dasharray:none;stroke-opacity:1"
d="M 74.390221,2.2678325 V 25.272407 H 51.847272 V 49.35412 H 25.765157 l 0.407279,233.66186 H 51.708771 C 52.428181,236.89816 76.750102,25.189654 125.23904,25.349346 L 125.38401,2.2678325 Z M 51.616457,282.99979 v 46.79472 h 23.158456 v 22.77376 H 99.936159 V 331.11208 H 75.162005 v -47.89299 z m 48.701983,71.11686 v 21.76395 h 25.46901 v -21.76395 z m 223.27759,0.3847 v 21.37925 h 24.84868 v -21.37925 z m -197.58017,23.00457 v 21.37926 h 197.50082 v -21.37926 z"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc" />
<path
style="opacity:1;fill:#c4a47b;fill-opacity:1;stroke:#c4a47b;stroke-width:1.23101;stroke-dasharray:none;stroke-opacity:1"
d="M 74.466078,25.204849 125.2795,25.706117 V 49.249261 H 100.50534 V 213.58964 h 24.92804 v 47.39404 h 48.62505 v 24.00478 h 25.69742 v 22.92763 h 22.92764 v 23.00458 h 125.94813 v 23.4662 h -24.8511 v 23.00458 H 125.97195 v -23.38927 h -25.8513 V 330.99761 H 75.3465 V 283.29097 L 51.58133,283.07167 51.48734,49.319271 h 22.770363 z"
id="path6020"
sodipodi:nodetypes="ccccccccccccccccccccccccccc" />
<path
id="path7838"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.23101;stroke-dasharray:none;stroke-opacity:1"
d="m 25.598063,120.67844 v 18.25362 h 9.749535 v 10.54537 h 8.150658 v 9.92505 h 10.191932 v 7.70827 h 67.434082 v -7.97515 h 10.01161 v -9.83609 h 10.19193 v -20.82386 h 17.72227 v 20.64834 h 10.27849 v 9.74714 h 7.88618 v 7.79721 h 67.52306 v -7.6193 h 9.74712 v -9.83609 h 10.36745 v -10.36984 h 9.57161 v -17.80884 z m 153.100157,7.5111 h 9.3937 v 10.14625 l 10.55739,0.0433 v 10.01162 h 9.39851 v -10.15106 h -9.32158 V 128.1896 l 9.6149,0.0433 v 10.10297 h 8.80705 l 0.0529,10.23281 9.21576,0.0457 v 9.5692 l -9.25904,-0.0432 0.0433,-9.57161 h -8.90563 v 9.21576 h -9.56921 v -9.17008 l -10.63432,-0.089 0.0457,-10.14625 -9.43938,-0.0433 z m -135.288923,1.35124 h 9.393695 v 10.14624 l 10.557388,0.0433 v 10.0116 h 9.398505 V 139.5909 h -9.321566 v -10.05007 l 9.614893,0.0433 v 10.10297 h 8.807035 l 0.05293,10.2328 9.215777,0.0457 v 9.56922 l -9.259047,-0.0433 0.04333,-9.57161 h -8.905615 v 9.21578 h -9.569308 v -9.1701 l -10.634327,-0.089 0.04568,-10.14625 -9.439377,-0.0433 z" />
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 4.0 KiB

Wyświetl plik

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
id="vector"
version="1.1"
sodipodi:docname="coffee.svg"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs429" />
<sodipodi:namedview
id="namedview427"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.4183568"
inkscape:cx="74.73437"
inkscape:cy="168.85737"
inkscape:window-width="2353"
inkscape:window-height="1205"
inkscape:window-x="154"
inkscape:window-y="100"
inkscape:window-maximized="0"
inkscape:current-layer="vector" />
<path
id="path_3"
d="m 204.58272,84.840504 c 1.80845,1.808458 0.93255,0.93255 0,0 z m 161.69124,1.049943 c 1.80846,1.808458 0.93255,0.93255 0,0 z"
fill="#00ffff"
stroke-width="1.04994" />
<path
id="path_6"
d="M 198.66227,121.40716 C 164.79995,123.96587 67.446546,149.54661 72,206 c 0.77288,22.17762 1.937799,44.34026 4.818359,66.35352 C 79.88843,298.23675 84.05346,324.1649 92.388672,349 106.87188,385.44853 139.19135,413.74531 177,423.80664 c 38.87316,10.6193 72.80992,12.78497 119.29883,-1.24023 36.08225,-9.86128 67.99311,-36.53615 79.89453,-72.56641 3.28243,-8.75943 5.18945,-17.81392 6.80664,-27 19.07386,0.97598 38.69133,-1.20613 57,-7.02734 26.14401,-9.16172 52.49271,-29.44882 55,-58.97266 1.91791,-18.30342 -3.15941,-37.98625 -18,-49.91797 C 460.14447,191.68195 436.45271,188.46533 414.52539,190 c -5.64248,-1.83103 -18.35397,4.17907 -18.77539,-4.05664 -20.51648,-40.18303 -70.97477,-60.23537 -111.02904,-64.18953 -14.6071,-1.33203 -52.19637,-2.90538 -86.05869,-0.34667 z m 59.40974,25.5914 c 34.00891,4.20129 71.20236,8.75541 97.92799,32.02878 12.04549,10.07476 22.19688,28.31347 11.66797,42.97266 -17.98181,24.58629 -49.28152,33.87777 -77.66797,40.36133 -29.86209,6.48244 -60.80797,5.52205 -91,2.55664 -31.78569,-4.82551 -66.13067,-10.77655 -90.91797,-32.94531 C 98.324708,222.50175 93.436721,206.95897 101.77734,195 116.52696,170.94944 145.29279,161.04086 171,153.30664 181.21016,150.70499 191.52414,148.17017 202,147 m 218.78906,82.83594 c 8.29465,0.0507 16.46161,0.88182 24.02149,4.51562 16.06033,8.09021 9.01512,31.65913 -4.81055,38.25977 -15.35479,7.76011 -33.11284,9.67209 -50,11.38867 1.74373,-18.01393 4.07588,-36.01893 6,-54 8.07229,0.51408 16.49442,-0.21478 24.78906,-0.16406 z"
style="fill:#e0e0e0;fill-opacity:1"
sodipodi:nodetypes="zccccccccccccczcccccccccsccccs"
class="UnoptimicedTransforms"
transform="matrix(1.0499432,0,0,1.0499432,-12.755514,-8.604437)" />
<ellipse
style="fill:#6d4b41;fill-opacity:1;stroke:#6d4b41;stroke-width:8.81928;stroke-dasharray:none;stroke-opacity:1"
id="path869"
ry="61.231174"
rx="141.91878"
cy="207.67036"
cx="232.63841" />
<path
id="path_48"
d="m 251.83016,158.33652 c -37.40343,0.75701 -63.36678,0.0952 -100.79454,11.34569 -16.24464,6.79619 -36.11656,14.39542 -42.82643,32.06249 4.78012,30.85051 60.55359,22.12454 56.06726,2.78932 -4.14112,-14.16367 14.98436,-19.74444 25.60706,-15.89509 21.72808,3.90724 40.06135,18.15635 61.94665,21.11541 8.81362,1.93572 20.57083,-2.79421 17.76189,-13.61986 -3.87401,-6.98165 0.15546,-14.74069 8.48669,-14.61206 25.3553,-1.82586 47.15812,13.80802 70.34619,21.11541 7.04559,3.95606 15.78282,-3.15314 8.54549,-9.65318 -28.17339,-23.14739 -72.36886,-35.31236 -105.14026,-34.64813 z"
fill="#b59075"
stroke-width="1.04994"
sodipodi:nodetypes="ccccccccccc" />
<path
id="path_116"
d="m 293.91503,199.80928 c -6.74378,4.63357 0.26246,16.20339 -8.57891,20.24586 -16.21035,10.23238 -35.69663,0.43989 -52.40494,-3.62211 -14.15857,-3.75018 -29.51786,-10.91206 -44.09761,-6.12432 -10.45537,5.46407 -3.97321,21.89119 7.3496,19.42395 7.85354,-1.08254 15.55189,-2.72384 23.09875,1.04994 22.26778,6.96038 45.97102,11.5143 69.29625,8.72083 10.74591,-2.04005 15.89665,-12.26271 24.14869,-17.82069 10.27207,-2.42946 22.44888,12.79529 30.50715,1.75026 3.6419,-11.7421 -12.07265,-16.17559 -20.32085,-19.70319 -9.31468,-3.2573 -19.11384,-5.82373 -28.99813,-3.92053 z"
fill="#b59074"
stroke-width="1.04994" />
<path
id="path_147"
d="m 403.02197,222.38306 c -0.0267,0.81414 0.014,9.72705 0.0522,10.4763 34.64255,-0.0563 53.29636,2.38274 65.08433,16.86849 4.07833,5.36073 7.46536,10.61614 10.14969,8.40731 -1.55896,-19.67583 -20.1814,-34.58218 -36.43831,-36.16053 -12.80208,-1.14695 -26.07961,-1.13078 -38.8479,0.40843 z"
fill="#6aa5ac"
stroke-width="1.04994"
sodipodi:nodetypes="cccccc" />
<path
id="path_186"
d="m 460.30619,242.28571 c 10.12096,17.21107 -6.21833,36.21448 -22.95486,40.03178 -13.30848,3.42857 -26.93168,6.23692 -40.62901,7.26193 -1.5122,4.60515 -7.20282,17.17523 1.16081,15.74915 18.91586,-0.45376 38.87207,-2.29443 55.7123,-11.65703 13.42389,-7.04686 22.47412,-20.88228 24.65233,-35.77548 -5.44646,2.15729 -11.70413,-14.70729 -17.94157,-15.61035 z"
fill="#bbced3"
stroke-width="1.04994"
sodipodi:nodetypes="ccccccc" />
<path
id="path_190"
d="m 113.23766,244.43186 c 1.80846,1.80846 0.93255,0.93255 0,0 z m 237.28716,0 c 1.80845,1.80846 0.93255,0.93255 0,0 z"
fill="#97827b"
stroke-width="1.04994" />
<path
id="path_195"
d="m 345.2751,247.58169 c 1.80845,1.80846 0.93255,0.93255 0,0 z m -224.68783,1.04995 c 1.80845,1.80845 0.93255,0.93254 0,0 z"
fill="#a79691"
stroke-width="1.04994" />
<path
id="path_253"
d="m 70.189995,296.92902 c 0.629926,13.98805 -1.645857,28.32498 2.099886,41.99773 -28.140431,7.43995 -58.321931,24.8007 -66.8173322,54.59704 -8.1989547,25.34293 9.6334142,50.00435 29.1112222,64.51043 42.756945,32.57028 96.749739,46.56039 149.386879,52.05338 25.5652,3.02391 51.5673,2.30003 77.309,1.67134 57.38266,-3.75982 116.6972,-14.92208 165.89102,-46.48938 24.11133,-15.16744 48.18578,-40.1267 45.78907,-70.69583 -3.38744,-27.59496 -31.4487,-41.65942 -55.23856,-48.99769 -6.85822,-2.01593 -13.8449,-4.04776 -20.99886,-4.54941 2.54676,-12.39353 4.10714,-10.87785 -7.5916,-11.30175 -3.14834,19.85871 -11.24075,41.84354 -22.36118,58.5492 -9.33455,27.17011 -32.88124,46.94594 -58.24245,58.79681 41.17382,-5.65062 76.46923,-60.67063 83.99545,-91.34505 21.0823,4.35167 45.07074,10.02609 58.38839,28.34846 9.97386,15.41291 -3.73627,32.73579 -13.88235,44.06822 -102.21456,85.13259 -293.1194,73.31463 -394.848687,9.36596 -11.239792,-12.65782 -26.761281,-34.2522 -13.843942,-51.48772 11.010847,-15.95042 29.051523,-25.57542 47.10376,-31.34487 12.866757,37.17342 39.595189,70.25262 75.070939,87.90334 2.31294,-1.995 -10.94084,-7.59127 -14.17424,-11.11154 C 123.07428,420.23694 108.44957,408.22255 102.3592,391.4827 104.48313,388.76109 94.881802,380.02101 91.976315,372.52493 78.855769,349.74309 75.03431,323.22917 70.948054,297.74588 Z"
fill="#bbced3"
stroke-width="1.04994"
sodipodi:nodetypes="ccccccccccccccccccccccccc" />
<path
id="path_255"
d="m 392.52254,355.72584 c -11.61095,47.00009 -52.9146,84.18762 -99.67303,96.08463 -25.95794,8.69027 -52.51528,9.94878 -79.60246,8.14038 -28.81623,-2.72109 -56.32325,-11.95325 -80.06047,-28.48316 -26.74465,-18.75256 -46.217348,-46.5613 -57.746869,-76.7918 -21.268277,6.03319 -44.592521,18.65802 -52.059332,40.94779 -4.033753,54.61247 91.596391,82.66236 133.954901,89.65359 55.06789,8.76581 123.33906,7.49908 172.19067,-3.47111 36.30417,-7.72716 158.10597,-59.91085 118.3284,-103.02924 -14.74583,-13.87253 -35.78343,-19.84783 -55.33181,-23.05108 z"
fill="#e0e0e0"
stroke-width="1.04994"
sodipodi:nodetypes="cccccccccc" />
<path
id="path_259"
d="m 366.72268,388.62688 c -25.239,35.35724 -71.86044,51.22099 -113.53289,54.88575 -24.64979,3.20803 -48.92329,0.36748 -73.09511,-5.06211 -29.28828,-7.56528 -59.66752,-27.71314 -79.04618,-51.06092 20.56052,60.68192 97.11068,78.57432 150.78166,73.33055 45.36479,-4.70579 103.34036,-25.75429 114.89252,-72.09327 z"
fill="#6aa5ac"
stroke-width="1.04994"
sodipodi:nodetypes="cccccc" />
<path
id="path-6"
d="m 335.91409,14.700123 c 6.07897,8.502195 9.15,22.200031 -1.5216,28.596598 -15.58423,5.865427 -32.8143,4.136152 -49.13816,6.080236 -29.96753,2.843494 -64.81903,9.675727 -81.48748,37.769244 -5.63461,8.925651 -7.22003,19.092029 -8.76662,29.392259 -0.0139,0.002 -0.0272,0.004 -0.041,0.006 -0.0524,15.85132 2.979,29.86689 9.47205,43.36757 l -0.1497,0.004 c 8.96426,13.26214 19.47407,29.82765 35.82521,35.98515 11.44228,2.55751 10.86708,-12.15059 10.95673,-20.16423 -0.34864,-14.02186 1.12636,-23.57721 8.28676,-32.41085 -10e-4,-1.7e-4 -1.71324,3.22401 -0.004,0 1.70914,-3.22401 6.50044,-8.8905 11.20896,-13.74564 4.70853,-4.85513 13.2203,-8.82457 20.4821,-11.60064 7.26179,-2.77607 72.30554,-24.481806 85.15408,-42.383252 C 390.22515,49.263295 375.5393,12.278315 348.25104,1.2249125 338.85552,-2.7730205 332.81972,9.4121181 335.9142,14.699865 Z"
sodipodi:nodetypes="ccccccccccczzzccc"
style="fill:#b9cdd5;fill-opacity:0.632035;stroke-width:1.04994" />
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 9.2 KiB

Wyświetl plik

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 236 236"
id="vector"
version="1.1"
sodipodi:docname="footstr.svg"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs855" />
<sodipodi:namedview
id="namedview853"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="3.077113"
inkscape:cx="36.722733"
inkscape:cy="82.057435"
inkscape:window-width="2111"
inkscape:window-height="1205"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="vector" />
<path
id="path"
d="M 172.02415,18.470294 184.0521,17.337428 C 183.46273,10.976387 181.09464,5.5024373 177.46942,0.06921335 M 192.47167,156.67991 c 15.5856,0.84139 18.53887,6.43869 27.81342,-9.06293 8.36424,-13.97729 2.98775,-28.30011 6.50111,-43.04889 1.28219,-5.383382 3.71544,-10.250173 4.06304,-15.860124 0.33438,-5.423028 -1.49387,-10.524322 -2.08924,-15.860119 -0.56412,-5.044651 -0.37648,-10.678392 -5.27306,-14.038472 -5.43783,-3.732792 -9.84006,1.109076 -10.43665,6.109545 -0.58216,4.873588 0.22613,9.842337 -0.25619,14.726121 -0.42219,4.273169 -1.94252,8.12378 -2.04957,12.461522 -0.0842,3.439381 -1.44095,8.999487 -6.24492,8.999487 -8.64087,0 -6.69234,-13.223943 -7.85305,-18.062412 -2.12413,-8.856744 -5.55209,-16.82872 -6.3712,-26.055911 -0.60501,-6.810789 1.68392,-13.506025 0.77099,-20.391582 -0.61823,-4.662876 -2.97571,-11.244825 -8.24876,-12.861425 -7.26969,-2.228346 -10.63873,5.206651 -10.75058,10.595693 -0.11908,5.818398 2.05798,11.230098 2.33582,16.992986 0.44504,9.246449 1.17513,18.806703 1.32187,27.998775 0.0505,3.17429 -1.30142,6.191111 -1.09694,9.386925 0.3043,4.758036 7.30216,11.044308 3.84172,15.447761 -4.17971,5.31653 -10.19609,-0.53812 -12.80254,-4.12137 -5.1624,-7.098536 -8.57594,-15.31861 -13.30412,-22.634656 -2.22397,-3.438248 -5.69283,-6.276076 -10.26225,-5.172665 -12.21318,2.947717 -2.33583,18.130383 1.64783,23.276991 10.46793,13.52642 19.59112,27.62493 30.78433,40.78317 6.22928,7.32171 15.1011,11.07716 17.95894,20.39158 m 25.2587,-125.748094 c 1.05003,7.343236 2.40558,14.050933 2.40558,21.524448 l 9.62236,3.398597 c -0.44022,-9.51154 -3.83932,-18.966437 -12.02794,-24.923045 m -80.58727,15.86012 c -4.54536,7.60606 -6.26897,16.446944 -3.60839,24.923045 3.2283,-1.535033 6.07051,-2.759661 9.62236,-3.398597 -1.06447,-6.785866 -3.04667,-15.301617 -6.01397,-21.524448 m -78.181677,1.132865 c -1.516724,6.904817 -3.734679,13.678221 -6.013975,20.391583 L 66.178193,69.44925 C 63.783429,62.513846 62.590256,54.306234 58.961423,47.924801 M 45.730679,207.65887 c 2.619687,-8.54634 8.777997,-9.62257 13.923554,-15.98361 8.239146,-10.18672 17.115773,-20.0891 25.0025,-30.46389 3.560273,-4.68553 6.035625,-10.01113 9.622359,-14.72725 3.915098,-5.14661 14.260338,-20.37346 1.902823,-23.27699 -4.613922,-1.08416 -8.062336,1.69476 -10.322387,5.17266 -4.740215,7.29226 -8.192237,15.57237 -13.305319,22.63466 -2.521058,3.48243 -7.66902,8.81709 -11.941348,4.29809 -4.307209,-4.55525 2.592023,-10.65007 3.010596,-15.62562 0.276643,-3.27511 -1.021173,-6.31459 -1.065676,-9.54326 -0.179217,-12.86255 1.33871,-26.46487 3.259574,-39.169962 0.915326,-6.054035 -0.08539,-19.425248 -10.412597,-16.260022 -5.273053,1.6166 -7.629329,8.197417 -8.248767,12.861425 -0.810685,6.116341 1.065676,12.084278 0.589369,18.125849 -0.79625,10.10743 -4.172496,18.64244 -6.356771,28.32165 -1.105369,4.89624 1.127019,17.89134 -7.685861,17.89134 -5.484745,0 -6.349554,-6.21376 -6.356771,-9.96128 -0.0072,-4.01828 -1.954542,-7.39875 -2.286514,-11.32866 -0.412558,-4.87019 0.608615,-9.82988 0.152755,-14.72612 -0.436614,-4.68893 -4.809977,-9.93524 -10.2851,-6.76208 -5.149166,2.98624 -4.938676,9.80609 -5.484745,14.691 -0.552082,4.94496 -2.2408073,9.7132 -2.1361645,14.72726 0.1166711,5.62128 2.2720805,10.53338 3.8020355,15.86012 4.38058,15.24271 -1.812612,29.58705 7.009889,44.18176 2.410402,3.98769 5.784241,9.17735 10.774638,10.53905 4.794341,1.30959 11.712818,-1.43534 16.837928,-1.47612 M 19.269189,81.910772 C 12.507075,89.00591 8.660536,97.250906 8.444033,106.83382 c 3.191015,-1.40815 6.204017,-2.592 9.62236,-3.3986 0,-6.501516 3.111631,-15.605225 1.202796,-21.524448 m 80.587261,15.86012 c -0.33077,7.132518 -3.12125,13.511688 -4.811177,20.391588 3.414737,1.23029 6.451797,2.81857 9.622357,4.53146 2.54632,-8.11245 1.76571,-18.72174 -4.81118,-24.923048 m 92.74512,69.945398 c -12.84585,5.1704 -0.97547,22.18604 10.58339,17.445 14.94834,-6.13107 2.89633,-22.8703 -10.58339,-17.445 m -9.75227,20.68386 c 0,7.66497 -0.5653,15.04219 -1.20278,22.65731 5.29349,-5.30747 10.00123,-12.12846 14.43353,-18.12585 -4.67526,-1.02184 -8.89226,-2.61352 -13.23075,-4.53146 M 34.911537,218.45847 c -13.565121,3.1641 -4.321643,20.76996 7.210757,17.98878 7.880713,-1.89982 12.631752,-11.13607 5.510003,-16.77661 -3.211462,-2.54215 -8.91271,-2.10033 -12.72076,-1.21217"
fill="#e102c2"
stroke-width="1.16731"
sodipodi:nodetypes="ccccccccccccsccsccccccccccccccccccccccccccccccccccsccccsccccccccccccccccccccccccccccc" />
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 5.3 KiB

Wyświetl plik

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 128 128"
id="vector"
version="1.1"
sodipodi:docname="grownostr.svg"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs681" />
<sodipodi:namedview
id="namedview679"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="5.6734271"
inkscape:cx="85.398119"
inkscape:cy="54.376305"
inkscape:window-width="2220"
inkscape:window-height="1205"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="vector" />
<path
id="path_1"
d="M 9.2237444,0.4855187 C 32.034659,17.549714 41.727103,30.892033 55.971957,46.502328 58.126799,41.354513 55.870239,32.947005 54.169179,27.761995 47.607946,7.7608978 28.730145,0.49791601 9.2237444,0.4855187 Z"
fill="#6200ee"
stroke-width="1.23984"
sodipodi:nodetypes="cccc" />
<path
id="path_5"
d="M 71.434272,71.774094 C 80.152316,58.929793 119.82981,33.375586 120.80933,24.042475 99.670061,24.478899 79.223862,31.772877 72.714704,53.798632 c -1.569637,5.311473 -1.279192,12.49413 -1.280432,17.975462 z"
fill="#6200ee"
stroke-width="1.23984"
sodipodi:nodetypes="cccc" />
<path
id="path_7"
d="M 106.89705,34.150731 C 85.728341,55.379358 83.294009,51.880421 72.930546,73.417535 99.005618,72.29548 124.09579,52.447797 120.96023,24.204246 c -6.39101,2.873927 -10.26101,5.063861 -14.06318,9.946485 z"
fill="#3700b3"
stroke-width="1.23984"
sodipodi:nodetypes="cccc" />
<path
id="path"
d="M 8.7529192,0.4855187 C 9.9915193,16.18313 11.869563,33.641315 26.581503,42.190012 c 8.310646,4.827935 17.999994,6.140926 27.276476,7.8891 C 51.373073,34.847608 52.380816,36.195214 23.789146,11.482306 19.470095,7.8344807 15.869245,4.3525579 8.7529192,0.4855187 Z"
fill="#3700b3"
stroke-width="1.23984"
sodipodi:nodetypes="ccccc" />
<path
id="path_2"
d="m 32.780702,4.2050373 1.23984,1.23984 z"
fill="#818181"
stroke-width="1.23984" />
<path
id="path_3"
d="m 21.622143,10.404237 c 1.727097,1.77793 2.768563,2.535472 4.95936,3.71952 -2.997933,0.895163 -5.544564,1.175368 -8.678879,1.239839 v 3.71952 c 12.328967,0 18.716622,3.24714 26.036637,13.638238 h -8.67888 v 3.71952 c 3.973687,0.0037 8.635485,-0.582725 11.990491,1.987463 5.094503,3.903015 6.27607,10.830001 7.860585,16.610135 4.071635,14.857 6.185562,30.480222 6.185562,45.874078 0,7.10056 -12.142771,35.84811 4.959358,24.79679 2.201074,-11.68571 -0.793194,-24.10141 -0.550488,-34.715513 3.591321,-12.145615 10.481827,-24.099246 19.148086,-30.583129 4.708912,-1.594435 11.079209,2.020939 12.398399,-4.132386 L 84.853975,57.51815 C 92.594296,48.012298 98.343432,42.674788 110.89062,42.640072 v -2.479678 h -8.67889 l 4.95936,-6.1992 C 99.438212,34.304629 94.621434,42.099502 88.573495,46.359592 88.311889,42.963672 88.199063,42.11686 84.853975,41.400233 84.4658,54.132593 72.010668,71.537156 63.776697,79.835268 63.68247,68.402705 61.36025,55.477375 56.361216,45.119752 53.376921,38.936672 48.970531,33.724384 45.693634,27.761995 c -1.764292,-3.211186 -2.344537,-6.790604 -4.234053,-9.918719 -0.84929,1.54732 -0.928641,1.919272 -1.23984,3.719519 C 34.743368,17.11797 28.995471,10.14263 21.622143,10.404237 Z"
fill="#35b458"
stroke-width="1.23984"
sodipodi:nodetypes="cccccccccsccccccccccccccccc" />
<path
id="path_4"
d="m 42.699421,10.404237 1.23984,1.23984 z"
fill="#818181"
stroke-width="1.23984" />
<path
id="path_6"
d="m 103.45157,25.282315 1.23984,1.23984 z"
fill="#818181"
stroke-width="1.23984" />
<path
id="path_8"
d="m 12.943264,27.761995 1.23984,1.239839 -1.23984,-1.239839 m 76.870071,2.479679 1.23984,1.23984 z"
fill="#01ff01"
stroke-width="1.23984" />
<path
id="path_9"
d="m 73.695417,48.839272 1.23984,1.23984 z"
fill="#818181"
stroke-width="1.23984" />
<path
id="path_10"
d="m 0.08064685,127.8813 c 9.28878715,0 23.30736215,0.004 33.05793515,-0.19174 18.283652,-0.21966 37.954981,-11.48638 49.607023,-18.06006 -6.533287,-6.66089 -21.684854,-9.693089 -28.932735,-6.42159 -6.338502,4.41148 -16.531072,6.01457 -23.401073,9.18674 -10.617994,8.43313 -25.2028561,8.66177 -30.33115015,15.48665 z"
fill="#f99721"
stroke-width="1.18196"
sodipodi:nodetypes="cccccc" />
<path
id="path_11"
d="m 61.96967,101.51759 1.013989,1.01399 z"
fill="#857f2d"
stroke-width="1.01399" />
<path
id="path_12"
d="m 51.829781,105.57355 1.013988,1.01398 -1.013988,-1.01398 m 23.321745,0 1.013988,1.01398 z"
fill="#ffff01"
stroke-width="1.01399" />
<path
id="path_13"
d="m 31.334105,127.8813 h 96.756805 c -5.64836,-7.80264 -12.97803,-6.39827 -22.03672,-10.16321 -9.515816,-3.95557 -14.556986,-9.59132 -27.042819,-7.55117 -9.57051,1.56357 -14.283549,7.55523 -22.674747,10.00502 -9.678485,2.827 -17.396593,1.07585 -25.002519,7.70936 z"
fill="#df7f07"
stroke-width="1.19243" />
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 5.3 KiB

Some files were not shown because too many files have changed in this diff Show More