Jump to content

CastleSoft

uniGUI Subscriber
  • Posts

    205
  • Joined

  • Last visited

  • Days Won

    20

Posts posted by CastleSoft

  1. unit uniLottie;
    {------------------------------------------------------------------------------}
    {                                                                              }
    { uniLottie                                                                    }
    { =============                                                                }
    {                                                                              }
    { Description:  This class contains a wrapper for the Lottie javascript        }
    {               library.                                                       }
    {                                                                              }
    {               Github:  https://lottiefiles.com/web-player                    }
    {                                                                              }
    { Installation: Under the files folder copy the following files:               }
    {               lottie/lottie-player.js                                        }
    {               lottie/myanimation.json                                        }
    {                                                                              }
    { This source code is copyrighted material.                                    }
    {                                                                              }
    { Copyright (c) CastleSoft Pty Ltd. 2017-2023. All rights reserved.            }
    {                                                                              }
    {                                                                              }
    { MIT License                                                                  }
    {                                                                              }
    { 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.                                                                }
    {                                                                              }
    { Version       Date          Description            Modified by               }
    { ---------------------------------------------------------------------------- }
    {  1.0.0        29-Jan-2023   Initial Release          Andrew Tierney          }
    { ---------------------------------------------------------------------------- }
    
    interface
    
    uses
      System.SysUtils, System.Classes, Vcl.Controls, Vcl.Forms, uniGUIBaseClasses,
      uniGUIClasses, uniPanel, uniHTMLFrame,
      uniGUITypes, uniGUIJSUtils, uniGUIApplication,System.Json;
    
    type TPlayModes = (Normal, Bounce);
    type TDirection = (Forward, Backward);
    
    
    type
      TUniLottie = class(TUniCustomHTMLFrame)
      private
        { Private declarations }
        FOnFinished : TNotifyEvent;
        fControls : Boolean;
        fHover    : Boolean;
        fAutoplay : Boolean;
        fLoop     : Boolean;
        fBackgroundColour: String; {can be transparent or    rgba(0, 0, 0, 0.51) }
        fWidth    : string;        { Can be 300px or 30% - pixels or percent }
        fHeight   : string;        { Can be 300px or 30% - pixels or percent }
        fAnimationSpeed: Float32;
        fPlayMode : TPlayModes;
        fDirection : TDirection;
        fAnimationFile: string;  { place in files/lottie/lf20_yom6uvgj.json  for example}
    
        procedure H_OnFinished(Sender: TObject);
        function GetOnFinished: TNotifyEvent;
        procedure SetOnFinished(const Value: TNotifyEvent);
    
        function BuildHTML(): string;
    
      protected
        { Protected declarations }
        procedure WebCreate; override;
        procedure JSEventHandler(AEventName: string; AParams: TUniStrings); override;
      public
        { Public declarations }
        constructor Create(owner: TComponent); override;
        destructor Destroy; override;
        procedure Clear;
        procedure Play;
      published
        { Published declarations }
          property ShowControls: Boolean read fControls write fControls;
          property Hover: Boolean read fHover write fHover;
          property Autoplay: Boolean read fAutoplay write fAutoplay;
          property Loop: Boolean read fLoop write fLoop;
          property BackgroundColour: string read fBackgroundColour write fBackgroundColour;
          property AnimationWidth: string read fWidth write fWidth;
          property AnimationfHeight: string read fHeight write fHeight;
          property AnimationSeed: float32 read fAnimationSpeed write fAnimationSpeed;
          property PlayMode: TPlayModes read fPlayMode write fPlayMode;
          property Direction: TDirection read fDirection write fDirection;
          property AnimationFile: string read fAnimationFile write fAnimationFile;
      end;
    
    procedure Register;
    
    implementation
    
    procedure Register;
    begin
      RegisterComponents('uniGUI Extensions', [TUniLottie]);
    end;
    
    { TUniLottie }
    
    function TUniLottie.BuildHTML: string;
    var bstr: string;
    begin
      // <lottie-player src="https://assets1.lottiefiles.com/datafiles/HN7OcWNnoqje6iXIiZdWzKxvLIbfeCGTmvXmEm1h/data.json"  background="transparent"  speed="1"  style="width: 300px; height: 300px;" hover loop controls autoplay></lottie-player>
    
      bstr := '';
      bstr := bstr + '<lottie-player ';
      bstr := bstr + ' id="'+JSName+'" ';
      bstr := bstr + ' src="/files/lottie/'+fAnimationFile+'" ';
    
      if fControls then
          bstr := bstr + ' controls ';
    
      if fHover then
          bstr := bstr + ' hover ';
    
      if fAutoplay then
          bstr := bstr + ' autoplay ';
    
      if fLoop then
          bstr := bstr + ' loop ';
    
      bstr := bstr + ' background="' + fBackgroundColour + '" ';
      bstr := bstr + ' style="width: ' + fWidth + '; height: ' + fHeight + ';"';
    
      bstr := bstr + ' speed="' + FloatToStr(fAnimationSpeed) + '"';
    
      if fPlayMode = TPlayModes.Normal then
          bstr := bstr + ' mode="normal" '
      else
          bstr := bstr + ' mode="bounce" ';
    
      bstr := bstr + 'complete: function() { ajaxRequest('+JSName+',"onFinished",[]); },';
      bstr := bstr + '/>';
      result := bstr;
    
    end;
    
    procedure TUniLottie.Clear;
    begin
       fControls := false;
       fHover    := false;
       fAutoplay := true;
       fLoop     := true;
       fBackgroundColour := 'transparent';
       fWidth    := '100%';
       fHeight   := '100%';
       fAnimationSpeed := 1;
       fPlayMode := TPlayModes.Normal;
       fDirection := TDirection.Forward;
       fAnimationFile := '';
    end;
    
    constructor TUniLottie.Create(owner: TComponent);
    begin
      inherited;
      Clear;
    end;
    
    destructor TUniLottie.Destroy;
    begin
      inherited;
    end;
    
    function TUniLottie.GetOnFinished: TNotifyEvent;
    begin
        result := FOnFinished;
    end;
    
    procedure TUniLottie.H_OnFinished(Sender: TObject);
    begin
        if Assigned(FOnFinished) then
           FOnFinished(Sender);
    end;
    
    procedure TUniLottie.JSEventHandler(AEventName: string; AParams: TUniStrings);
    begin
      inherited;
    
      if AEventName = 'onFinished' then
      begin
         H_OnFinished(self);
      end;
    end;
    
    procedure TUniLottie.Play;
    begin
      HTML.Text := BuildHTML;
    end;
    
    procedure TUniLottie.SetOnFinished(const Value: TNotifyEvent);
    begin
         FOnFinished := Value;
    end;
    
    procedure TUniLottie.WebCreate;
    begin
      inherited;
      // Optional Webcreate extras
    end;
    
    Initialization
    
    UniAddJSLibrary('lottie/lottie-player.js',False,[upoFolderFiles,upoPlatformBoth]);
    
    end.

     

  2. 2023-01-31-uniLottie-V100.zip

     

    Attached is a SIMPLE uniGUI component to display Lottie Animations using the player. It's raw and a quick hack that could do with some work, use as you like.

    A handy little control to add Lottie animations to your uniGUI app.

    https://lottiefiles.com/featured

     

    image.thumb.png.73f56254f21b43d352e345e2dd9b935a.png

     

     

    image.thumb.png.3303bbd60e79f47dc99c338ac95b7b51.png

     

    1138656265_ScreenShot2023-01-31at3_22_44pm.thumb.png.d2bb3c278cc5c766073b03ddf93a5200.png871906218_ScreenShot2023-01-31at3_22_47pm.thumb.png.6364e101ba4a1b31bb92982196e11ad5.png

     

    Properties published from the control are:

    image.thumb.png.7e39faeb9afcb388e40263fcdff35b8c.png

     

          property ShowControls: Boolean read fControls write fControls;
          property Hover: Boolean read fHover write fHover;
          property Autoplay: Boolean read fAutoplay write fAutoplay;
          property Loop: Boolean read fLoop write fLoop;
          property BackgroundColour: string read fBackgroundColour write fBackgroundColour;
          property AnimationWidth: string read fWidth write fWidth;
          property AnimationfHeight: string read fHeight write fHeight;
          property AnimationSeed: float32 read fAnimationSpeed write fAnimationSpeed;
          property PlayMode: TPlayModes read fPlayMode write fPlayMode;
          property Direction: TDirection read fDirection write fDirection;
          property AnimationFile: string read fAnimationFile write fAnimationFile;

     

     

    • Like 1
  3. Cool...

    Looks pretty straight forward:

    <script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
    <lottie-player src="https://assets3.lottiefiles.com/packages/lf20_yom6uvgj.json"  background="transparent"  speed="1"  style="width: 300px; height: 300px;"  loop  autoplay></lottie-player>

    https://github.com/LottieFiles/lottie-player

    Include the lottie-player.js

    Expose a few properties:

    - Playmode (Normal or Bounce)

    - Direction (Forward or Backward)

    - Background Colour (transparent, RGB)

    - Width, Height (pixels or percent)

    - Animation Speed (1x)

    - Controls (true/false)

    - Autoplay (true/false)

    - Hover (true/false)

    - Loop (true/false)

    - Lottie File/URL (json file or url)

    That's about it... If you don't I'll try and throw one together when I get a change.

  4. Hi Fred,

    "for what ?" - The existing styles are basic, and if you have desk/mobile apps using Delphi Styles it would be nice to match the web interface.

    "As for tiktok mode effects ?" - Actually Lottie animations would be very cool. (https://lottiefiles.com) and Skia4Delphi implements these. So a port would be nice. 🙂

    A full bootstrap and material design theme would also be nice.

    I agree it may be a tricky task, but I believe it would be possible for a smart parser to read the Delphi style and generate CSS. 

    Not a high priority obviously.. A nice to have.

    Reactive layouts are higher on the list for me.  

  5. 1 hour ago, Sherzod said:

    Hello,

    Thanks for the contribution!

    If you want, you can attach here or in the thread:

    http://forums.unigui.com/index.php?/forum/15-components-and-code-samples/ 

    No problem..

    I've uploaded the PAS files into the link above.

    It's works for a number of projects, is very very raw. Anyone who wishes to improve/cleanup/make a component or include in the uniGUI core is free to do whatever with the code. (the code is from all over the net. Just returning the favour). 🙂
     

    • Thanks 1
  6. Merry Christmas... Attached is an raw/rough hack to implement SAML/SSO for office365/AzureAD

    The attached code is very RAW, needs some cleanup. But it is working for me in a few projects.

    It's FREE for anyone to improve/make into a component for others who use uniGUI.

    It contains a few PAS files:

    - ServerModule (Basically contains a List of OpenIDSessions

    - MainModule uses the BeforeLogin event to call TOpenIDConnect.DoCallBack and create a UserInfo object (ie. Who is logged in)

    - Login (a uniLoginForm) has a Button to Login via SSO (ie.   TOpenIDConnect.DoLogin(...)

    - OpenIDConnect.pas and Pkg.Json.DTO.pas are the core bits which do the dirty work.

    It's been extracted from a few projects.. So you WILL need to read/cut/paste etc.

    If anyone wants to create a polished FREE component from this for the uniGUI community that would be great. (or if it was included in the uniGUI Core).

     

     

     

    SAML and SSO.zip

    • Like 2
    • Thanks 2
  7. I have a working SAML/SSO setup with Office365/AzureAD in uniGUI.

    The code is VERY VERY rough, snippets from stack overflow, google, etc etc..  Patched together and it seems to be working ok.

    Is anyone interested in me uploading the code, cleaning it up and making it a FREE component/feature for other uniGUI users.

  8. NOT tested.. maybe something like this ?

    function beforeInit(sender, config)
    {
      config.listConfig={
            getInnerTpl: function() {
                var tpl = '<table width="100%">'+
                         '<tr>'+
                                '<td style="vertical-align:top;width:100%">'+
                                '<div><span style="font-weight:bold;">{name} {middlename} </span><span style="float:right;color:blue">{lastname}</span></div>'+
                               '</td>'+
                         '</tr>'+
                        '</table>';
                return tpl;
            }
        };
    }

  9. In a LOGIN form I have a button which builds a URL (for OpenID Connect) Microsoft authentication.

    And redirects to the OpenID for authentication, the URL contains the UniSession.SessionID.

    Using:

     UniSession.UrlRedirect(loginRequest);

    Microsoft authenticates ok, and the URL (callback used in the loginRequest) is called.

    This triggers:    UniGUIServerModuleHTTPCommand

    if ARequestInfo.URI.Contains('/auth') then
          I extract the TOKEN and the SessionID I sent to Microsoft (it comes back)
          I store the SessionID in a Dictionary<string,string> so I have SessionID,Token
          Then set Handled := true;
          AResponseInfo.Redirect('/?_S_ID='+sID);   (ie.. The original session id sent to Microsoft, returned etc).
     
    This returns back to the LOGIN form on the ORIGINAL Session_ID.
     
    On the FORM_SHOW I check if the Current Session_ID is in the Server Dictionary and if approved.
               set the LOGIN to mrOK.
     
    All seems to be great..!!!!
     
    EXCEPT.. Strange Javascript errors appear when I do anything on the main form ???
     
    Any ideas ?
     
    If you have been redirected like:
     
    LOGIN -> HTTPCommand -> /?_S_ID=xxxxx. 
     
    Is there anything else you need to keep the session valid ?
     
    Thanks
    Andrew
     
       

     

     

     

  10. The link below has a BASIC implementation of SAML for ASP.NET. (323 lines of c# code), a Delphi/uniGUI version would be nice.

    This would assist in Education / Business sites who use SAML for single-sign-on to take up uniGUI as an option.

    https://github.com/jitbit/AspNetSaml

    How SAML works?

    SAML workflow has 2 steps:

    1. User is redirected to the SAML provider (where he authenticates)
    2. User is redirected back to your app, where you validate the payload

    Here's how you do it (this example is for ASP.NET MVC:

    1. Redirecting the user to the saml provider:

    //this example is an ASP.NET MVC action method
    public ActionResult Login()
    {
    	//TODO: specify the SAML provider url here, aka "Endpoint"
    	var samlEndpoint = "http://saml-provider-that-we-use.com/login/";
    
    	var request = new AuthRequest(
    		"http://www.myapp.com", //TODO: put your app's "entity ID" here
    		"http://www.myapp.com/SamlConsume" //TODO: put Assertion Consumer URL (where the provider should redirect users after authenticating)
    		);
    
    	//redirect the user to the SAML provider
    	return Redirect(request.GetRedirectUrl(samlEndpoint));
    }

    2. User has been redirected back

    User is sent back to your app - you need to validate the SAML response ("assertion") that you recieved via POST.

    Here's an example of how you do it in ASP.NET MVC

    //ASP.NET MVC action method... But you can easily modify the code for Web-forms etc.
    public ActionResult SamlConsume()
    {
    	// 1. TODO: specify the certificate that your SAML provider gave you
    	string samlCertificate = @"-----BEGIN CERTIFICATE-----
    BLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAH123543==
    -----END CERTIFICATE-----";
    
    	// 2. Let's read the data - SAML providers usually POST it into the "SAMLResponse" var
    	Saml.Response samlResponse = new Response(samlCertificate, Request.Form["SAMLResponse"]);
    
    	// 3. We're done!
    	if (samlResponse.IsValid())
    		username = samlResponse.GetNameID();
    }

    Reading more attributes from the provider

    SAML providers usually send more data with their response: username, first/last names etc. Here's how to get it:

    if (samlResponse.IsValid())
    {
    	//WOOHOO!!! user is logged in
    
    	//Some more optional stuff for you
    	//let's extract username/firstname etc
    	string username, email, firstname, lastname;
    	try
    	{
    		username = samlResponse.GetNameID();
    		email = samlResponse.GetEmail();
    		firstname = samlResponse.GetFirstName();
    		lastname = samlResponse.GetLastName();
    	}
    	catch(Exception ex)
    	{
    		//insert error handling code
    		//no, really, please do
    		return null;
    	}
    
    	//user has been authenticated, put your code here, like set a cookie or something...
    	//or call FormsAuthentication.SetAuthCookie() or something
    }

     

  11. > www.unigui.com
    ;; Got SERVFAIL reply from 8.8.8.8, trying next server
    Server:        8.8.4.4
    Address:    8.8.4.4#53

    ** server can't find www.unigui.com: SERVFAIL

    forums.unigui.com
    ;; Got SERVFAIL reply from 8.8.8.8, trying next server
    Server:        8.8.4.4
    Address:    8.8.4.4#53

    ** server can't find forums.unigui.com: SERVFAIL

    > forums.unigui.com
    Server:        139.130.4.4
    Address:    139.130.4.4#53

    Non-authoritative answer:
    Name:    forums.unigui.com
    Address: 82.113.145.191

    Google DNS servers 8.8.8.8 and 8.8.4.4 having problems with your domain.

    Telstra 139.130.4.4 appears to resolve ok.

     

     

  12. Would it be possible to add support for V3 (or make an additional) reCaptcha control ?
    V3 doesn't require the 'checkbox - I'm not a robot' question.  It just displays a 'hovering' logo right bottom side of the page.
    No user interaction is required with v3, which is nice.

    The sample howto for php is below:

    The basic JS code 

    <script src="https://www.google.com/recaptcha/api.js?render=your reCAPTCHA site key here"></script> 

    <script> 

        grecaptcha.ready(function() { 

        // do request for recaptcha token 

        // response is promise with passed token 

            grecaptcha.execute('your reCAPTCHA site key here', {action:'validate_captcha'}) 

                      .then(function(token) { 

                // add token value to form 

                document.getElementById('g-recaptcha-response').value = token; 

            }); 

        }); 

    </script> 

    The basic HTML code 

    <form id="form_id" method="post" action="your_action.php"> 

        <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response"> 

        <input type="hidden" name="action" value="validate_captcha"> 

        .... your fields 

    </form> 

    The basic PHP code 

        if(isset($_POST['g-recaptcha-response'])){ 

            $captcha=$_POST['g-recaptcha-response']; 

        } 

        else 

            $captcha = false; 

      

        if(!$captcha){ 

            //Do something with error 

        } 

        else{ 

            $secret = 'Your secret key here'; 

            $response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret= 

                .$secret.&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']); 

            if($response.success==false) 

            { 

                //Do something with error 

            } 

        } 

    ... The Captcha is valid you can continue with the rest of your code 

      

     

    • Like 1
    • Upvote 1
  13. Code is now available via Github:

    https://github.com/CastleSoft/uiXtra

    Contains the latest source code (v1.07 - RIO release, uniGUI 1.5 (latest release) - Forum patches/updates in this thread ** Thank you all ** )

    MIT lic.. Feel free to FORK / hack / etc.

    Sorry. I don't have much time these days to monitor the forums. Enjoy..

    PS.. v1.06 is the original release for pre RIO / pre 1.5 / pre patches - if anyone needs it. 

  14. I have a custom control based on TUniCustomHTMLFrame  which works with a <canvas> element.

     

    I have a Javascript function called resizeCanv() which is as follows:

     

    function resizeCanv(){
       var canvas = $( "canvas#'+JSName+'" )[0];
       canvas.width = canvas.parentElement.clientWidth;
       canvas.height = canvas.parentElement.clientHeight;
     }
     
    In my TUniFAKECanvas controls .create the  HTML.Text is set to <canvas id="'+JSName+'"></canvas> 
    and the resizeCanv() is called.
     
    It all works great.
     
    I then added the Align to allow me to use 'client' for sizing.
     
    When the form is resized, the HTMLFrame resizes ok, but I need to call my resizeCanv() javascript function.
     
    Inside the custom control, what should I hook / trap and whats the recommended way inside a custom control to trap a forms align=client
    so the child controls can be resized/moved etc ?
     
    Thanks
     
     
     
  15. A few minor tweaks and another another freebie.

     

    iTyped  - https://github.com/luisvinicius167/ityped

     

    Simply add the uniTyped control (resize to your size).

     

    var s: TStrings;
    begin
      s := TStringList.Create;
      s.Add('Welcome to the jungle');
      s.Add('Restarting soo...');
      UniTyped1.text := s;
      UniTyped1.PlayTyped;
      s.Free;
    end;
     
    or 
     
    Just set the properties in the control and do a UniTyped.PlayTyped.
     
    Source code and Example below (includes the sweetalert/jquerytoast/iTyped).
     
     
     
     
     
     
     
    • Upvote 1
  16. A few more fixes.

     

    - Z-Index for jToast fixed

    - buttonsStyling (typo / spelling incorrect in SweetAlert2)

     

    New css file added to jToast.  (re-grab the files/jtoast and   files/sweetalert folders in any code you use for the updated).

     

    Added 'custom' to  jToast..  when 'Pos: custom' the Left and Top are used for positioning.

     

    *** If you are using an older version you may need to ignore the buttonStyling missing error and toggle the 'buttonsStyling' and save to fix.

    *** If you have Z-Index issues.. Clear your browser cache and try again.

     

    Enjoy.

    uniExtensions-V5.zip

    • Like 1
×
×
  • Create New...