Code Monkey home page Code Monkey logo

construkt's Introduction

Welcome to the Hits-of-Code developer page.

val y9vad9 by developer {
    fullName = "Vadym Yaroshchuk"
    age = 0x12
    
    stack = reference("MY STACK.md")

    contacts {
        telegram(username = "@y9vad9")
        instagram(username = "@y9vad9")
        twitter(username = "@y9vad9")
        email(address = "[email protected]")
    }
    
    website = "y9vad9.com"
}

๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป Looking for Job Opportunities
I'm a Kotlin software engineer with expertise in Android and Multiplatform development, actively seeking exciting job opportunities. You can refer to the my LinkedIn profile for details about me.

My stack

You can check it out there.

My publications

Contacts

construkt's People

Contributors

y9vad9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

construkt's Issues

support AttributeSet

Some view configurations can be set only using resources and xml, so it would be good to somehow support it.

take into account the inheritance of views that are generated

Idea

I think it would be nice to have inheritance for generated DSL views.

Example

We have two views to be generated: android.widget.TextView and android.widget.EditText. If we look into EditText hierarchy we will see that it inherited from TextView. So, to follow it and in order to memory usage it will be good to make next:

public interface TextViewScope : ViewScope<TextView> {
    public fun text(text: String)
    // other functions
    /* ... */
}

// other file
public interface EditTextScope : ViewScope<EditText>, TextViewScope {
   public fun selection(start: Int, end: Int)
}

Add functionality for providing values (DI)

Problem

I don't think it's necessary to add something to ViewScope<T> every time we need to use some common values. Also, there should be a way to provide instances as DI does.

Solution

I think in this case we should divide types of instances we provide. So, I propose next types of instances:

  • static โ€“ initializes on application init and never changes (for example, ApplicationInstance)
  • local โ€“ initializes in specific scope (for example, LocalContext that is unique for each view)
  • mutable โ€“ can be changed while program runs (for example, AccountInstance where account can change due to log in / log out)

Providing instances

To provide instance, we use provider function, for example:

class Account(val name: String)
val AccountInstance = instance<Account?> { error("Not yet initialized") }

internal fun ViewGroupScope<*>.AppView() {
    provider(AccountInstance provides Account("test")) {
        AccountView()
    }
}

Getting instances

To get instance, we just call corresponding instance in ViewScope<T>:

internal fun ViewGroupScope<*>.AccountView() {
    frameLayout(frameLayoutParams().maxSize()) {
        AccountInstance.state.constructOnEach { account ->
            if (account != null) {
                textView {
                    text("Hello, ${account.name}!")
                }
            } else {
                button(layoutParams().width(64.dp)) {
                    text("Sign in")
                    gravity(Gravity.CENTER)
                }
            }
        }
    }
}

It's important to have ViewScope<T>, because it stores instanceProvider: InstanceProvder.

Support different types of LayoutParams

We should recognize LayoutParams for cases where we can use, for example, margin or not.
Current workaround is different functions for layout params: marginLayoutParams() and layoutParams()

`android.view.Menu` default implementation

It's impossible to use android.view.Menu because usually views don't have setters for it (menu creates using context and resources, no other default ways), so we need android.view.Menu default DSL implementation.

For example, like this:

bottomNavigationBar(layoutParams().maxWidth()) {
    menu {
         item("Home")
         item(R.string.about)
         group("extra") {
             item("Quit app")
         }
    }
}

Currently, it's impossible even in manual way using getMenu() because such functions are not engaged into codegeneration (only set functions allowed).

add annotation for generating builder from get properties & functions

Idea

Add annotation for generating dsl builder functions for types like it made for menu.
It will take functions that returns specified type (in ApplyDSL annotations) and apply for it scope functions.

How I see it

Definition

@ApplyDSL(forType = Editable::class, using = EditableDSLScope::class)
@ViewDSL
typealias TextView = android.view.TextView

public class EditableDSLScope(private val editable: Editable) {
   operator fun plus(other: String) = editable.append(other)
}

Result

textView {
   // get / set prefixes will be removed
    editableText {
        +"something"
    }
}

Also, it can be done for ksp options to apply it for all classes.

Use case

It will be useful when you want to make your own DSL (because it is difficult / impossible to achieve this automatically, for example) and want to apply it to all functions, and not write for each of your implementations.
Without it, you need to specify every function yourself like this:

@OptIn(InternalConstruktApi::class)
fun TextViewDSLScope.editableText(block: EditableDSLScope.() -> Unit) {
     origin.getEditableText().apply(block)
}

@OptIn(InternalConstruktApi::class)
fun EditTextDSLScope.editableText(block: EditableDSLScope.() -> Unit) {
     origin.getEditableText().apply(block)
}

add an annotation that makes scope functions

Idea

Add annotation for generating scope functions for types.
It will take functions that returns specified type (in ScopedType annotation) and apply for it scope functions.

How I see it

Definition

@ScopedType(Editable::class)
typealias TextView = android.view.TextView

Result

textView {
    editableText {
        append("something")
    }
}

Also, it can be done for ksp options to apply it for all classes.

Use case

Very useful, since the get functions and immutable properties are not visible in the DSL without a direct call to origin. That is, it will be like origin.property.apply { /* code */ }
Without it, you need to specify every function yourself like this:

@OptIn(InternalConstruktApi::class)
fun TextViewDSLScope.editableText(block: Editable.() -> Unit) {
     origin.getEditableText().apply(block)
}

@OptIn(InternalConstruktApi::class)
fun EditTextDSLScope.editableText(block: Editable.() -> Unit) {
     origin.getEditableText().apply(block)
}

Remember views across reconstructions

Problem

Currently, any change to State<T> causes the reconstruction that removes all views and readds it to view.

Solution

I propose next variant with wrapping view adding feature and comparing views ids on each reconstruction:

remember(ids = 1, ...) {
  // this state is used for updating data of recyclerview that was created before
  // data update.
  val items = State<List<Account>>(emptyList())
  state.constructOnEach { state ->
    if(state is FooVM.State.Failure) {
     ...
    } else {
     // we set data to update old recycler view or for new, if it's first construction with recycler
     items.value = state.accounts
     recyclerView(id = 1, adapter = FooAdapter(), data = items)
    }
   }
}

*It requires custom realization of recycler view that has items (data) as state value

For this kind of realization, we should have custom StatedViewGroup to be able to compare new and old trees.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.