1
0
Fork 0
mirror of https://gitlab.com/dadada_/uuidgen.git synced 2025-06-09 10:31:42 +02:00

Initial commit

This commit is contained in:
Tim Schubert 2020-11-07 20:39:23 +01:00
commit 3c8a8522d8
Signed by: dadada
GPG key ID: EEB8D1CE62C4DFEA
67 changed files with 1824 additions and 0 deletions

1
app/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

60
app/build.gradle Normal file
View file

@ -0,0 +1,60 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId "li.dadada.uuidgen"
minSdkVersion 22
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
dataBinding = true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
testImplementation "androidx.room:room-testing:$room_version"
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

21
app/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,24 @@
package li.dadada.uuidgen
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("li.dadada.uuidgen", appContext.packageName)
}
}

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="li.dadada.uuidgen">
<application
android:name=".UuidGen"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.UUIDGen">
<activity
android:name=".ui.MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.UUIDGen.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,19 @@
package li.dadada.uuidgen
import android.app.Application
import androidx.room.Room
import li.dadada.uuidgen.model.AppDatabase
import li.dadada.uuidgen.model.UuidDao
class UuidGen : Application() {
internal val uuidDao : UuidDao by lazy {
db.uuidDao()
}
private val db: AppDatabase by lazy {
Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "uuids"
).build()
}
}

View file

@ -0,0 +1,9 @@
package li.dadada.uuidgen.model
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [Uuid::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun uuidDao(): UuidDao
}

View file

@ -0,0 +1,32 @@
package li.dadada.uuidgen.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.*
@Entity
data class Uuid(
@PrimaryKey val uuid: String = UUID.randomUUID().toString(),
@ColumnInfo(name = "created") val created: Long = Date().time
) {
override fun toString(): String {
return uuid
}
override fun equals(other: Any?): Boolean {
return if (other !is Uuid) {
false
} else {
uuid == other.uuid
}
}
override fun hashCode(): Int {
var result = uuid.hashCode()
result = 31 * result + created.hashCode()
return result
}
}

View file

@ -0,0 +1,19 @@
package li.dadada.uuidgen.model
import androidx.lifecycle.LiveData
import androidx.room.*
@Dao
interface UuidDao {
@Query("SELECT * FROM `uuid` ORDER BY `created` ASC")
fun getAll(): LiveData<List<Uuid>>
@Query("SELECT * FROM `uuid` WHERE `uuid` IS :uuid")
fun get(uuid: String) : List<Uuid>
@Insert(onConflict = OnConflictStrategy.ABORT)
fun insertAll(vararg uuid: Uuid)
@Delete
fun delete(user: Uuid)
}

View file

@ -0,0 +1,37 @@
package li.dadada.uuidgen.ui
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import kotlinx.coroutines.*
import li.dadada.uuidgen.*
class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_history -> {
findNavController(R.id.nav_host_fragment)
.navigate(R.id.action_uuid_gen_fragment_to_uuid_list_fragment)
true
}
else -> super.onOptionsItemSelected(item)
}
}
}

View file

@ -0,0 +1,52 @@
package li.dadada.uuidgen.ui
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import li.dadada.uuidgen.R
import li.dadada.uuidgen.databinding.UuidGenFragmentBinding
import li.dadada.uuidgen.viewmodel.ClipBoardUtil
import li.dadada.uuidgen.viewmodel.UuidViewModel
class UuidGenFragment : Fragment(), CoroutineScope by MainScope() {
private val viewModel: UuidViewModel by lazy {
ViewModelProvider(this).get(UuidViewModel::class.java)
}
private lateinit var clipboardManager: ClipboardManager
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding: UuidGenFragmentBinding =
DataBindingUtil.inflate(inflater, R.layout.uuid_gen_fragment, container, false)
clipboardManager = inflater.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
binding.buttonGen.setOnClickListener { view ->
launch { genUuid(view) }
}
return binding.root
}
private suspend fun genUuid(view: View) {
val uuid = viewModel.genUuid()
if (uuid != null) {
ClipBoardUtil.copyUuid(uuid, view, clipboardManager)
} else {
Snackbar.make(view, R.string.warn_duplicate_uuid, Snackbar.LENGTH_SHORT)
}
}
}

