Other Subscribe to B4J library updates

DonManfred

Expert
Licensed User
Longtime User
jTelegrambot v0.19

New:
- Support for pinChatMessage and unpinChatMessage
- Support for ReplayKeyboard Markup (similar to Inlinekeyboard but shows a Custom Keyboard).
B4X:
            Dim kmark As ReplyKeyboardMarkup
            kmark.initkeyboard(2,3) ' 2 Rows, 3 Columns each
            kmark.SetButton(0,0,"BTN0-0") ' Set Button text for Button at Row 0 and Column 0
            kmark.SetButton(0,1,"BTN0-1")
            kmark.SetButton(0,2,"BTN0-2")
            kmark.SetButton(1,0,"BTN1-0")
            kmark.SetButton(1,1,"BTN1-1")
            kmark.SetButton(1,2,"CloseKB")
            kmark.initialize(kmark.GetKeyboard,True,False,True)
            Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Yo man","MARKDOWN",False,False,message.MessageId,kmark)

telegrambot089.png



- Support to send a Command to Hide the Customkeyboard.
B4X:
            Dim hidekb As ReplyKeyboardHide
            hidekb.initialize
            Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Thank you for using the Keyboard","MARKDOWN",False,False,message.MessageId,hidekb.hideKeyboard)
 

alwaysbusy

Expert
Licensed User
Longtime User
BANano v4.07

TAKE A BACKUP! <----

CHANGES:

1. [NEW] Besides the build-in Base64, there is an extra library based on another framework you can use in case you have problems with e.g. Chinese characters.

B4X:
Dim b64 As Base64
b64.Initialize
Log(b64.ToBase64("dankogai"))  ' ZGFua29nYWk=
Log(b64.Tobase64("小飼弾"))    ' 5bCP6aO85by+
Log(b64.ToBase64URI("小飼弾"))  ' 5bCP6aO85by-

Log(b64.FromBase64("ZGFua29nYWk="))  ' dankogai
Log(b64.FromBase64("5bCP6aO85by+"))  ' 小飼弾
Log(b64.FromBase64URI("5bCP6aO85by-"))  ' 小飼弾

Dim pngBase64 As String = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
Dim b() As Byte = b64.FromBase64Bytes(pngBase64)
' because the Log() method of B4J does not support printing a byte array
BANano.Console.Log(b)

2. [NEW] Added polyfills for the Fetch and AbortController APIs. They will be injected if you set the parameter BANano.TranspilerOptions.ShowWarningsUnsupportedForOldBrowsers = true

3. [FIX] Chained methods sometimes wrongly transpiled

4. [NEW] you are now able to use additional parameters using an Array in the WaitFor method

B4X:
BANano.WaitFor(PromiseResult, Me, "secondAsyncWait", Array(20))
Log("secondAsyncWait result:" & PromiseResult)

5. [NEW] I have added a warning in the B4J log if the method does not exist in a WaitFor call

B4X:
[WARNING]: The method WaitFor in banano_ready can not find '"DoesNotExist"'!

6. [FIX] Bad transpiling with BANano.Iif()

B4X:
Dim x As Object = Null
Dim xIsNull as Boolean = BANano.Iif(x = null, true, false) ' -> results in false because of (_x = null) instead of ==

7. [NEW] Try Catch can now also use the Javascript Finally keyword. See the example for what the difference is.

B4X:
Dim num As Int = 10
Dim divider As Int = 0
Try
   If divider = 0 Then
      BANano.Throw("You can not divide by 0!")
   Else
      Log(num/divider)
   End If  
Catch
   Log(LastException)
   ' will still do the Finally part, but not the "After the Try" log.
   Return
BANano.Finally 'ignore
   Log("Always doing this")          
End Try

Log("After the Try")

8. [NEW] Finally keyword also on Promise and Fetch

9. [CHANGE] BANanoEvent.CurrentTarget and RelatedTarget are now of the type Object

10. [CHANGE] BANanoElement.Last, First, Closest do now not return an Array anymore but directly the Element

11. [FIX] promise didn't bubble if BANano.CallBack is not called inside a sub. The

