Rush • A new and improved way of building extensions

Make sure that you have restarted the terminal. If it still shows the same error, try building with the -r flag, this will invalidate the caches and build the extension afresh.

2 Likes

After rush build -r

:slightly_frowning_face: :slightly_frowning_face:

It looks like for some reason, Rush is still picking JDK 18 to compile your source files. Are you sure you restarted your terminal? If yes, can you try restarting your computer and then building with the -r flag again?

Now only show build faild
image

It’s most likely that your Java installation doesn’t have a JDK (even if the folder says otherwise). Try running javac -version in terminal to confirm this, if it says program not found then you don’t have JDK installed.

You can re-download the correct JDK installer from the link posted earlier in this topic, or try this:

3 Likes

Solved the problem. Thanks @Shreyash to help

if using ide maker extension work but when using rush
i got error with rush what is defferent?

package alfi;

import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ScrollView;

import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;

import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.Component;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;
import com.google.appinventor.components.runtime.VerticalScrollArrangement;


public class Vsrollhandler extends AndroidNonvisibleComponent implements Component {
    public static final int VERSION = 3;

    private final ComponentContainer container;

    private static final String LOG_TAG = "VerticalScrollHandler";

    private int oldScrollY = 0;

    private boolean userControl = true;

    private boolean scrollBarEnabled = true;

    private boolean fadingEdgeEnabled = true;

    private int overScrollMode = 1;

    private ScrollView scrollView = null;

    public Vsrollhandler(ComponentContainer container) {
        super(container.$form());
        this.container = container;
        Context context = (Context) container.$context();
        Log.d("VerticalScrollHandler", "VerticalScrollHandler Created");
    }

    private float deviceDensity() {
        return this.container.$form().deviceDensity();
    }

    private int px2dx(int px) {
        return Math.round(px * deviceDensity());
    }

    private int dx2px(int dx) {
        return Math.round(dx / deviceDensity());
    }

    private float dx2px(float dx) {
        return dx / deviceDensity();
    }