View file

@ -0,0 +1,58 @@
package li.dadada.uuidgen.ui
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import li.dadada.uuidgen.R
import li.dadada.uuidgen.model.Uuid
import li.dadada.uuidgen.viewmodel.UuidAdapter
import li.dadada.uuidgen.viewmodel.UuidViewModel
import li.dadada.uuidgen.databinding.UuidListFragmentBinding
import li.dadada.uuidgen.viewmodel.ClipBoardUtil
import li.dadada.uuidgen.viewmodel.OnUuidClickListener
/**
* A simple [Fragment] subclass as the default destination in the navigation.
*/
class UuidListFragment : Fragment() {
private val uuidAdapter = UuidAdapter(object : OnUuidClickListener {
override fun onUuidClicked(view: View, uuid: Uuid): Boolean {
ClipBoardUtil.copyUuid(
uuid,
view,
activity?.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager)
return true
}
})
private lateinit var binding : UuidListFragmentBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.uuid_list_fragment, container, false)
binding.listUuids.apply {
adapter = uuidAdapter
layoutManager = LinearLayoutManager(this@UuidListFragment.context)
}
return binding.root;
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val viewModel = ViewModelProvider(this).get(UuidViewModel::class.java)
viewModel.uuidList.observe(viewLifecycleOwner,
Observer<List<Uuid>> { list -> uuidAdapter.submitList(list) })
}
}

View file

@ -0,0 +1,16 @@
package li.dadada.uuidgen.viewmodel
import android.content.ClipData
import android.content.ClipboardManager
import android.view.View
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import li.dadada.uuidgen.model.Uuid
object ClipBoardUtil {
fun copyUuid(uuid: Uuid, view: View, clipboardManager: ClipboardManager) {
clipboardManager.setPrimaryClip(ClipData.newPlainText("uuid", uuid.uuid))
Snackbar.make(view, "Copied $uuid to clipboard", BaseTransientBottomBar.LENGTH_SHORT)
.show()
}
}

View file

@ -0,0 +1,8 @@
package li.dadada.uuidgen.viewmodel
import android.view.View
import li.dadada.uuidgen.model.Uuid
interface OnUuidClickListener {
fun onUuidClicked(view: View, uuid: Uuid) : Boolean
}

View file

@ -0,0 +1,56 @@
package li.dadada.uuidgen.viewmodel
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import li.dadada.uuidgen.R
import li.dadada.uuidgen.databinding.UuidItemBinding
import li.dadada.uuidgen.model.Uuid
class UuidAdapter(private val controller: OnUuidClickListener) : ListAdapter<Uuid, UuidAdapter.UuidViewHolder>(UuidDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UuidViewHolder {
return from(parent, controller)
}
override fun onBindViewHolder(holder: UuidViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
}
class UuidViewHolder(
private val binding: UuidItemBinding,
private val listener: OnUuidClickListener
) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: Uuid) {
binding.uuid = item
binding.listener = listener
binding.executePendingBindings()
}
}
companion object {
fun from(parent: ViewGroup, listener: OnUuidClickListener) : UuidViewHolder {
val binding : UuidItemBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.uuid_item,
parent, false
)
return UuidViewHolder(binding, listener)
}
}
}
class UuidDiffCallback : DiffUtil.ItemCallback<Uuid>() {
override fun areItemsTheSame(oldItem: Uuid, newItem: Uuid): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Uuid, newItem: Uuid): Boolean {
return oldItem == newItem
}
}

View file