e.g.
B4X:
Private Sub Sub1() 'ignore
   Dim result, response, error as object
   Dim promise As BANanoPromise
   promise.CallSub(Me, "Sub2", Null)
   promise.Then(response)
       result = response
   promise.Else(error)
       result = error
   promise.Finally
       Log(result)
   promise.End
End Sub

'didn't work as _BANp,_B aren't passed to Sub3 as additional arguments, so calling BANano.ReturnThen() didn't work in Sub3
Private Sub Sub2()
   Sub3
End Sub

Private Sub Sub3()
   BANano.ReturnThen(True)
End Sub

12. [NEW] The Fetch API does now also have ...Wait methods like a Promise already has

B4X:
Dim fetch As BANanoFetch
Dim response As BANanoFetchResponse
Dim json As Object
fetch.Initialize("https://jsonplaceholder.typicode.com/todos/1", Null)
fetch.Then(response) ' not a wait
   Log("1")
   Return response.Json 'ignore
fetch.ThenWait(json) 'a wait
   Log("2")
   BANano.Sleep(1000)
   Log(json)
fetch.ElseWait(response) ' a wait
   Log("3")
   BANano.Sleep(1000)
   Log(response)
fetch.FinallyWait ' a wait
   Log("4")
   BANano.Sleep(1000)
   Log("Finally")
fetch.end

13. [FIX] Trasnpiler problem with BANanoElement.Last

14. [FIX] I fixed some problems where a method without parameters and written with () e.g. Initialize() was badly transpiled.
There are problably more methods that don't accept parameters where the () can give a problem. I will need to fix them as we discover them. General rule is, no params, don't use ().

15. [NEW] Support for importing an ES6 module.

IMPORTANT: Adding an ES6 module must use the BANano.Header.AddJavascriptES6File("math.js") method instead of the normal BANano.Header.AddJavascriptFile()!
This is because in Javascript a module is loaded differenly than a normal javascript file.

Content of math.js
B4X:
let sumAll = (a, b) => {return a + b;}
let subtractAll = (a, b) => {return a - b;}
let divideAll = (a, b) => {return a / b;}
let multiplyAll = (a, b) => {return a * b;}
let findModulus = (a, b) => {return a % b;}

export {sumAll, subtractAll, divideAll, multiplyAll, findModulus};

Example usage in B4J:
B4X:
Dim math As BANanoObject
Dim mathProm As BANanoPromise
mathProm = BANano.Import("math.js") ' <--- is an ES6 module
mathProm.Then(math)
   Log(math.RunMethod("sumAll", Array(5,6)))
mathProm.End

I also added a BANano.ImportWait() method, which directly returns the ES6 module as a BANanoObject.

16. [NEW] Support for nested b4xlib libraries.

IMPORTANT: There is currently a bug in B4J that prevents you to use them in Release mode. Erel has already fixed this bug and it will be possible in the next release of B4J.

17. [FIX] HandleEvents and On now converts the method parameter to lowercase

18. [NEW] The throw statement allows you to create a custom error.

Technically you can throw an exception (throw an error).

e.g.
B4X:
BANano.Throw("This number is not valid")
BANano.Throw(500)

19. [NEW] New methods on the BANano object that cover the 'Is' in B4J:

B4X:
BANano.IsBoolean(var)
BANano.IsDate(var)
BANano.IsDomelement(var)
BANano.IsFunction(var)
BANano.IsNull(var)
BANano.IsNumber(var)
BANano.IsObject(var)
BANano.IsMap(var)
BANano.IsList(var)
BANano.IsJson(var)
BANano.IsString(var)
BANano.IsUndefined(var)
BANano.IsError(var)
BANano.IsEmpty(var)
BANano.Existy(var)
BANano.IsCapitalzed(var)
BANano.IsDecimal(var)
BANano.IsInteger(var)

20. [FIX] LastMessageExeception does now not automatically append .Message (sometimes errors did not have a message and hence were not printed)

21. [NEW] BANanoObject.GetFunction and BANanoObject.Execute. Gets a function and then you can directly call the Execute method on it.

22. [REMOVED] DetectNoES6, ShowWarningsUnsupportedForOldBrowsers and the event are removed. They are replaced with a new system, see 24