    @SimpleFunction
    public void RegisterScrollView(VerticalScrollArrangement verticalScrollArrangement) {
        this.scrollView = (ScrollView)verticalScrollArrangement.getView();
        this.scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            public void onScrollChanged() {
                Vsrollhandler.this.onScroll();
            }
        });
        this.scrollView.setOnTouchListener(new View.OnTouchListener() {
            private boolean touchDownDetected = false;

            private int touchDownScrollY = 0;

            private int touchDownPointerId;

            private float touchDownPointerY;

            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getActionMasked();
                if (action == 0) {
                    onTouchDown(event);
                } else if (action == 2) {
                    if (onMove(event))
                        return true;
                } else if (action == 1 || action == 3) {
                    onTouchUp(event);
                }
                return !Vsrollhandler.this.UserControl();
            }

            private void onTouchDown(MotionEvent event) {
                Vsrollhandler.this.TouchDown();
                this.touchDownDetected = true;
                this.touchDownScrollY = Vsrollhandler.this.dx2px(Vsrollhandler.this.scrollView.getScrollY());
                this.touchDownPointerId = Vsrollhandler.this.dx2px(event.getPointerId(0));
                this.touchDownPointerY = Vsrollhandler.this.dx2px(event.getY(0));
            }

            private boolean onMove(MotionEvent event) {
                if (this.touchDownDetected == true) {
                    int currentScrollY = Vsrollhandler.this.dx2px(Vsrollhandler.this.scrollView.getScrollY());
                    float currentPointerY = Vsrollhandler.this.dx2px(event.getY(event.findPointerIndex(this.touchDownPointerId)));
                    if (this.touchDownScrollY <= 0 && currentScrollY <= 0)
                        return Vsrollhandler.this.OverScrollDown(currentPointerY - this.touchDownPointerY);
                    int max = Vsrollhandler.this.MaxScrollPosition();
                    if (this.touchDownScrollY >= max && currentScrollY >= max)
                        return Vsrollhandler.this.OverScrollUp(this.touchDownPointerY - currentPointerY);
                } else {
                    onTouchDown(event);
                    return onMove(event);
                }
                return false;
            }

            private void onTouchUp(MotionEvent event) {
                Vsrollhandler.this.TouchUp();
                this.touchDownDetected = false;
            }
        });
        OverScrollMode(OverScrollMode());
        ScrollBarEnabled(ScrollBarEnabled());
        FadingEdgeEnabled(FadingEdgeEnabled());
    }

    @SimpleEvent
    public void ReachTop() {
        EventDispatcher.dispatchEvent(this, "ReachTop", new Object[0]);
    }

    @SimpleEvent
    public void ReachBottom() {
        EventDispatcher.dispatchEvent(this, "ReachBottom", new Object[0]);
    }

    @SimpleEvent
    public void ScrollChanged(int scrollY) {
        EventDispatcher.dispatchEvent(this, "ScrollChanged", new Object[] { Integer.valueOf(scrollY) });
        if (scrollY == 0) {
            ReachTop();
        } else if (MaxScrollPosition() - ScrollPosition() <= 0) {
            ReachBottom();
        }
    }

    public void onScroll() {
        int scrollY = dx2px(this.scrollView.getScrollY());
        if (scrollY < 0)
            scrollY = 0;
        if (this.oldScrollY != scrollY) {
            ScrollChanged(scrollY);
            this.oldScrollY = scrollY;
        }
    }

    @SimpleEvent
    public void TouchDown() {
        EventDispatcher.dispatchEvent(this, "TouchDown", new Object[0]);
    }

    @SimpleEvent
    public void TouchUp() {
        EventDispatcher.dispatchEvent(this, "TouchUp", new Object[0]);
    }

    @SimpleEvent
    public boolean OverScrollDown(float displacement) {
        if (displacement > 0.0F)
            return EventDispatcher.dispatchEvent(this, "OverScrollDown", new Object[] { Float.valueOf(displacement) });
        return false;
    }

    @SimpleEvent
    public boolean OverScrollUp(float displacement) {
        if (displacement > 0.0F)
            return EventDispatcher.dispatchEvent(this, "OverScrollUp", new Object[] { Float.valueOf(displacement) });
        return false;
    }

    @SimpleProperty
    public boolean UserControl() {
        return this.userControl;
    }

    @SimpleProperty
    public void UserControl(boolean enable) {
        this.userControl = enable;
    }
    @DesignerProperty(editorType = "boolean", defaultValue = "True")


    @SimpleProperty
    public boolean ScrollBarEnabled() {
        return this.scrollBarEnabled;
    }

    @SimpleProperty
    public void ScrollBarEnabled(boolean enabled) {
        this.scrollBarEnabled = enabled;
        if (this.scrollView != null)
            this.scrollView.setVerticalScrollBarEnabled(enabled);
    }
    @DesignerProperty(editorType = "boolean", defaultValue = "True")


    @SimpleProperty
    public boolean FadingEdgeEnabled() {
        return this.fadingEdgeEnabled;
    }

    @SimpleProperty
    public void FadingEdgeEnabled(boolean enabled) {
        this.fadingEdgeEnabled = enabled;
        if (this.scrollView != null)
            this.scrollView.setVerticalFadingEdgeEnabled(enabled);
    }
    @DesignerProperty(editorType = "boolean", defaultValue = "True")


    @SimpleProperty
    public int OverScrollMode() {
        return this.overScrollMode;
    }

    @SimpleProperty(description = "Can be:\n 0: ALWAYS\n1: OVER SCROLL IF CONTENT SCROLLS\n2: NEVER")
    public void OverScrollMode(int mode) {
        if (mode != 0 && mode != 1 && mode != 2)
            mode = 1;
        this.overScrollMode = mode;
    }
    @DesignerProperty(editorType = "non_negative_integer", defaultValue = "1")

    @SimpleProperty
    public int ScrollPosition() {
        int dxPosition = dx2px(this.scrollView.getScrollY());
        if (dxPosition < 0)
            return 0;
        if (dxPosition > MaxScrollPosition())
            return MaxScrollPosition();
        return dxPosition;
    }
    @SimpleProperty
    public int MaxScrollPosition() {
        View view = this.scrollView.getChildAt(this.scrollView.getChildCount() - 1);
        return dx2px(view.getBottom() - this.scrollView.getHeight());
    }

    @SimpleFunction
    public void ScrollTop() {
        if (this.scrollView == null)
            return;
        this.scrollView.fullScroll(33);
    }

    @SimpleFunction
    public void ScrollBottom() {
        if (this.scrollView == null)
            return;
        this.scrollView.fullScroll(130);
    }

    @SimpleFunction
    public void ArrowScrollUpward() {
        if (this.scrollView == null)
            return;
        this.scrollView.arrowScroll(33);
    }

    @SimpleFunction
    public void ArrowScrollDownward() {
        if (this.scrollView == null)
            return;
        this.scrollView.arrowScroll(130);
    }

    @SimpleFunction
    public void PageScrollUpward() {
        if (this.scrollView == null)
            return;
        this.scrollView.pageScroll(33);
    }

    @SimpleFunction
    public void PageScrollDownward() {
        if (this.scrollView == null)
            return;
        this.scrollView.pageScroll(130);
    }

    @SimpleFunction
    public void ScrollTo(int px) {
        if (this.scrollView == null)
            return;
        this.scrollView.scrollTo(0, px2dx(px));
    }

    @SimpleFunction
    public void ScrollBy(int px) {
        if (this.scrollView == null)
            return;
        this.scrollView.scrollBy(0, px2dx(px));
    }

    @SimpleFunction
    public void SmoothScrollTo(int px) {
        if (this.scrollView == null)
            return;
        this.scrollView.smoothScrollTo(0, px2dx(px));
    }

    @SimpleFunction
    public void SmoothScrollBy(int px) {
        if (this.scrollView == null)
            return;
        this.scrollView.smoothScrollBy(0, px2dx(px));
    }
}