@ -0,0 +1,45 @@
package li.dadada.uuidgen.viewmodel
import android.app.Application
import android.content.ClipData
import android.content.ClipboardManager
import android.view.View
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.SavedStateHandle
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import li.dadada.uuidgen.UuidGen
import li.dadada.uuidgen.model.Uuid
import li.dadada.uuidgen.model.UuidDao
internal class UuidViewModel(application: Application,
savedStateHandle: SavedStateHandle
) : AndroidViewModel(application) {
private val uuidDao : UuidDao by lazy {
(application as UuidGen).uuidDao
}
val uuidList = uuidDao.getAll()
suspend fun genUuid() : Uuid? {
return genUuid(uuidDao)
}
companion object {
private suspend fun genUuid(uuidDao: UuidDao) : Uuid? = withContext(Dispatchers.IO) {
val uuid = Uuid()
with(uuidDao) {
if (get(uuid.uuid).isEmpty()) {
insertAll(uuid)
uuid
} else {
null
}
}
}
}
}

View file

@ -0,0 +1,31 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.5"
android:scaleY="0.5"
android:translateX="27"
android:translateY="27">
<path
android:pathData="m24.585,14.831l10.448,0l0,46.683q0,12.353 4.478,17.809 4.478,5.404 14.515,5.404 9.985,0 14.463,-5.404 4.478,-5.456 4.478,-17.809l0,-46.683l10.448,0l0,47.97q0,15.029 -7.463,22.698 -7.412,7.669 -21.926,7.669 -14.566,0 -22.029,-7.669 -7.412,-7.669 -7.412,-22.698z"
android:strokeWidth="0.264583"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m40.025,42.285l4.996,0l0,22.324q0,5.907 2.141,8.516 2.141,2.584 6.941,2.584 4.775,0 6.916,-2.584 2.141,-2.609 2.141,-8.516l0,-22.324l4.996,0l0,22.94q0,7.187 -3.569,10.854 -3.544,3.667 -10.485,3.667 -6.966,0 -10.534,-3.667 -3.544,-3.667 -3.544,-10.854z"
android:strokeWidth="0.144474"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m52.524,42.721l3.923,0l0,28.996L52.524,71.717Z"
android:strokeWidth="0.134163"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m43.15,36.505l21.887,-0l0,-4.6q0,-5.825 -2.639,-8.521 -2.639,-2.715 -8.333,-2.715 -5.656,-0 -8.276,2.715 -2.639,2.696 -2.639,8.521zM40.021,40.313l0,-7.824q0,-8.182 3.412,-12.009 3.393,-3.827 10.632,-3.827 7.277,-0 10.689,3.846 3.412,3.846 3.412,11.99l0,7.824z"
android:strokeWidth="0.13023"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
</group>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
</vector>

View file

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -0,0 +1,31 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.5"
android:scaleY="0.5"
android:translateX="27"
android:translateY="27">
<path
android:pathData="m24.585,14.831l10.448,0l0,46.683q0,12.353 4.478,17.809 4.478,5.404 14.515,5.404 9.985,0 14.463,-5.404 4.478,-5.456 4.478,-17.809l0,-46.683l10.448,0l0,47.97q0,15.029 -7.463,22.698 -7.412,7.669 -21.926,7.669 -14.566,0 -22.029,-7.669 -7.412,-7.669 -7.412,-22.698z"
android:strokeWidth="0.264583"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m40.025,42.285l4.996,0l0,22.324q0,5.907 2.141,8.516 2.141,2.584 6.941,2.584 4.775,0 6.916,-2.584 2.141,-2.609 2.141,-8.516l0,-22.324l4.996,0l0,22.94q0,7.187 -3.569,10.854 -3.544,3.667 -10.485,3.667 -6.966,0 -10.534,-3.667 -3.544,-3.667 -3.544,-10.854z"
android:strokeWidth="0.144474"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m52.524,42.721l3.923,0l0,28.996L52.524,71.717Z"
android:strokeWidth="0.134163"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m43.15,36.505l21.887,-0l0,-4.6q0,-5.825 -2.639,-8.521 -2.639,-2.715 -8.333,-2.715 -5.656,-0 -8.276,2.715 -2.639,2.696 -2.639,8.521zM40.021,40.313l0,-7.824q0,-8.182 3.412,-12.009 3.393,-3.827 10.632,-3.827 7.277,-0 10.689,3.846 3.412,3.846 3.412,11.99l0,7.824z"
android:strokeWidth="0.13023"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
</group>
</vector>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:drawable="@color/material_blue_grey_800" android:state_pressed="true" />
<!-- default -->
<item android:drawable="@color/background_floating_material_light" />
</selector>