23. [FIX] The callback in BANano.Window.SetTimeOut and BANano.Window.SetInterval was wrongly transpiled.

24. [NEW] new BANano controlword: BANano_OLDBROWSER

Must be used like this (the if can NOT contain extra conditions!):
B4X:
if BANano.OLDBROWSER then
   ' your old browser compatible stuff
else
   ' your ES6 stuff
end if

Example (here old browsers do not support wait methods or sleep):
B4X:
Dim promise As BANanoPromise
' the results from the promise
Dim Result As Map
Dim Error As String
                
' call the UploadAll method  
promise.CallSub(Me, "UploadAllFiles", Array(UploadedFiles))
  
If BANano.OLDBROWSER Then
      ' when it is done, we can use whatever the UploadAll has returned in its BANano.ReturnThen call
      ' we use can't use ThenWait here
      promise.Then(Result)
          ' let's show all our urls
          For i = 0 To Result.Size - 1
              Log(Result.GetKeyAt(i) & "=" & Result.GetValueAt(i))
          Next
      promise.Then(Null)
          ' now how about next we make a HTTP request after we got all files
          DoHTTP("assets/product.json")
          promise.Else(Error)
          Log("Error: " & Error)
      promise.End
Else
      ' when it is done, we can use whatever the UploadAll has returned in its BANano.ReturnThen call
      ' we use the ThenWait here because we use ...Wait functions or in this case a Sleep
      promise.ThenWait(Result)
          Log("Done, going to sleep for 2 seconds just to demonstrate ThenWait()...")
          Sleep(2000)
          Log("Printing result after 2 seconds")
          ' let's show all our urls
          For i = 0 To Result.Size - 1
              Log(Result.GetKeyAt(i) & "=" & Result.GetValueAt(i))
          Next
      promise.Then(Null)
          ' now how about next we make a HTTP request after we got all files
          DoHTTP("assets/product.json")
          promise.Else(Error)
          Log("Error: " & Error)
      promise.End
End If

a. two js files are created: one normal app.js for new browsers, one ES5_app.js for old browsers
b. In the html file, the scripts are no longer loaded with the <script> tags, but with a loadjs script. A check is done if the browser does support ES6 stuff. If it does the normal app.js is loaded, else the ES5_app.js.
c. all your own Wait methods will NOT be generated in the ES5_app.js

25. [NEW] a new polyfill was used for the Promise in old browsers which appears to be better than the old one.

26. [NEW] nested Promises are now allowed

27. [FIX] Transpiler error in GetAllResponseHeaders

28. [FIX] Consts on XMLHttpRequest: DONE, HEADERS_RECEIVED, LOADING, OPENED, UNSENT were not transpiled

30. [FIX] Transpiler error in BANanoXMLHttpRequest.SetWithCredentials()

31. [FIX] BANano.Window.RequestAnimationFrame now uses a callback syntax for its parameters. Also BANano.Window.CancelAnimationFrame was added.

32. [FIX] Datetime.DateFormat and BANano.Timeformat fix used in a condition or log()

33. [NEW] Conditional loading of assets.

Use the BANano.Header.AddCSSFileForLater, BANano.Header.AddJavascriptFileForLater and BANano.Header.AddJavascriptES6FileForLater to 'declare' which assets will be used.
Other assets like pictures, json or fonts this is not needed as they will be copied automatically if they are in the /Files folder.

* Check if bundle has already been defined
B4X:
BANano.AssetsIsDefined(bundleName as String) As Boolean

* Loads a bundle of assets and returns a promise.
If the asset is a CSS or JS file, it must have been Added with the BANano.header.Add...ForLater() methods
B4X:
' in Sub AppStart()
BANano.Header.AddCSSFileForLater("mini-nord.min.css")
...
' in Sub BANano_Ready()
Dim pathsNotFound() as String
If BANano.AssetIsDefined("Loader") = False then
   Dim prom as BANanoPromise = BANano.AssetsLoad("Loader", Array("./assets/1.jpg", "./styles/mini-nord.min.css"))
   prom.Then(Null)
       Log("Loader has been loaded!")
   prom.Else(pathsNotFound)
       Log("Doh! Loader has not been loaded completely!")
       For Each path As String In pathsNotFound
           Log(path)
       Next
   prom.End