erro Annotation@SimpleEventcan't be used on element "ReachTop". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleEventcan't be used on element "ReachBottom". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleEventcan't be used on element "ScrollChanged". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleEventcan't be used on element "TouchDown". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleEventcan't be used on element "TouchUp". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleEventcan't be used on element "OverScrollDown". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleEventcan't be used on element "OverScrollUp". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "RegisterScrollView". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "ScrollTop". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "ScrollBottom". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "ArrowScrollUpward". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "ArrowScrollDownward". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "PageScrollUpward". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "PageScrollDownward". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "ScrollTo". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "ScrollBy". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimpleFunctioncan't be used on element "SmoothScrollTo". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimplePropertycan't be used on element "ScrollPosition". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@SimplePropertycan't be used on element "MaxScrollPosition". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@DesignerPropertycan't be used on element "ScrollBarEnabled". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@DesignerPropertycan't be used on element "FadingEdgeEnabled". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@DesignerPropertycan't be used on element "OverScrollMode". It can only be used on members of class "alfi.Alfi".
│ erro Annotation@DesignerPropertycan't be used on element "ScrollPosition". It can only be used on members of class "alfi.Alfi".
└ failed

The name of you extension’s class should be same as the name used while creating the project using the create command. Change the class name from Vsrollhandler to Alfi to get rid of the errors.

If you wish to change the name of your extension, delete all the files inside of the .rush folder of your project and change the value of name field in rush.yml to desired name.

I make 2 clss Alfi and Vsrollhandler in Alfi pack age Java class on Alfi class succes compile and Vsrollhandler error’. Is any way make 2clas in one package

Yes, it’s possible. But you can not make multi components extension in Rush so you can only use those annotations in your main defined class. For ex, if you move your all blocks from Vscrollhandler to your main defined class (Alfi) or declare your Vscrollhandler as the main class as Shreyash mentioned then you would not see above errors.

1 Like

I So only one main class can not create two main classes…

Status update 2 – I spent the last month laying the foundation of the new update, implementing a few new features, and mostly, refactoring the horrible spaghetti only God knows which drunk head wrote (no, don’t look at me).

We now have a mostly working dependency management system in place, written entirely from scratch to best meet Rush’s needs. Along with that I recently added support for the helper blocks. The multi-component extensions are also supported now.

Talking about beta testing, I will certainly start it in a couple of days. I wanted to start it by the end of the last month, but things were mostly half-baked and/or broken and it didn’t really made any sense to beta-test at that phase. If you’re interested in beta testing Rush, PM me here on the community or on Discord (my username: shreyash#4002).

Also, if you have any feature requests, suggestions, or bug reports, now is the right time to let me know about them. Bring them on!

Before we finish, here’s a peek at a handy little feature I implemented to view the dependency tree of your extension project. This screenshot is from my media-notification extension.

10 Likes

how write permission in rush??
fill this example

<?xml version="1.0" encoding="utf-8"?>
<!-- <activity android:name=".MainActivity">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity> -->

This is how you declare permissions in the Android manifest:

<manifest ...>
    <uses-permission android:name="android.permission.CAMERA"/>
    <application ...>
        ...
    </application>
</manifest>

Read more about declaring permissions here:

iam still not understand can you show full exampel in rush permission

2 Likes

what wrong if from ide succes build apk ,if using rush errot build
whre is the problem

@SimpleFunction

public void Delete(String paramString) {
    boolean bool = false;
    String str = getAbsoluteFilePath(paramString);
    File file = new File(str);
    if (file.exists()) {
        if (file.isDirectory()) {
            File[] arrayOfFile = file.listFiles();
            if (arrayOfFile != null)
                for (File file1 : arrayOfFile) {
                    if (file1.isFile()) {
                        boolean bool1 = file1.delete();
                    } else {
                        Delete(file1.toString());
                    }
                }
        }
        bool = file.delete();
    }
   BolDelete(bool);
}
public String getAbsoluteFilePath(String url) {
    if (url.isEmpty())
        return url;
    String str1 = getExternalStoragePath();
    String str2 = url;
    if (url.startsWith("file:///")) {
        str2 = url.substring(7);
    } else if (url.startsWith("//")) {
        if (this.isRepl)
            str2 = getReplFilePath() + url.substring(2);
    } else if (url.startsWith("/")) {
        if (!url.startsWith(str1))
            str2 = str1 + url;
    } else {
        str2 = str1 + File.separator + url;
    }
    return str2;
}

@SimpleEvent
public void BolDelete(boolean Boolean) {
    EventDispatcher.dispatchEvent(this, "FileOrFolderDeleted", Boolean);
}

public String getExternalStoragePath() {
    return getExternalStorageDirectory().getAbsolutePath();
}

private String getReplFilePath() {
    return (Build.VERSION.SDK_INT >= 29) ? (this.context.getExternalFilesDir(null).getAbsolutePath() + "/assets/") : (getExternalStoragePath() + "/AppInventor/assets/");
}

}

And the error is?

How can i access assets folder in rush ( in which the rush icon is present)

in kodular
file:///storage/emulated/0/Kodular/assets/external_comps/{your package}/assets/{your file}
= for example
file:///storage/emulated/0/Kodular/assets/external_comps/com.aemo.extension/assets/icon.png

1 Like