View file

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="m6.4368,4.2333l1.4097,0l0,6.2986q0,1.6667 0.6042,2.4028 0.6042,0.7292 1.9583,0.7292 1.3472,0 1.9514,-0.7292 0.6042,-0.7361 0.6042,-2.4028l0,-6.2986l1.4097,0l0,6.4722q0,2.0278 -1.0069,3.0625 -1,1.0347 -2.9583,1.0347 -1.9653,0 -2.9722,-1.0347 -1,-1.0347 -1,-3.0625z"
android:strokeWidth="0.264583"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
<path
android:pathData="m8.52,7.9375l0.6741,0l0,3.012q0,0.797 0.2889,1.149 0.2889,0.3487 0.9365,0.3487 0.6442,0 0.9332,-0.3487 0.2889,-0.352 0.2889,-1.149l0,-3.012l0.6741,0l0,3.0951q0,0.9697 -0.4815,1.4645 -0.4782,0.4948 -1.4147,0.4948 -0.9398,0 -1.4213,-0.4948 -0.4782,-0.4948 -0.4782,-1.4645z"
android:strokeWidth="0.144474"
android:fillColor="#000000"
android:strokeColor="#00000000"/>
</vector>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.UUIDGen.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.UUIDGen.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_gen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/action_generate"
android:textSize="40sp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="uuid"
type="li.dadada.uuidgen.model.Uuid" />
<variable
name="listener"
type="li.dadada.uuidgen.viewmodel.OnUuidClickListener" />
</data>
<LinearLayout
android:id="@+id/uuid_item"
android:layout_width="match_parent"
android:layout_height="42sp"
android:layout_gravity="top"
android:onClick="@{(view) -> listener.onUuidClicked(view, uuid)}"
android:orientation="vertical"
android:padding="6dip">
<TextView
android:id="@+id/uuid_uuid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="@{uuid.uuid}"
android:textSize="16sp"
android:typeface="monospace"
tools:text="3966a07a-4699-48a2-b5a2-53d08a9f3d8f" />
</LinearLayout>
</layout>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.UuidListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_uuids"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:listSelector="@drawable/uuid_selector"
tools:layout_editor_absoluteX="88dp"
tools:layout_editor_absoluteY="287dp"
tools:listitem="@layout/uuid_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="li.dadada.uuidgen.ui.MainActivity">
<item
android:id="@+id/action_history"
android:orderInCategory="100"
android:title="@string/action_history"
android:icon="@drawable/ic_baseline_history_24"
app:showAsAction="always" />
</menu>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/uuid_gen_fragment">
<fragment
android:id="@+id/uuid_gen_fragment"
android:name="li.dadada.uuidgen.ui.UuidGenFragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/uuid_list_fragment" >
<action
android:id="@+id/action_uuid_gen_fragment_to_uuid_list_fragment"
app:destination="@id/uuid_list_fragment" />
</fragment>
<fragment
android:id="@+id/uuid_list_fragment"
android:name="li.dadada.uuidgen.ui.UuidListFragment"
tools:layout="@layout/uuid_list_fragment" />
</navigation>

View file

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.UUIDGen" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

View file

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#3DDC84</color>
</resources>

View file

@ -0,0 +1,8 @@
<resources>
<string name="app_name">UuidGen</string>
<string name="action_history">History</string>
<!-- Strings used for fragments for navigation -->
<string name="first_fragment_label">UUID List Fragment</string>
<string name="warn_duplicate_uuid">Duplicate UUID. Try again!</string>
<string name="action_generate">Generate</string>
</resources>

View file

@ -0,0 +1,25 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.UUIDGen" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
<style name="Theme.UUIDGen.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.UUIDGen.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="Theme.UUIDGen.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>

View file

@ -0,0 +1,17 @@
package li.dadada.uuidgen
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}