End if

* Loads a bundle of assets and uses the BANano bundleEventName_AssetsLoaded() event
If the asset is a CSS or JS file, it must have been Added with the BANano.header.Add...ForLater() methods
The bundle name and eventName is the same.
B4X:
 ' in Sub AppStart()
 BANano.Header.AddCSSFileForLater("mini-nord.min.css")
 ...
 ' in Sub BANano_Ready()
 BANano.AssetsLoadEvent(Me, "Loader", Array("./assets/1.jpg", "./styles/mini-nord.min.css"))
 ...
 Sub loader_AssetsLoaded(pathsNotFound() As String)
   If BANano.IsNull(pathsNotFound) = False Then
       Log("Doh! Loader has not been loaded completely!")
       For Each path As String In pathsNotFound
           Log(path)
       Next
   Else
       Log("Loader has been loaded!")  
   End If
 End Sub

* Loads a bundle of assets and waits until it is loaded. Returns a String array containing the paths that failed.
If the asset is a CSS or JS file, it must have been Added with the BANano.header.Add...ForLater() methods
B4X:
 ' in Sub AppStart()
 BANano.Header.AddCSSFileForLater("mini-nord.min.css")
 ...
 ' in Sub BANano_Ready()
 Dim pathsNotFound() as String
 If BANano.AssetIsDefined("Loader") = False then
   pathsNotFound = BANano.AssetsLoadWait("Loader", Array("./assets/1.jpg", "./styles/mini-nord.min.css"))
   If BANano.IsNull(pathsNotFound) = False Then
       Log("Doh! Loader has not been loaded completely!")
       For Each path As String In pathsNotFound
           Log(path)
       Next
   Else
       Log("Loader has been loaded!")  
   End If
 end if

* Reset the dependency trackers
B4X:
BANano.AssetsReset

34. [NEW] In case CSS/JS assets are locale files in your /Files folder (not URLs), you can use the * wildcard:

e.g.

B4X:
BANano.Header.AddJavascriptFile("dayjs-locale*.js")' will load all javascript files starting with dayjs-locale

35. [NEW] Support for the Promise.All, Promise.AllSettled (only newer browsers) and Promise.Race

e.g.
B4X:
Sub BANano_Ready()
   ' All
   Dim ResultsAll() As Object  
   Dim pAll1 As BANanoPromise = 3 'ignore
   Dim pAll2 As BANanoPromise = 42 'ignore
   Dim pAll3 As BANanoPromise
   pAll3.CallSub(Me, "TheCallDelayed", Array("foo", 100, True))
  
   Dim AllProm As BANanoPromise = BANano.PromiseAll(Array(pAll1, pAll2, pAll3))
   AllProm.Then(ResultsAll)
       ' expected output: Array [3, 42, "foo"]
       Log(ResultsAll)
   AllProm.end
  
   ' AllSettled (not supported in old browsers yet!)
   Dim ResultsAllSettled() As BANanoObject
   Dim pAllSettled1 As BANanoPromise = 3 'ignore
   Dim pAllSettled2 As BANanoPromise
   pAllSettled2.CallSub(Me, "TheCallDelayed", Array(42, 100, False))
   Dim pAllSettled() As BANanoPromise = Array(pAllSettled1, pAllSettled2) 'ignore
   Dim AllSettledProm As BANanoPromise = BANano.PromiseAllSettled(pAllSettled)
   AllSettledProm.Then(ResultsAllSettled)
       ' expected output: fulfilled, rejected
       For i = 0 To ResultsAllSettled.Length - 1
           Log(ResultsAllSettled(i).GetField("status"))          
       Next
   AllSettledProm.end
  
   ' Race
   Dim ResultRace As Object
   Dim pRace1 As BANanoPromise
   pRace1.CallSub(Me, "TheCallDelayed", Array(3, 500, True))
   Dim pRace2 As BANanoPromise
   pRace2.CallSub(Me, "TheCallDelayed", Array("foo", 100, True))
   Dim RaceProm As BANanoPromise = BANano.PromiseRace(Array(pRace1, pRace2))
   RaceProm.Then(ResultRace)
       ' both resolved, but pRace2 is faster so
       ' expected output: foo
       Log(ResultRace)
   RaceProm.end
End Sub

Private Sub TheCallDelayed(ret As Object, ms As Long, DoResolve As Boolean) 'ignore
   BANano.Window.SetTimeout(BANano.CallBack(Me, "ResolveOrReject", Array(ret, DoResolve)), ms)
End Sub

private Sub ResolveOrReject(var As Object, DoResolve As Boolean) 'ignore
   If DoResolve Then
       BANano.ReturnThen(var)
   Else
       BANano.ReturnElse(var)
   End If      
End Sub

36. [NEW] New Initialize4 on BANanoObject

Can be used e.g. to connect a BANanoObject to a JavaScript object, with parameters.
This is basically the .Initialize, but with parameters. It does NOT do a New like the Initialize2 method!

37. Other minor Transpiler fixes and optimisations

Download: https://www.b4x.com/android/forum/t...-abstract-designer-support.99740/#post-627764

Alwaysbusy
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
PDFBox v0.27
- Added some nice Features. Working with XFDF Files, Splitting a PDF into multiple PNG, Splitting a PDF into multile PDF (one page each), adding Barcodes (using ZXING).
- A new example is provided which does some more than the old one ;-)

Also note to redownload the additional library zip from the Dropbox. It contains all the additional libs needed for barcode generation, PDF to PNG export...
 

stevel05

Expert
Licensed User
Longtime User
[B4x] MineXML Auto create Class and b4xlib

A tool written in B4j, The resulting code and libraries are cross platform​
  • Extract XML keys from an XML file
  • Merge multiple files to extract keys
  • Allows adding friendly names for the keys
  • Creates a class to access the selected keys from an XML file using the assigned friendly names (or tags from the XML if not defined)
  • Export the class as a b4xlib
  • Warn if a key is present in an XML file that is not recognised. (Optional)
There is also a test app companion to help check that the library is working correctly.​
 

stevel05

Expert
Licensed User
Longtime User
[B4x] MineXML Auto create Class and b4xlib

Update v1.1
  • Faster Parsing and handling of larger files
  • Shows count of data items for large lists
  • Better validation of entered Variable and Module names
  • Added B4xTable to display data in a better format and export to csv
  • Improved merging data storage
 

DonManfred

Expert
Licensed User
Longtime User
jTelegrambot 0.24

New Objects for Video, audio, Document and Photo.

Example of use. Basically it works like this when you receive a Audio, Video, Photo or Document:
B4X:
    Log($"MessageDocument: ${message.Document}"$)
    If message.Document <> Null Then
        Dim fdoc As Document = message.Document ' get the Document out of the Message
        Log($"Document.FileId = ${fdoc.FileId}"$)
        Log($"Document.FileName = ${fdoc.FileName}"$)
        Log($"Document.FileSize = ${fdoc.FileSize}"$)
        Log($"Document.MimeType = ${fdoc.MimeType}"$)
        Dim tfile As TelegramFile = jtb.getFile(fdoc.FileId)  ' Get the Telegramfile out of the Document
        Log($"File.Size = ${tfile.FileSize}"$)
        Log($"File.Path = ${tfile.FilePath}"$)
        Dim furl As String = $"https://api.telegram.org/file/bot${bottoken}/${tfile.FilePath}"$ ' Build the downloadurl for this File/document
        Log(furl)
        File.MakeDir(File.DirApp, "documents") ' Store documents in th documents folder to match it

        Dim j As HttpJob
        j.Initialize("",Me)
        j.Download(furl) ' Download file using okhttputils2
        Wait For (j) JobDone(j As HttpJob)
        If j.Success Then
            Dim out As OutputStream = File.OpenOutput(File.DirApp, tfile.FilePath, False)
            File.Copy2(j.GetInputStream, out)
            out.Close '<------ very important
        End If
        j.Release
    End If


Complete code for any kind of file(s). Document, Audio, Video and Photo

B4X:
Sub JTB_onMessageReceived(api As Object, id As Int, msg As Object)
    bld.Initialize(api)
    Log($"JTB_onMessageReceived( ${id}, ${msg}"$)
    Dim message As Message = msg
    Log($"MessageFrom: ${message.From}"$)

    Log($"MessageAudio: ${message.Audio}"$)
    If message.Audio <> Null Then
        Dim faudio As Audio = message.Audio
        Log($"Audio.FileId = ${faudio.FileId}"$)
        Log($"Audio.Duration = ${faudio.Duration}"$)
        Log($"Audio.Performer = ${faudio.Performer}"$)
        Log($"Audio.Title = ${faudio.Title}"$)
        Log($"Audio.FileSize = ${faudio.FileSize}"$)
        Log($"Audio.MimeType = ${faudio.MimeType}"$)
        Dim tfile As TelegramFile = jtb.getFile(faudio.FileId)
        Log($"File.Size = ${tfile.FileSize}"$)
        Log($"File.Path = ${tfile.FilePath}"$)
        Dim furl As String = $"https://api.telegram.org/file/bot${bottoken}/${tfile.FilePath}"$
        Log(furl)
        File.MakeDir(File.DirApp, "music")

        Dim j As HttpJob
        j.Initialize("",Me)
        j.Download(furl)
        Wait For (j) JobDone(j As HttpJob)
        If j.Success Then
            Dim out As OutputStream = File.OpenOutput(File.DirApp, tfile.FilePath, False)
            File.Copy2(j.GetInputStream, out)
            out.Close '<------ very important
        End If
        j.Release
    End If

    Log($"MessageDocument: ${message.Document}"$)
    If message.Document <> Null Then
        Dim fdoc As Document = message.Document
        Log($"Document.FileId = ${fdoc.FileId}"$)
        Log($"Document.FileName = ${fdoc.FileName}"$)
        Log($"Document.FileSize = ${fdoc.FileSize}"$)
        Log($"Document.MimeType = ${fdoc.MimeType}"$)
        Dim tfile As TelegramFile = jtb.getFile(fdoc.FileId)
        Log($"File.Size = ${tfile.FileSize}"$)
        Log($"File.Path = ${tfile.FilePath}"$)
        Dim furl As String = $"https://api.telegram.org/file/bot${bottoken}/${tfile.FilePath}"$
        Log(furl)
        File.MakeDir(File.DirApp, "documents")

        Dim j As HttpJob
        j.Initialize("",Me)
        j.Download(furl)
        Wait For (j) JobDone(j As HttpJob)
        If j.Success Then
            Dim out As OutputStream = File.OpenOutput(File.DirApp, tfile.FilePath, False)
            File.Copy2(j.GetInputStream, out)
            out.Close '<------ very important
        End If
        j.Release
    End If
    Log($"MessageDocument: ${message.Document}"$)
    If message.Video <> Null Then
        Dim fvid As Video = message.Video
        Log($"Video.FileId = ${fvid.FileId}"$)
        Log($"Video.Duration = ${fvid.Duration}"$)
        Log($"Video.Width = ${fvid.Width}"$)
        Log($"Video.Height = ${fvid.Height}"$)
        Log($"Video.MimeType = ${fvid.MimeType}"$)
        Log($"Video.FileSize = ${fvid.FileSize}"$)
        Dim tfile As TelegramFile = jtb.getFile(fvid.FileId)
        Log($"File.Size = ${tfile.FileSize}"$)
        Log($"File.Path = ${tfile.FilePath}"$)
        Dim furl As String = $"https://api.telegram.org/file/bot${bottoken}/${tfile.FilePath}"$
        Log(furl)
        File.MakeDir(File.DirApp, "videos")

        Dim j As HttpJob
        j.Initialize("",Me)
        j.Download(furl)
        Wait For (j) JobDone(j As HttpJob)
        If j.Success Then
            Dim out As OutputStream = File.OpenOutput(File.DirApp, tfile.FilePath, False)
            File.Copy2(j.GetInputStream, out)
            out.Close '<------ very important
        End If
        j.Release
    End If

    Dim from As User = message.From
    Log($"FromFirstName: ${from.FirstName}"$)
    Log($"FromLastName: ${from.LastName}"$)
    Log($"FromUserName: ${from.Username}"$)
    Log($"FromID: ${from.Id}"$)
    If message.Photo <> Null Then
        Log($"Photosizes: ${message.Photo}"$)
        Dim phsi As List = message.Photo
        If phsi.IsInitialized And phsi.Size > 0 Then
            For i= 0 To phsi.Size-1
                Dim photo As PhotoSize = phsi.Get(i)
                Log(photo)
                Log(photo.FileId)
                Dim tfile As TelegramFile = jtb.getFile(photo.FileId)
                Log($"File.Size = ${tfile.FileSize}"$)
                Log($"File.Path = ${tfile.FilePath}"$)
                Dim furl As String = $"https://api.telegram.org/file/bot${bottoken}/${tfile.FilePath}"$
                Log(furl)
                File.MakeDir(File.DirApp, "photos")

                Dim j As HttpJob
                j.Initialize("",Me)
                j.Download(furl)
                Wait For (j) JobDone(j As HttpJob)
                If j.Success Then
                    Dim out As OutputStream = File.OpenOutput(File.DirApp, tfile.FilePath, False)
                    File.Copy2(j.GetInputStream, out)
                    out.Close '<------ very important
                End If
                j.Release
   
            Next
        End If
    End If
   

    Log($"MessageChat: ${message.Chat}"$)
    Dim chat As Chat = message.Chat
    Log($"ChatFirstName: ${chat.FirstName}"$)
    Log($"ChatFirstName: ${chat.LastName}"$)
    Log($"ChatUserName: ${chat.Username}"$)
   
    If chat.Title <> Null Then
        Log($"ChatTitle: ${chat.Title}"$)
    End If
    Log($"ChatID: ${chat.Id}"$)

    If message.Caption <> Null Then
        Log($"MessageCaption: ${message.Caption}"$)
    End If
    If message.Contact <> Null Then
        Log($"MessageContact: ${message.Contact}"$)
        Dim cont As Contact = message.Contact
        Log($"ContactFirstname: ${cont.FirstName}"$)
        Log($"ContactLastName: ${cont.LastName}"$)
        Log($"ContactPhoneNumber: ${cont.PhoneNumber}"$)
        Log($"ContactUserId: ${cont.UserId}"$)
    End If
    Log($"MessageDate: ${message.Date}"$)
    Dim entitiesList As List = message.Entities
    If entitiesList.IsInitialized And entitiesList.Size > 0 Then
        For i=0 To entitiesList.Size-1
            Dim ent As MessageEntity = entitiesList.Get(i)
            'Log($"Entity.Length = ${ent.Length}"$)
            'Log($"Entity.Offset = ${ent.Offset}"$)
            If ent.Url <> Null Then
                Log($"Entity.URL = ${ent.Url}"$)
            End If
            If ent.User <> Null Then
                Log($"Entity.User = ${ent.User}"$)
            End If
            Log($"Entity.Type = ${ent.Type}"$)
        Next
    End If
    If message.Voice <> Null Then
        Dim voic As Voice = message.Voice
        Log($"Voice.Duration ${voic.Duration}"$)
        Log($"Voice.FileId ${voic.FileId}"$)
        Log($"Voice.Filesize ${voic.FileSize}"$)
        Log($"Voice.MimeType ${voic.MimeType}"$)
    End If
    If message.Video <> Null Then
        Dim vid As Video = message.Video
        Log($"Video.FileId ${vid.FileId}"$)
        Log($"Video.Duration ${vid.Duration}"$)
        Log($"Video Size ${vid.Width}x${vid.Height}"$)
        Log($"Video.MimeType ${vid.MimeType}"$)
        Log($"Video.Filesize ${vid.FileSize}"$)
    End If


    Log($"MessageText: ${message.Text}"$)
    If message.Text <> Null And message.Text <> "null" Then

        If message.Text = "/buttons" Then
            Dim ibld As InlineKeyboardButtonBuilder
            Dim mark As InlineKeyboardMarkup
           
            mark.initialize(ibld.Initialize.newRow.newButton("1").withCallbackData("BTN1").newButton("2").withCallbackData("BTN2").newButton("3").withCallbackData("BTN3").newRow.newButton("Google").withUrl("https://www.google.com").newRow.build)
            Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Click the Button!","MARKDOWN",False,False,message.MessageId,mark)
            glmap.Put(buttons.MessageId,buttons)
        else If message.Text = "/location" Then
            jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionFIND_LOCATION)
            jtb.sendLocation(jtb.byId(from.Id),50.8337006,6.441118,False,message.MessageId,Null)
        else If message.Text = "/url" Then
            jtb.sendMessage(jtb.byId(from.Id),"[jTelegramBot Thread](https://www.b4x.com/android/forum/threads/beta-jtelegrambot-create-your-own-telegram-bot.103821/)","MARKDOWN",False,False,message.MessageId,Null)
        else If message.Text = "/plainurl" Then
            bld.sendMessage(chat.Id,"Link without Preview [jTelegramBot Thread](https://www.b4x.com/android/forum/threads/beta-jtelegrambot-create-your-own-telegram-bot.103821/)",message.MessageId,False,True,Null,jtb.parsemodeMARKDOWN)
        else If message.Text = "/text" Then
            jtb.sendMessage(jtb.byId(from.Id),$"Testtext <b>Bold</b>, <i>Italic</i>
        new row..."$,"HTML",True,False,message.MessageId,Null)
        else If message.Text = "/document" Then
            jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionUPLOAD_DOCUMENT)
            jtb.sendDocument(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"jtbex.zip"),"DocumentCaption",False,message.MessageId,Null)
        else If message.Text = "/photo" Then
            jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionUPLOAD_PHOTO)
            jtb.sendPhoto(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"donmanfred.png"),"DocumentCaption",False,message.MessageId,replbld.forceReply)
        else If message.Text = "/audio" Then
            jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionUPLOAD_VIDEO)
            'jtb.sendAudio(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"EyesOfTheWorld.mp3"),223,"Fleedwood Mac","Eyes of the World",False,message.MessageId,replbld.forceReply)
        else If message.Text = "/sticker" Then
            jtb.sendSticker(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"cuppy.webp"),False,message.MessageId,Null)
        else if message.Text = "CloseKB" Then
            Dim hidekb As ReplyKeyboardHide
            hidekb.initialize
            Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Thank you for using the Keyboard","MARKDOWN",False,False,message.MessageId,hidekb.hideKeyboard)
            '
        else If message.Text = "/replykeyboard" Then
            Log("ReplyKeyboard requested")
            Dim kmark As ReplyKeyboardMarkup
            kmark.initkeyboard(2,3) ' 2 Rows, 3 Columns each
            kmark.SetButton(0,0,"BTN0-0") ' Set Button text for Button at Row 0 and Column 0
            kmark.SetButton(0,1,"BTN0-1")
            kmark.SetButton(0,2,"BTN0-2")
            kmark.SetButton(1,0,"BTN1-0")
            kmark.SetButton(1,1,"BTN1-1")
            kmark.SetButton(1,2,"CloseKB")
            kmark.initialize(kmark.GetKeyboard,True,False,True)
            Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Yo man","MARKDOWN",False,False,message.MessageId,kmark)
            'glmap.Put(buttons.MessageId,buttons)
        else If message.Text = "/anim" Then
            jtb.sendAnimation(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"anim.gif"),5,400,179,jtb.MediaByFile(File.DirApp,"giphy90.jpg"),False,message.MessageId,Null,"Caption...",jtb.parsemodeMARKDOWN)
        else If message.Text = "/start" Then
            jtb.sendMessage(jtb.byId(from.Id),$" Hello ${chat.Username}
    `Command   | Result
    ----------|-------------------------
    /location | Returns a Locationobject
    /document | Returns a Document
    /photo    | Returns a Photo
    /url      | Returns a URL with Preview
    /plainurl | Returns a URL without Preview
    /buttons  | Shows some buttons To Click on
    `
    Thank you For choosing Me :-)"$,"MARKDOWN",False,False,message.MessageId,Null)
        Else
        End If  
    End If
End Sub
 

stevel05

Expert
Licensed User
Longtime User
Project Overview

Update to v0.5
  • A little speed up for parsing projects
  • Greatly increased speed of displaying projects with partial on demand loading.
  • Sort on Project names now works as expected.
 
Top