Providence: Cataloguing and Data/media Management Application

README: Providence version 1.7.17

About CollectiveAccess

CollectiveAccess is a web-based suite of applications providing a framework for management, description, and discovery of complex digital and physical collections in museum, archival, and research contexts. It is comprised of two applications. Providence is the “back-end” cataloging component of CollectiveAccess. It is highly configurable and supports a variety of metadata standards, data types, and media formats. Pawtucket2 is CollectiveAccess' general purpose public-access publishing tool. It provides an easy way to create web sites around data managed with Providence. (You can learn more about Pawtucket2 at https://github.com/collectiveaccess/pawtucket2)

CollectiveAccess is freely available under the open source GNU Public License version 3.

About CollectiveAccess 1.7.17

Version 1.7.17 is a maintenance release with these bug fixes and minor improvements:

  • Add option to display nested type hierarchies as indented list in menus rather than nested menus.
  • Fix fatal error in library checkout due to incorrect type checking in display template parser.

Note that this version is not yet compatible with PHP version 8. Please use versions 7.3 or 7.4.

Installation

First make sure your server meets all of the requirements. Then follow the installation instructions.

Updating from a previous version

NOTE: The update process is relatively safe and rarely, if ever, causes data loss. That said BACKUP YOUR EXISTING DATABASE AND CONFIGURATION prior to updating. You almost certainly will not need the backup, but if you do you'll be glad it's there.

To update, decompress the CollectiveAccess Providence 1.7.17 tar.gz or zip file and replace the files in your existing installation with those in the update. Take care to preserve your media directory (media/), local configuration directory (app/conf/local/), any local print templates (app/printTemplates/) and your setup.php file.

If you are updating from a version prior to 1.7, you must recreate your existing setup.php as the format has changed. Rename the existing setup.php to setup.php-old and copy the version 1.7.17 setup.php template in setup.php-dist to setup.php. Edit this file with your database login information, system name and other basic settings. You can reuse the settings in your existing setup.php file as-is. Only the format of setup.php has changed. If you are updating from version 1.7.x you do not need to change your setup.php file.

Once the updated files are in place navigate in your web browser to the login screen. You will see this message:

Your database is out-of-date. Please install all schema migrations starting with migration #xxx. Click here to automatically apply the required updates.

The migration number may vary depending upon the version you're upgrading from. Click on the here link to begin the database update process.

Version 1.7 introduced zoomable page media for multipage documents such as PDFs, Microsoft Word or Powerpoint. Systems migrated from pre-1.7 versions of CollectiveAccess will not have these zoomable media versions available causing the built-in document viewer to fail. If your system includes multipage documents you should regenerate the media using the command-line caUtils utility in support/bin. The command to run (assuming your current working directory is support/) is:

bin/caUtils reprocess-media 

Be sure to run it as a user that has write permissions on all media. You do not need to reprocess media if you are updating from a 1.7.x system.

Installing development versions

The latest development version is always available in the develop branch (https://github.com/collectiveaccess/providence/tree/develop). Other feature-specific development versions are in branches prefixed with dev/. To install a development branch follow these steps:

  1. clone this repository into the location where you wish it to run using git clone https://github.com/collectiveaccess/providence.
  2. by default, the newly cloned repository will use the main branch, which contains code for the current release. Choose the develop branch by running from within the cloned repository git checkout develop.
  3. install the PHP package manager Composer if you do not already have it installed on your server.
  4. run composer from the root of the cloned repository with composer.phar install. This will download and install all required 3rd party software libraries.
  5. follow the release version installation instructions to complete the installation.

Useful Links

To report issues please use GitHub issues.

Other modules

Pawtucket2: https://github.com/collectiveaccess/pawtucket2 (The public access front-end application for Providence)


Download Details:

Author: Collectiveaccess
Source Code: https://github.com/collectiveaccess/providence 
License: GPL-3.0 license

#php #data #media #management #application 

Providence: Cataloguing and Data/media Management Application

Как разработать приложение, управляемое событиями, с ZIO Actors

Что такое ЗИО:

ZIO — это передовая платформа для создания облачных JVM-приложений. ZIO позволяет разработчикам создавать передовые приложения, которые являются чрезвычайно масштабируемыми, протестированными, надежными, отказоустойчивыми, ресурсобезопасными, эффективными и наблюдаемыми благодаря своему удобному, но мощному функциональному ядру.

Разница между Аккой и ZIO:

Akka и ZIO — это библиотеки в Scala для создания параллельных, масштабируемых и отказоустойчивых приложений.

Akka — это набор инструментов и среда выполнения для создания высокопараллельных, распределенных и отказоустойчивых систем. Он предоставляет акторов, которые представляют собой легкие единицы вычислений, которые взаимодействуют друг с другом путем обмена сообщениями. Akka также включает в себя инструменты для кластеризации, маршрутизации и сохраняемости, что делает его подходящим для создания реактивных приложений.

С другой стороны, ZIO (ZIO означает «ZIO Is Our») — чисто функциональная библиотека, обеспечивающая типобезопасный и компонуемый способ написания параллельного и асинхронного кода. Он предоставляет набор абстракций, таких как волокна, представляющие собой легкие потоки, которые можно комбинировать для создания сложных приложений, и эффекты, являющиеся неизменяемыми и составными описаниями вычислений с побочными эффектами. ZIO также включает мощную модель параллелизма и поддержку асинхронных операций ввода-вывода.

Почему ZIO вместо Akka:

ZIO и Akka — мощные платформы для создания параллельных и распределенных приложений на Scala. Однако есть несколько причин, по которым мы можем выбрать ZIO, а не Akka:

  1. Безопасность типов: ZIO — это чисто функциональная структура, использующая систему типов для обеспечения безопасного параллелизма и параллелизма. Это упрощает анализ нашего кода и поиск ошибок во время компиляции, а не во время выполнения.
  2. Легкий: ZIO — это легкая библиотека, которую легко изучить и использовать. Он имеет меньшую площадь поверхности API, чем Akka, и не требует столько стандартного кода.
  3. Производительность: ZIO оптимизирован для повышения производительности, с низкими затратами на управление потоками и минимальным переключением контекста. Он также обеспечивает детальный контроль над планированием и пулами потоков.
  4. Совместимость: ZIO полностью совместим с существующими библиотеками Scala и Java, что упрощает интеграцию в существующие проекты.

Актеры ЗИО:

В ZIO акторы реализованы как тип волокна, который представляет собой облегченный поток, который можно запускать одновременно с другими волокнами. Актер — это, по сути, волокно, которое может получать сообщения и реагировать на них.

Одним из способов создания актора в ZIO является использование метода actor.make, который принимает функцию, определяющую поведение актора. Функция принимает два параметра: первый — это начальное состояние актора, а второй — сообщение, которое получает актор.

Разработка системы бронирования билетов с использованием ZIO Actors –

Чтобы создать некоторую систему акторов в ZIO, нам нужно добавить некоторые зависимости, связанные с ZIO, в build.sbt. Проверьте ниже зависимость, которую мы использовали:

libraryDependencies ++= Seq(

  "dev.zio" %% "zio" % zioVersion,

  "dev.zio" %% "zio-streams" % zioVersion,

  "dev.zio" %% "zio-kafka" % "2.0.7",

  "dev.zio" %% "zio-json" % "0.4.2",

  "dev.zio" %% "zio-dynamodb" % "0.2.6",

  "dev.zio" %% "zio-test" % zioVersion,

  "dev.zio" %% "zio-actors" % "0.1.0",

  "dev.zio" %% "zio-http" % "0.0.4",

  "dev.zio" %% "zio-http-testkit" % "0.0.3",

  "io.d11" %% "zhttp" % "2.0.0-RC11"

)

Архитектура и блок-схема (система бронирования билетов):

Затем, переходя к кодовой базе, мы представили актера ZIO таким образом, что есть интеграция потребителя кафки и производителя кафки, который работает параллельно со всеми актерами.
Давайте определим главного актера для TicketBookingSystem.

  object TicketBookingSystem extends ZIOAppDefault {

  val actorSystem = ActorSystem("ticketBookingSystem")

  def run = {

    println("starting actor system ")

    for {

      ticketInfoConsumerProducer <- KafkaConsumer.consumerRun.fork

      _ <- ticketInfoConsumerProducer.join

    } yield ()

  }

}

Здесь мы инициализируем Kafka Consumer.

  def consumerRun: ZIO[Any, Throwable, Unit] = {
  
  println("starting KafkaConsumer ")

    val finalInfoStream =

      Consumer

        //create a kafka consumer here with respect to a particular topic

          for {

            theatreActor <- actorSystem.flatMap(x => 

x.make("ticketBookingflowActor", zio.actors.Supervisor.none, (), 

theatreActor))

            theatreActorData <- theatreActor ! ticketBooking

          } yield theatreActorData

        }

        .map(_.offset)

        .aggregateAsync(Consumer.offsetBatches)

        .mapZIO(_.commit)

        .drain

      finalInfoStream.runDrain.provide(KafkaProdConsLayer.consumerLayer ++ 

KafkaProdConsLayer.producer)

  }

В Kafka Consumer мы передаем информацию о бронировании актеру театра с помощью метода tell (!). Этот актер обработает данные и получит детали платежа, подтвердит билет и передаст его следующему актеру.

Реализация TheatreActor для TicketBookingSystem –

Это один из способов, которым мы можем создать систему акторов и различных других акторов и связать их с помощью метода ask или tell. В нашем коде мы добавили нашего первого актора в самого потребителя kafka, который срабатывает. И оттуда мы можем получить доступ к нашим следующим актерам.

object ThreatreActor {

  val theatreActor: Stateful[Any, Unit, ZioMessage] = new Stateful[Any, Unit, 

ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) => {

          println("ThreatreActor ................" + value)

          val ticketConfirm= Booking(value.uuid, value.bookingDate, 

value.theatreName, value.theatreLocation, value.seatNumbers, 

value.cardNumber, value.pin,

            value.cvv, value.otp, Some("Success"), Some("Confirmed"))

          for{

            paymentActor <- actorSystem.flatMap(x => 

x.make("paymentGatewayflowActor", zio.actors.Supervisor.none, (), 

paymentGatewayflowActor))

            paymentDetails <- paymentActor ? BookingMessage(value)

            bookingSyncActor <- actorSystem.flatMap(x => 

x.make("bookingSyncActor", zio.actors.Supervisor.none, (), bookingSyncActor))

            _ <- bookingSyncActor ! BookingMessage(ticketConfirm)

          }yield {

            println("Completed Theatre Actor")

            ((),())}

        }

        case _ => throw new Exception("Wrong value Input")

      }

  }

}

Этот код приведет нас к paymentActor, который написан следующим образом:

Реализация PaymentActor для TicketBookingSystem –

object PaymentGatewayActor {

   val paymentGatewayflowActor: Stateful[Any, Unit, ZioMessage] = new 

Stateful[Any, Unit, ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) =>

          println("paymentInfo ................" + value)

          val booking = Booking(value.uuid, value.bookingDate, 

value.theatreName, value.theatreLocation, value.seatNumbers, 

value.cardNumber, value.pin,

            value.cvv, value.otp, Some("Success"), Some(""))

          for {

            bookingSyncActor <- actorSystem.flatMap(x => 

x.make("bookingSyncActor", zio.actors.Supervisor.none, (), bookingSyncActor))

            //ZIO.succeed(booking)

          }yield{

            println("paymentInfo return................" + booking)

            ( BookingMessage(booking), ())

          }

        case _ => throw new Exception("Wrong value Input")

      }

  }

}

Тот же theatreActor приведет нас к bookingSyncActor, который написан так:

Реализация bookingSyncActor для TicketBookingSystem –

  val bookingSyncActor: Stateful[Any, Unit, ZioMessage] = new Stateful[Any, 

Unit, ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) =>

          println("bookingSyncActor ................" + value)

          for {

            _ <- KafkaProducer.producerRun(value)

            _ <- f1(value).provide(

              netty.NettyHttpClient.default,

              config.AwsConfig.default,

              dynamodb.DynamoDb.live,

              DynamoDBExecutor.live

            )

          }yield((),())

      }

  } // plus some other computations.

Эти разные акторы будут собирать некоторую информацию из класса базового случая и давать некоторую релевантную информацию об отдельных актерах.

Отправка ответа обратно клиенту –

Для ответного сообщения производитель создает данные по другой теме (ответное сообщение).

          for {
 
           _ <- KafkaProducer.producerRun(value)

           //logic for db

          } yield((),())

Тестовый пример системы бронирования билетов:

Конечно, давайте проверим, как тестировать наших актеров с помощью модульного теста.

Для приведенного выше кода theatreActor мы создали theatreActorSpec, который можно записать в этом простом формате. Мы можем проверить правильность введенных данных в актере или нет.

object ThreatreActorSpec extends ZIOAppDefault{

  val data: Booking = booking.handler.actor.JsonSampleData.booking

  override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] =

    for {

      system <- ActorSystem("ticketBookingSystem")

      actor <- system.make("ticketBookingflowActor", Supervisor.none, (), 

theatreActor)

      result <- actor !  BookingMessage(data)

    }

    yield result

}

Чтобы запустить эту службу -

  • Настройка брокера
  • Запустить службу субъекта
  • Продюсер запуска

Заключение :

В заключение, ZIO Actors — это мощная и эффективная библиотека для создания параллельных и распределенных систем на Scala. Он обеспечивает упрощенный и типобезопасный подход к параллелизму, позволяя разработчикам легко моделировать свои потребности в параллелизме для предметной области без сложностей традиционных систем акторов. Благодаря расширенным функциям, таким как прозрачность местоположения, перехват сообщений и контроль, ZIO Actors упрощает разработку и развертывание масштабируемых и отказоустойчивых распределенных приложений.

Здесь мы создали различных актеров, таких как актер театра, актер платежа и актер синхронизации бронирования, которые работают в соответствии с их логикой. Кроме того, мы попытались реализовать акторы ZIO с помощью ZIO kafka, и это очень хороший пример такой простой интеграции.

Кроме того, его интеграция с экосистемой ZIO обеспечивает бесшовную композицию с другими функциональными библиотеками, предоставляя разработчикам мощный и целостный набор инструментов для создания надежного и удобного в сопровождении программного обеспечения. Дополнительные блоги см. здесь . Дополнительные блоги ZIO см. здесь

Оригинальный источник статьи:   https://blog.knoldus.com/

#scala #event #application #actors 

Как разработать приложение, управляемое событиями, с ZIO Actors
田辺  桃子

田辺 桃子

1678959749

打开选项 使用 ZIO Actors 开发事件驱动的应用程序

什么是 ZIO:

ZIO 是用于创建云原生 JVM 应用程序的尖端框架。ZIO 使开发人员能够构建最佳实践应用程序,这些应用程序具有极高的可扩展性、经过测试、健壮、有弹性、资源安全、高效且可观察,这要归功于其用户友好但功能强大的核心。

Akka 和 ZIO 的区别:

Akka 和 ZIO 都是 Scala 中用于构建并发、可扩展和容错应用程序的库。

Akka 是用于构建高度并发、分布式和容错系统的工具包和运行时。它提供了参与者,这是轻量级的计算单元,通过交换消息相互通信。Akka 还包括用于集群、路由和持久化的工具,使其非常适合构建反应式应用程序。

另一方面,ZIO(ZIO 代表“ZIO Is Our”)是一个纯函数库,它提供了一种类型安全且可组合的方式来编写并发和异步代码。它提供了一组抽象,例如纤程,它们是轻量级的线程,可以组合起来创建复杂的应用程序,以及效果,它们是对副作用计算的不可变和可组合的描述。ZIO 还包括强大的并发模型和对异步 IO 操作的支持。

为什么 ZIO 而不是 Akka:

ZIO 和 Akka 都是在 Scala 中构建并发和分布式应用程序的强大框架。但是,有一些我们可能会选择 ZIO 而不是 Akka 的原因:

  1. 类型安全:ZIO 是一个纯功能框架,它使用类型系统来强制执行安全的并发性和并行性。这使得在编译时而不是运行时更容易推理我们的代码并捕获错误。
  2. 轻量级:ZIO 是一个轻量级的库,易于学习和使用。它具有比 Akka 更小的 API 表面积,并且不需要那么多的样板代码。
  3. 性能:ZIO 针对性能进行了高度优化,线程管理开销较低,上下文切换最少。它还提供对调度和线程池的细粒度控制。
  4. 兼容性:ZIO 与现有的 Scala 和 Java 库完全兼容,可以轻松集成到现有项目中。

齐奥演员:

在 ZIO 中,actor 被实现为一种 fiber,它是一种轻量级线程,可以与其他 fiber 并发运行。Actor 本质上是一根可以接收消息并对其做出反应的纤维。

要在 ZIO 中创建一个 actor,一种方法是我们可以使用 方法actor.make,它采用一个定义 actor 行为的函数。该函数有两个参数:第一个是actor的初始状态,第二个是actor接收到的消息。

使用 ZIO Actors 开发票务预订系统 –

要在 ZIO 中创建一些 actor 系统,我们需要在 build.sbt 中添加一些 ZIO 相关的依赖项。在下面检查我们使用的依赖项-

libraryDependencies ++= Seq(

  "dev.zio" %% "zio" % zioVersion,

  "dev.zio" %% "zio-streams" % zioVersion,

  "dev.zio" %% "zio-kafka" % "2.0.7",

  "dev.zio" %% "zio-json" % "0.4.2",

  "dev.zio" %% "zio-dynamodb" % "0.2.6",

  "dev.zio" %% "zio-test" % zioVersion,

  "dev.zio" %% "zio-actors" % "0.1.0",

  "dev.zio" %% "zio-http" % "0.0.4",

  "dev.zio" %% "zio-http-testkit" % "0.0.3",

  "io.d11" %% "zhttp" % "2.0.0-RC11"

)

架构和流程图(订票系统):

然后转向代码库,我们以这样一种方式引入了 ZIO actor,即集成了 kafka consumer,kafka producer,它与所有 actors 并行工作。
让我们为 TicketBookingSystem 定义一个主要参与者。

  object TicketBookingSystem extends ZIOAppDefault {

  val actorSystem = ActorSystem("ticketBookingSystem")

  def run = {

    println("starting actor system ")

    for {

      ticketInfoConsumerProducer <- KafkaConsumer.consumerRun.fork

      _ <- ticketInfoConsumerProducer.join

    } yield ()

  }

}

在这里,我们正在初始化 Kafka Consumer。

  def consumerRun: ZIO[Any, Throwable, Unit] = {
  
  println("starting KafkaConsumer ")

    val finalInfoStream =

      Consumer

        //create a kafka consumer here with respect to a particular topic

          for {

            theatreActor <- actorSystem.flatMap(x => 

x.make("ticketBookingflowActor", zio.actors.Supervisor.none, (), 

theatreActor))

            theatreActorData <- theatreActor ! ticketBooking

          } yield theatreActorData

        }

        .map(_.offset)

        .aggregateAsync(Consumer.offsetBatches)

        .mapZIO(_.commit)

        .drain

      finalInfoStream.runDrain.provide(KafkaProdConsLayer.consumerLayer ++ 

KafkaProdConsLayer.producer)

  }

在 Kafka Consumer 中,我们使用 tell 方法 (!) 将预订信息传递给剧院演员。该演员将处理数据并获取付款详细信息并确认票证并传递给下一个演员。

TicketBookingSystem 的 TheatreActor 实现 –

这是我们可以创建演员系统和各种其他演员并可以使用询问或告诉方法链接它们的方式之一。在我们的代码中,我们在 kafka 消费者本身中添加了我们的第一个演员,它正在被触发。从那里,我们可以访问我们的下一个演员。

object ThreatreActor {

  val theatreActor: Stateful[Any, Unit, ZioMessage] = new Stateful[Any, Unit, 

ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) => {

          println("ThreatreActor ................" + value)

          val ticketConfirm= Booking(value.uuid, value.bookingDate, 

value.theatreName, value.theatreLocation, value.seatNumbers, 

value.cardNumber, value.pin,

            value.cvv, value.otp, Some("Success"), Some("Confirmed"))

          for{

            paymentActor <- actorSystem.flatMap(x => 

x.make("paymentGatewayflowActor", zio.actors.Supervisor.none, (), 

paymentGatewayflowActor))

            paymentDetails <- paymentActor ? BookingMessage(value)

            bookingSyncActor <- actorSystem.flatMap(x => 

x.make("bookingSyncActor", zio.actors.Supervisor.none, (), bookingSyncActor))

            _ <- bookingSyncActor ! BookingMessage(ticketConfirm)

          }yield {

            println("Completed Theatre Actor")

            ((),())}

        }

        case _ => throw new Exception("Wrong value Input")

      }

  }

}

此代码将带我们到 paymentActor,其编写如下 -

TicketBookingSystem 的 PaymentActor 实现 –

object PaymentGatewayActor {

   val paymentGatewayflowActor: Stateful[Any, Unit, ZioMessage] = new 

Stateful[Any, Unit, ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) =>

          println("paymentInfo ................" + value)

          val booking = Booking(value.uuid, value.bookingDate, 

value.theatreName, value.theatreLocation, value.seatNumbers, 

value.cardNumber, value.pin,

            value.cvv, value.otp, Some("Success"), Some(""))

          for {

            bookingSyncActor <- actorSystem.flatMap(x => 

x.make("bookingSyncActor", zio.actors.Supervisor.none, (), bookingSyncActor))

            //ZIO.succeed(booking)

          }yield{

            println("paymentInfo return................" + booking)

            ( BookingMessage(booking), ())

          }

        case _ => throw new Exception("Wrong value Input")

      }

  }

}

相同的 theatreActor 将带我们到 bookingSyncActor,如下所示 -

TicketBookingSystem 的 bookingSyncActor 实现 –

  val bookingSyncActor: Stateful[Any, Unit, ZioMessage] = new Stateful[Any, 

Unit, ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) =>

          println("bookingSyncActor ................" + value)

          for {

            _ <- KafkaProducer.producerRun(value)

            _ <- f1(value).provide(

              netty.NettyHttpClient.default,

              config.AwsConfig.default,

              dynamodb.DynamoDb.live,

              DynamoDBExecutor.live

            )

          }yield((),())

      }

  } // plus some other computations.

这些不同的参与者将从基本案例类中收集一些信息,并将提供一些关于各个参与者的相关信息。

将响应发送回客户端 –

对于回复消息,生产者正在生成关于不同主题的数据(回复消息)

          for {
 
           _ <- KafkaProducer.producerRun(value)

           //logic for db

          } yield((),())

订票系统测试用例:

当然,让我们检查一下如何使用单元测试来测试我们的演员。

对于上面的 theatreActor 代码,我们创建了可以用这种简单格式编写的 theatreActorSpec。我们可以检查输入的数据在演员中是否正确。

object ThreatreActorSpec extends ZIOAppDefault{

  val data: Booking = booking.handler.actor.JsonSampleData.booking

  override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] =

    for {

      system <- ActorSystem("ticketBookingSystem")

      actor <- system.make("ticketBookingflowActor", Supervisor.none, (), 

theatreActor)

      result <- actor !  BookingMessage(data)

    }

    yield result

}

要运行此服务 –

  • 设置经纪人
  • 运行 Actor 服务
  • 运行制作人

结论 :

总之,ZIO Actors 是一个强大而高效的库,用于在 Scala 中构建并发和分布式系统。它提供了一种轻量级和类型安全的并发方法,允许开发人员轻松地模拟他们特定领域的并发需求,而无需传统参与者系统的复杂性。ZIO Actors 凭借其位置透明、消息拦截和监督等高级功能,简化了高度可扩展和容错分布式应用程序的开发和部署。

在这里,我们创建了各种 actor,如剧院 actor、支付 actor 和预订同步 actor,它们按照它们的逻辑工作。此外,我们尝试使用 ZIO kafka 实现 ZIO actor,这是这种简单集成的一个很好的例子。

此外,它与 ZIO 生态系统的集成允许与其他功能库无缝组合,为开发人员提供强大且内聚的工具包,用于构建健壮且可维护的软件。更多博客请参考这里。更多 ZIO 博客,请参考这里

文章原文出处:https:   //blog.knoldus.com/

#scala #event #application #actors 

 打开选项 使用 ZIO Actors 开发事件驱动的应用程序

Работа по разработке облачных приложений в облачной инженерии

Мир технологий постоянно меняется, и с появлением облачных вычислений предприятия смогли ускорить свой рост и деятельность, используя преимущества облака. Разработка облачных приложений — это быстро развивающаяся область, которая меняет способы работы, совместной работы и масштабирования бизнеса.

Разработка облачных приложений позволяет предприятиям разрабатывать и развертывать программные приложения в облаке, где пользователи могут получить к ним доступ из любого места и в любое время. Это коренным образом изменило подход компаний к разработке программного обеспечения, поскольку оно предлагает экономичное, масштабируемое и гибкое решение для предоставления реальных бизнес-решений с гибким подходом к развертыванию.

В этом блоге мы рассмотрим, как предприятия могут использовать самые современные облачные технологии и методы проектирования облачных вычислений для разработки и развертывания облачных приложений, предоставляющих реальные бизнес-решения.

Гибкий подход к развертыванию

Гибкая разработка — это методология разработки программного обеспечения, которая делает упор на итеративную и поэтапную разработку программного обеспечения. Это позволяет разработчикам адаптироваться к изменяющимся требованиям и отзывам клиентов, что приводит к более быстрым и эффективным циклам разработки.

Гибкая разработка также способствует сотрудничеству между командами разработчиков, заинтересованными сторонами и клиентами. Это позволяет предприятиям разрабатывать программные приложения, отвечающие потребностям их клиентов, и предоставлять реальные бизнес-решения.

Когда дело доходит до разработки облачных приложений , гибкий подход к развертыванию имеет решающее значение. Облачные вычисления предоставляют предприятиям гибкость для быстрого и эффективного развертывания и масштабирования приложений. Гибкий подход к развертыванию позволяет компаниям воспользоваться преимуществами этой гибкости, разрабатывая и развертывая программные приложения небольшими итеративными циклами.

Этот подход позволяет предприятиям тестировать и совершенствовать свои приложения по мере их использования, гарантируя, что они удовлетворяют потребности своих клиентов и предоставляют реальные бизнес-решения. Agile-разработка также позволяет компаниям быстро реагировать на меняющиеся требования, что очень важно в современной быстро меняющейся бизнес-среде.

Современные облачные технологии

Разработка облачных приложений опирается на современные облачные технологии для предоставления реальных бизнес-решений. Эти технологии включают облачные платформы, базы данных и языки программирования.

Облачные платформы, такие как Amazon Web Services (AWS), Microsoft Azure и Google Cloud Platform, предоставляют предприятиям инфраструктуру и услуги, необходимые для быстрой и эффективной разработки и развертывания облачных приложений. Эти платформы предлагают ряд услуг, включая вычисления, хранение и работу в сети, которые предприятия могут использовать для создания и развертывания своих приложений.

Базы данных также являются важным компонентом разработки облачных приложений. Облачные базы данных, такие как Amazon Aurora, Google Cloud SQL и Microsoft Azure SQL Database, предоставляют компаниям возможность хранить и управлять большими объемами данных в облаке. Это позволяет предприятиям разрабатывать приложения, способные быстро и эффективно анализировать и обрабатывать большие объемы данных.

Языки программирования, такие как Java, Python и Node.js, также необходимы для разработки облачных приложений. Эти языки позволяют разработчикам писать код, который может работать в облаке, позволяя компаниям разрабатывать и развертывать приложения, которые можно быстро и эффективно масштабировать.

Практики облачной инженерии

Облачная инженерия — это практика проектирования, создания и обслуживания облачных систем и приложений. Он включает в себя ряд практик, включая архитектуру, безопасность и операции.

Когда дело доходит до разработки облачных приложений, методы облачной инженерии имеют решающее значение. Они гарантируют, что предприятия разрабатывают и развертывают безопасные, масштабируемые и надежные приложения.

Облачная архитектура — важнейший компонент облачной инженерии. Он включает в себя разработку систем и приложений, которые могут работать в облаке, используя преимущества гибкости и масштабируемости, которые обеспечивают облачные вычисления. Облачная архитектура также гарантирует, что приложения являются отказоустойчивыми, отказоустойчивыми и могут быстро восстанавливаться в случае сбоя.

Безопасность также является важным компонентом облачной инженерии. Облачные приложения должны разрабатываться и развертываться с учетом требований безопасности, поскольку они доступны из любого места и в любое время. Это требует ряда методов обеспечения безопасности, включая шифрование, контроль доступа и сетевую безопасность.

Операции также важны для облачной инженерии. Облачные приложения должны контролироваться и управляться, чтобы гарантировать, что они работают должным образом. Для этого требуется ряд операционных методов, включая мониторинг, регистрацию и автоматизацию.

Оригинальный источник статьи:   https://blog.knoldus.com/

#cloud #application #development 

Работа по разработке облачных приложений в облачной инженерии
Nat  Grady

Nat Grady

1678955951

Develop Event Driven Application using ZIO Actors

What is ZIO :

ZIO is a cutting-edge framework for creating cloud-native JVM applications. ZIO enables developers to construct best-practice applications that are extremely scalable, tested, robust, resilient, resource-safe, efficient, and observable thanks to its user-friendly yet strong functional core.

Difference between Akka and ZIO :

Akka and ZIO are both the libraries in Scala for building concurrent, scalable, and fault-tolerant applications.

Akka is a toolkit and runtime for building highly concurrent, distributed, and fault-tolerant systems. It provides actors, which are lightweight units of computation that communicate with each other by exchanging messages. Akka also includes tools for clustering, routing, and persistence, making it well-suited for building reactive applications.

On the other hand, ZIO (ZIO stands for “ZIO Is Our”) is a purely functional library that provides a type-safe and composable way to write concurrent and asynchronous code. It provides a set of abstractions such as fibers, which are lightweight threads that can be composed to create complex applications, and effects, which are immutable and composable descriptions of side-effecting computations. ZIO also includes a powerful concurrency model and support for asynchronous IO operations.

Why ZIO over Akka :

ZIO and Akka are both powerful frameworks for building concurrent and distributed applications in Scala. However, there are some reasons why we might choose ZIO over Akka:

  1. Type safety: ZIO is a purely functional framework that uses the type system to enforce safe concurrency and parallelism. This makes it easier to reason about our code and catch errors at compile time rather than runtime.
  2. Lightweight: ZIO is a lightweight library that is easy to learn and use. It has a smaller API surface area than Akka and doesn’t require as much boilerplate code.
  3. Performance: ZIO is highly optimized for performance, with a low overhead for thread management and minimal context switching. It also provides fine-grained control over scheduling and thread pools.
  4. Compatibility: ZIO is fully compatible with existing Scala and Java libraries, making it easy to integrate into existing projects.

ZIO Actors :

In ZIO, actors are implemented as a type of fiber, which is a lightweight thread that can be run concurrently with other fibers. An actor is essentially a fiber that can receive messages and react to them.

To create an actor in ZIO, one of the way is we can use the actor.make method, which takes a function that defines the behavior of the actor. The function takes two parameters: the first one is the initial state of the actor, and the second one is the message that the actor receives.

Developing a Ticket Booking System using ZIO Actors –

To create some actor system in ZIO, we need to add some ZIO related dependencies in build.sbt. Check below for the dependency which we have used-

libraryDependencies ++= Seq(

  "dev.zio" %% "zio" % zioVersion,

  "dev.zio" %% "zio-streams" % zioVersion,

  "dev.zio" %% "zio-kafka" % "2.0.7",

  "dev.zio" %% "zio-json" % "0.4.2",

  "dev.zio" %% "zio-dynamodb" % "0.2.6",

  "dev.zio" %% "zio-test" % zioVersion,

  "dev.zio" %% "zio-actors" % "0.1.0",

  "dev.zio" %% "zio-http" % "0.0.4",

  "dev.zio" %% "zio-http-testkit" % "0.0.3",

  "io.d11" %% "zhttp" % "2.0.0-RC11"

)

Architecture and Flow Diagram (Ticket Booking System) :

Then moving forward to codebase, we have introduced ZIO actor in such a way that there is an integration of kafka consumer, kafka producer which is is working parallely with all the actors.
Lets define a main actor for the TicketBookingSystem.

  object TicketBookingSystem extends ZIOAppDefault {

  val actorSystem = ActorSystem("ticketBookingSystem")

  def run = {

    println("starting actor system ")

    for {

      ticketInfoConsumerProducer <- KafkaConsumer.consumerRun.fork

      _ <- ticketInfoConsumerProducer.join

    } yield ()

  }

}

Here, we are initializing Kafka Consumer.

  def consumerRun: ZIO[Any, Throwable, Unit] = {
  
  println("starting KafkaConsumer ")

    val finalInfoStream =

      Consumer

        //create a kafka consumer here with respect to a particular topic

          for {

            theatreActor <- actorSystem.flatMap(x => 

x.make("ticketBookingflowActor", zio.actors.Supervisor.none, (), 

theatreActor))

            theatreActorData <- theatreActor ! ticketBooking

          } yield theatreActorData

        }

        .map(_.offset)

        .aggregateAsync(Consumer.offsetBatches)

        .mapZIO(_.commit)

        .drain

      finalInfoStream.runDrain.provide(KafkaProdConsLayer.consumerLayer ++ 

KafkaProdConsLayer.producer)

  }

In Kafka Consumer, we are passing booking information to the theatre actor by using tell method (!). This actor will process the data and fetch the payment details and confirm ticket and pass on to next actor.

TheatreActor implementation for TicketBookingSystem –

This is one of the way we can create actor system and various other actors and can link them using ask or tell method.In our code, we have added our first actor in kafka consumer itself, which is getting triggered. And from there, we can get access to our next actors.

object ThreatreActor {

  val theatreActor: Stateful[Any, Unit, ZioMessage] = new Stateful[Any, Unit, 

ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) => {

          println("ThreatreActor ................" + value)

          val ticketConfirm= Booking(value.uuid, value.bookingDate, 

value.theatreName, value.theatreLocation, value.seatNumbers, 

value.cardNumber, value.pin,

            value.cvv, value.otp, Some("Success"), Some("Confirmed"))

          for{

            paymentActor <- actorSystem.flatMap(x => 

x.make("paymentGatewayflowActor", zio.actors.Supervisor.none, (), 

paymentGatewayflowActor))

            paymentDetails <- paymentActor ? BookingMessage(value)

            bookingSyncActor <- actorSystem.flatMap(x => 

x.make("bookingSyncActor", zio.actors.Supervisor.none, (), bookingSyncActor))

            _ <- bookingSyncActor ! BookingMessage(ticketConfirm)

          }yield {

            println("Completed Theatre Actor")

            ((),())}

        }

        case _ => throw new Exception("Wrong value Input")

      }

  }

}

This code will take us to paymentActor which is written as below –

PaymentActor implementation for TicketBookingSystem –

object PaymentGatewayActor {

   val paymentGatewayflowActor: Stateful[Any, Unit, ZioMessage] = new 

Stateful[Any, Unit, ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) =>

          println("paymentInfo ................" + value)

          val booking = Booking(value.uuid, value.bookingDate, 

value.theatreName, value.theatreLocation, value.seatNumbers, 

value.cardNumber, value.pin,

            value.cvv, value.otp, Some("Success"), Some(""))

          for {

            bookingSyncActor <- actorSystem.flatMap(x => 

x.make("bookingSyncActor", zio.actors.Supervisor.none, (), bookingSyncActor))

            //ZIO.succeed(booking)

          }yield{

            println("paymentInfo return................" + booking)

            ( BookingMessage(booking), ())

          }

        case _ => throw new Exception("Wrong value Input")

      }

  }

}

The same theatreActor will take us to bookingSyncActor which is written as below –

bookingSyncActor implementation for TicketBookingSystem –

  val bookingSyncActor: Stateful[Any, Unit, ZioMessage] = new Stateful[Any, 

Unit, ZioMessage] {

    override def receive[A](state: Unit, msg: ZioMessage[A], context: 

Context): Task[(Unit, A)] =

      msg match {

        case BookingMessage(value) =>

          println("bookingSyncActor ................" + value)

          for {

            _ <- KafkaProducer.producerRun(value)

            _ <- f1(value).provide(

              netty.NettyHttpClient.default,

              config.AwsConfig.default,

              dynamodb.DynamoDb.live,

              DynamoDBExecutor.live

            )

          }yield((),())

      }

  } // plus some other computations.

These different actors will collect some info from the base case class and will give some relevant info regarding the individual actors.

Sending a response back to client –

For reply message, the producer is producing the data on a different topic (reply message)

          for {
 
           _ <- KafkaProducer.producerRun(value)

           //logic for db

          } yield((),())

Ticket Booking System Test Case :

Sure, Lets check how to test our actors using unit test.

For the above theatreActor code, we have created theatreActorSpec which can be written in this simple format. We can check if the data entered is getting correct in the actor or not.

object ThreatreActorSpec extends ZIOAppDefault{

  val data: Booking = booking.handler.actor.JsonSampleData.booking

  override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] =

    for {

      system <- ActorSystem("ticketBookingSystem")

      actor <- system.make("ticketBookingflowActor", Supervisor.none, (), 

theatreActor)

      result <- actor !  BookingMessage(data)

    }

    yield result

}

To run this service –

  • Setup broker
  • Run Actor Service
  • Run Producer

Conclusion :

In conclusion, ZIO Actors is a powerful and efficient library for building concurrent and distributed systems in Scala. It provides a lightweight and type-safe approach to concurrency, allowing developers to easily model their domain-specific concurrency needs without the complexities of traditional actor systems. With its advanced features such as location transparency, message interception, and supervision, ZIO Actors simplifies the development and deployment of highly scalable and fault-tolerant distributed applications.

Here, we created various actors such as theatre actor, payment actor and booking sync actor which are working as per their logic. Also, we tried to implement ZIO actors with ZIO kafka and this is a very good example of this simple integration.

Additionally, its integration with the ZIO ecosystem allows for seamless composition with other functional libraries, providing developers with a powerful and cohesive toolkit for building robust and maintainable software. For more blogs, please refer here . For more ZIO blogs, refer here

Original article source at:  https://blog.knoldus.com/

#scala #event #application #actors 

Develop Event Driven Application using ZIO Actors
田辺  桃子

田辺 桃子

1678955470

云工程中的云应用开发工程

技术世界瞬息万变,随着云计算的出现,企业已经能够利用云的优势加速其增长和运营。云应用程序开发是一个快速发展的领域,它正在改变企业运营、协作和扩展运营的方式。

云应用程序开发使企业能够在云中开发和部署软件应用程序,用户可以随时随地访问它们。这彻底改变了企业进行软件开发的方式,因为它提供了一种经济高效、可扩展且灵活的解决方案,可通过敏捷部署方法交付有形的业务解决方案。

在此博客中,我们将探讨企业如何利用最先进的云技术和云工程实践来开发和部署提供切实业务解决方案的云应用程序。

敏捷部署方法

敏捷开发是一种软件开发方法论,强调软件的迭代和增量开发。它允许开发人员适应不断变化的需求和来自客户的反馈,从而导致更快、更有效的开发周期。

敏捷开发还促进了开发团队、利益相关者和客户之间的协作。这使企业能够开发满足其客户需求的软件应用程序并提供有形的业务解决方案。

在云应用程序开发方面,敏捷部署方法至关重要。云计算为企业提供了快速高效地部署和扩展应用程序的灵活性。敏捷部署方法使企业能够通过在小的迭代周期中开发和部署软件应用程序来利用这种灵活性。

这种方法允许企业在运行过程中测试和改进他们的应用程序,确保他们满足客户的需求并提供切实的业务解决方案。敏捷开发还使企业能够快速响应不断变化的需求,这在当今快节奏的商业环境中至关重要。

最先进的云技术

云应用程序开发依赖于最先进的云技术来提供有形的业务解决方案。这些技术包括云平台、数据库和编程语言。

Amazon Web Services (AWS)、Microsoft Azure 和 Google Cloud Platform 等云平台为企业提供了快速高效地开发和部署云应用程序所需的基础设施和服务。这些平台提供一系列服务,包括计算、存储和网络,企业可以使用这些服务来构建和部署他们的应用程序。

数据库也是云应用程序开发的重要组成部分。Amazon Aurora、Google Cloud SQL 和 Microsoft Azure SQL 数据库等云数据库为企业提供了在云中存储和管理大量数据的能力。这使企业能够开发能够快速高效地分析和处理大量数据的应用程序。

Java、Python 和 Node.js 等编程语言对于云应用程序开发也是必不可少的。这些语言使开发人员能够编写可在云中运行的代码,使企业能够开发和部署可快速高效扩展的应用程序。

云工程实践

云工程是设计、构建和维护基于云的系统和应用程序的实践。它涉及一系列实践,包括架构、安全和操作。

在云应用程序开发方面,云工程实践至关重要。他们确保企业开发和部署安全、可扩展且可靠的应用程序。

云架构是云工程的重要组成部分。它涉及设计可以在云中运行的系统和应用程序,利用云计算提供的灵活性和可扩展性。云架构还确保应用程序具有弹性、容错能力,并且可以在发生故障时快速恢复。

安全性也是云工程的重要组成部分。云应用程序的设计和部署必须牢记安全性,因为它们可以随时随地访问。这需要一系列安全实践,包括加密、访问控制和网络安全。

运维对于云工程来说也是必不可少的。必须监控和管理云应用程序以确保它们按预期运行。这需要一系列操作实践,包括监控、日志记录和自动化

文章原文出处:https:   //blog.knoldus.com/

#cloud #application #development 

云工程中的云应用开发工程
Nat  Grady

Nat Grady

1678951620

Cloud Application Development Works in Cloud Engineering

The world of technology is ever-changing, and with the advent of cloud computing, businesses have been able to accelerate their growth and operations by utilizing the benefits of the cloud. Cloud application development is a rapidly growing field that is transforming the way businesses operate, collaborate, and scale their operations.

Cloud application development enables businesses to develop and deploy software applications in the cloud, where they can be accessed by users from anywhere and at any time. This has revolutionized the way businesses approach software development, as it offers a cost-effective, scalable, and flexible solution for delivering tangible business solutions with an agile deployment approach.

In this blog, we will explore how businesses can leverage state-of-the-art cloud technologies and cloud engineering practices to develop and deploy cloud applications that deliver tangible business solutions.

Agile Deployment Approach

Agile development is a software development methodology that emphasizes the iterative and incremental development of software. It allows developers to adapt to changing requirements and feedback from customers, which leads to faster and more effective development cycles.

Agile development also promotes collaboration between development teams, stakeholders, and customers. This enables businesses to develop software applications that meet the needs of their customers and deliver tangible business solutions.

When it comes to cloud application development, an agile deployment approach is crucial. Cloud computing provides businesses with the flexibility to deploy and scale applications quickly and efficiently. An agile deployment approach enables businesses to take advantage of this flexibility by developing and deploying software applications in small, iterative cycles.

This approach allows businesses to test and refine their applications as they go, ensuring that they meet the needs of their customers and deliver tangible business solutions. Agile development also enables businesses to respond quickly to changing requirements, which is essential in today’s fast-paced business environment.

State-of-the-Art Cloud Technologies

Cloud application development relies on state-of-the-art cloud technologies to deliver tangible business solutions. These technologies include cloud platforms, databases, and programming languages.

Cloud platforms like Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform provide businesses with the infrastructure and services they need to develop and deploy cloud applications quickly and efficiently. These platforms offer a range of services, including computing, storage, and networking, which businesses can use to build and deploy their applications.

Databases are also a critical component of cloud application development. Cloud databases like Amazon Aurora, Google Cloud SQL, and Microsoft Azure SQL Database provide businesses with the ability to store and manage large amounts of data in the cloud. This enables businesses to develop applications that can analyze and process large amounts of data quickly and efficiently.

Programming languages like Java, Python, and Node.js are also essential for cloud application development. These languages enable developers to write code that can run in the cloud, enabling businesses to develop and deploy applications that can scale quickly and efficiently.

Cloud Engineering Practices

Cloud engineering is the practice of designing, building, and maintaining cloud-based systems and applications. It involves a range of practices, including architecture, security, and operations.

When it comes to cloud application development, cloud engineering practices are crucial. They ensure that businesses develop and deploy applications that are secure, scalable, and reliable.

Cloud architecture is a critical component of cloud engineering. It involves designing systems and applications that can run in the cloud, taking advantage of the flexibility and scalability that cloud computing provides. Cloud architecture also ensures that applications are resilient, fault-tolerant, and can recover quickly in the event of a failure.

Security is also a critical component of cloud engineering. Cloud applications must be designed and deployed with security in mind, as they are accessible from anywhere and at any time. This requires a range of security practices, including encryption, access control, and network security.

Operations are also essential for cloud engineering. Cloud applications must be monitored and managed to ensure that they are performing as expected. This requires a range of operational practices, including monitoring, logging, and automation

Original article source at:  https://blog.knoldus.com/

#cloud #application #development 

Cloud Application Development Works in Cloud Engineering
Monty  Boehm

Monty Boehm

1678767540

React-artboard: A Realistic Paint Component

React-artboard

A freeform sketching component for React. Try the demo

shading

react-artboard includes an Artboard component and several tools, including a realistic paintbrush, a marker pen and airbrush, as well as the abstract shading tool. Tools are implemented as custom hooks, so you can add your own brushes and other tools.

Installation

npm install react-artboard

Usage

For a full usage example, see this file. The simplest usage of the component is like this:

import React from "react";
import { useBrush, Artboard } from "react-artboard";
export function App() {
  const brush = useBrush({ color: "#663399", strokeWidth: 40 });

  return <Artboard tool={brush} style={{ width: 800, height: 600 }} />;
}

You probably want to allow users to change the colors and size of the brush. Here is an example that uses native color and range inputs:

import React, { useState } from "react";
import { useBrush, Artboard } from "react-artboard";
export function App() {
  const [color, setColor] = useState("#993366");
  const [strokeWidth, setStrokeWidth] = useState(40);
  const brush = useBrush({ color, strokeWidth });

  return (
    <main>
      <div>
        <input
          type="color"
          value={color}
          onInput={(evt) => setColor(evt.currentTarget.value)}
        />
        <input
          type="range"
          min={5}
          max={50}
          value={strokeWidth}
          onInput={(evt) => setStrokeWidth(parseInt(evt.currentTarget.value))}
        />
      </div>
      <Artboard tool={brush} style={{ width: 800, height: 600 }} />
    </main>
  );
}

You could use a custom component instead of these inputs if you want more control over them, as long as they return a number for the brush size and a string for the color.

If you want to export your creations or clear the canvas, you can use the ref like this:

import React, { useState } from "react";
import { useBrush, Artboard } from "react-artboard";
export function App() {
  const [color, setColor] = useState("#993366");
  const [strokeWidth, setStrokeWidth] = useState(40);
  const brush = useBrush({ color, strokeWidth });

  const [artboardRef, setArtboardRef] = useState();

  return (
    <main>
      <div>
        <button onClick={() => artboardRef?.download()}>Download</button>
        <button onClick={() => artboardRef?.clear()}>Clear</button>
        <input
          type="color"
          value={color}
          onInput={(evt) => setColor(evt.currentTarget.value)}
        />
        <input
          type="range"
          min={5}
          max={50}
          value={strokeWidth}
          onInput={(evt) => setStrokeWidth(parseInt(evt.currentTarget.value))}
        />
      </div>
      <Artboard tool={brush} style={{ width: 800, height: 600 }} />
    </main>
  );
}

API

Artboard

Props

tool

This is the tool returned by the useBrush() hook. You can also implement your own tools and pass them in here.

ref

This accepts a callback that will be passed a ref that you can use to make the following calls:

download: (filename: string, type: string) => void

Downloads the canvas as an image. You can pass in a filename (default "image.png"), and a mimetype (default "image/png"). If you pass an unsupported type it will fallback to PNG.

getImageAsDataUri: (type: string) => string | undefined

Returns the image as a data URI, which can be displayed in an <img> tag for example.

clear: () => void

Clears the image

context: CanvasRenderingContext2D | null | undefined

Canvas rendering context

onStartStroke: (point: Point) => void

Callback at the start of a stroke

onContinueStroke: (point: Point) => void

Callback at the continuing of a stroke

onEndStroke: () => void

Callback at the end of a stroke

Paintbrush

useBrush(options)

paint

Options

  • color A CSS string color.
  • strokeWidth The width of the brush

Shading

useShadingBrush()

This tools is inspired by some blog posts, exploring the use of "neighbour point" sketching. It gives a fun, unusual effect that is similar to pencil shading. It is highly configurable, giving quite different effects according to the different parameters.

shading

Options

  • color A CSS string color. Default: #000000
  • spreadFactor The length of the connecting line. A value of 1 means it exactly joins the two points, while 0.5 only covers half the distance. A value above 1 gives a "fur" effect as the line extends beyond the points. Default: 0.9
  • distanceThreshold How near the point needs to be to join, in pixels. Default: 50
  • neighbourStrokeWidth Width of the stroke joining the points. Default: 1
  • neighbourColor Color of the line joining the points. Default: color value with 0.2 alpha

Watercolor

useWatercolor(options)

paint

Options

  • color A CSS string color.
  • strokeWidth The width of the brush

Marker pen

useMarker(options)

marker

Options

  • color A CSS string color.
  • strokeWidth The width of the brush

Airbrush

useAirbrush(options)

airbrush

Options

  • color A CSS string color.
  • strokeWidth The width of the brush

Custom brushes

See the source for useBrush to see how to create a brush. It must return an object, with the following optional callbacks:

  • startStroke?: (point: Point, context: CanvasRenderingContext2D) => void
  • continueStroke?: (point: Point, context: CanvasRenderingContext2D) => void
  • endStroke?: (context: CanvasRenderingContext2D) => void
  • cursor?: string A CSS-compatible string for the cursor to display. You can use the circleCursor() helper to display a resizable circle for the cursor

History

The useHistory() hook allows undo/redo functionality. Pass it a size value to limit the size of the history stack. It returns and object with the following:

  • history: The History object. Pass this to the Artboard.
  • undo(): Reverts the image to the previous state.
  • redo(): Move forward in history, if available.
  • canUndo: History is available to undo
  • canRedo: History is available to redo

Sources

These posts gave inspiration, particularly for the shading tool.

Inspiration for the watercolor tool:


Download Details:

Author: ascorbic
Source Code: https://github.com/ascorbic/react-artboard 
License: MIT Licence

#react #paint #application 

React-artboard: A Realistic Paint Component
Monty  Boehm

Monty Boehm

1676364021

Debug Node.js Application Efficiently

Debug Node.js Application Efficiently

In this blog, we have explained how we can debug Node JS application and will share our developer experiences, which will help you to master debugging skills.

Introduction to Debugging

While working on any web project, sometimes we get stuck in complex problems, so we debug the backend code to understand the situation. Debugging is the skill by which we can explore these problematic situations, and with the help of this skill, we can see precisely how our code is executed one by one. We can also explore the values of the variable after a single instruction is executed.

Debugging is a very underrated skill and is often ignored by developers. This skill really helps you understand your code accurately, and it also improves your development skill so you can write your code very effectively. Putting console.log() in your code is not always a good idea; it’s also a time-consuming task.

We will now head up to the intended topic of debugging Node.js application.

Prerequisites to Debug NodeJs app in VS code

Here are some points that you need to be familiar with before you debug Node Js application:

1. Basic understanding of node.js (Express)
2. Basics of javascript

Step-by-Step Guide to Debug Node js Application

To stay on Node.js debug process, let’s take it gradually.

Step 1: Create a Node.js Application

We begin with a basic Node.js application with a single endpoint, and we do some random stuff here. You can use any node.js project.

For now, we have a very basic application where we’re filtering objects from an array on the basis of given type in query parameters. Here is our main js file app.js.

App.js

And here is the tasks.json file where we have an array of objects (list of tasks).

tasks.json file

The above express app example is basic, where we’re listing and filtering tasks. The followings are the endpoint to perform this operation.

To fetch all tasks – http://localhost:3000/all-tasks
To filter tasks by given type – http://localhost:3000/all-tasks?taskType=personal

Now let’s continue with the next step for Nodejs debug process.

Are you struggling to debug your Node.js application?
Don’t waste time trying to fix the problem on your own. Hire Node js developer today and get your application running smoothly again.

Step 2: Setup Node.js Debugger With “Nodemon”

We are using nodemon to debug Node js application. Let’s install nodemon globally, to install nodemon use this command:

npm install -g nodemon 
or
yarn global add nodemon

Once nodemon is installed now we need to serve the node.js application with nodemon, and to do that, use this command:

nodemon -L --inspect app.js

Here app.js file is the main file of node.js application, by hitting this command your application will to served to a given port, for us it is 3000 so the application is running on http://localhost:3000

Now in next step let’s continue with enabling the debugging option in VS code.

Step 3: Start debugger in VS code

Now its time to start the debugger in VS code. To start the debugger, open the command palette in vs code, and to open it simply press Ctrl + Shift + p in windows or Cmd + Shift + p in macOS. It will open the following section:

Start debugger in VS code

Now simply type “Debug: Attach” and you will see an option for “Debug: Attach Node Process” click on it, and after clicking, you’ll see the following screen:

Attach Node Process

These are just node processes that are running in your system, simply click on the first one, and you will see a debug controller like this:

debug controller

We are almost done, our debugger is on now, now we just need to add some breakpoints so the execution will be going to stop there, but directly moving to breakpoints let’s first understand some basic stuff of debugger and debug controller.

Basic Overview of Debug Controller

We are numbering the elements in debug controller, and you can follow the respective numbers to understand their uses. Here is the debug controller:

elements in debug controller

Debug Controller

Here is the explanation of each section.

🟠 Play/Pause: Used for start and pause debugging
🟠 Step In: If want to execute instruction line by line then it will help you to execute step-by-step instruction
🟠 Step into: Let if you are calling a function in between the script then you can simply get into those functions also, it means by this option you can deep down to a function or statement and debug there as well.
🟠 Restart: Restart Debugger from the start or first breakpoint
🟠 Disconnect: Used to stop debugging

Breakpoints

Breakpoints are a main entity of debugging, it tails debuggers from where to stop the execution. By putting breakpoints to your code you are tailing to a debugger that stops execution here and tails the executed variables value here.

You can apply breakpoints by clicking the left side of the editor (left side of the line number column), Following is a screenshot of some breakpoints.

Breakpoints

Once you added the breakpoint now the execution will going to stop here, let’s run the debugger now and see how it works.

Step 4: Run Debugger with Breakpoint

Follow Step 2 & Step 3 to turn on the debugger. Once the debugger is active, let’s hist to the endpoint by which the code will be executed.

Once you hit the respective endpoint or execution starts for the code section in which you have mentioned the breakpoints, you will see a screen like the following:

Run Debugger with breakpoint

This is how it looks when execution stops. This is complete data while executing your code line by line. Let us explain these sections so that you can better understand how to debug Node js application.

🟠 Variables section: This section shows all the variables used in that code section you can also see the respective values of that variable. You might see some variables are undefined or null its because execution has been stopped once the execution for a variable has been finished then you will see the real-time value of that variable
🟠 Call Stack: It’s simply a history of all execution, for example, you can see all execution which was done before the current execution
🟠 Breakpoints: In this section, you can find all the breakpoints which you have added all over the project, this section manages all breakpoints in a single place


Conclusion

That’s about the debugger and how to debug Node js app. We hope this tutorial could help you achieve Node Js debugging. For more such intriguing practicals, you can check our Node tutorials.

Happy Coding 🙂

Original article source at: https://www.bacancytechnology.com/

#node #debug #application 

Debug Node.js Application Efficiently
Nat  Grady

Nat Grady

1676354520

Animate A React Application with Framer Motion

Animate A React Application with Framer Motion

Animations on web pages involve moving elements on the screen to improve the visual experience of users. These animations are visually appealing and tend to draw users’ attention to buttons, images, and other important information. Overall, it contributes to establishing a solid connection between users and the content on the screen.

In the past, web pages were very plain and lacked interactivity because they were only intended to display information, and there was no capability to create appealing visual experiences. Things have changed dramatically in recent years, thanks to the availability of libraries and packages that make it easier to animate and add visual experiences to your web pages.

This article will teach you how to use the Framer Motion library to animate a React application. Why should you use Framer Motion? And how it works by animating a mini-project.

What is Framer Motion?

Framer Motion is an open-source production-ready motion library for React. It allows you to add all forms of animations and transitions directly to Document Object Model (DOM) elements defined in your React components. Its syntax is easy to understand, and with a few lines of code, you will be able to implement awesome animations.

Framer Motion uses an awesome API that gives you access to the motion component. You can plug this component into your React DOM elements giving you access to additional props for animation. For example, the div element will become motion.div.

The Framer Motion also has beginner-friendly documentation with lots of practical examples and illustrations showing how to perform simple to complex forms of animations and transitions.

How Framer Motion works

Framer Motion uses the motion component, which you can attach to any DOM element to implement an animation or transition effect. 

<motion.div>
    <p> An animated text </p>
</motion.div>

Code language: HTML, XML (xml)

Nothing changes when you attach the motion component to your element. Instead, it supercharges that element with animation capabilities, giving you access to props, keys, and values you can use to add any animation. For example, you can access the animate prop, which takes in a dynamic value — an object which contains the different properties and values you want to animate.

<motion.div animate={{x: -10, y: 10}}>
    <p> An animated text </p>
</motion.div>

Code language: HTML, XML (xml)

The above animation will cause the div element to slide 10px to the left and then 10px to the bottom when it loads from the original position specified in style. 

ℹ️ When units are not specified, calculations are done in pixels. You can also specify your preferred units by attaching them. For example: animate={{x:"-10rem"}}.

Getting started with Framer Motion in React

Framer Motion is a popular library with over 1.6 million weekly downloads. You can install the library into your React project using the command below in your terminal:

$ npm i framer-motion

Once you have installed it, you can verify if it has been installed in your package.json file’s dependencies object:

"dependencies": {
    // ...
    "framer-motion": "^7.5.3",
    "react": "^18.2.0",
    // ...
},

Code language: JSON / JSON with Comments (json)

Once you have installed the Framer Motion library, you can import the motion component into a component you wish to use within your project, and everything will work fine.

import { motion } from 'framer-motion';

<motion.h1 animate={{x: 10, y: 20}}>
    An animated text
</motion.h1>

Code language: JavaScript (javascript)

Animating elements in React

The motion component can be applied to any DOM element within your React component. You can apply it to the container elements, headings, text elements, images, and other elements. This motion component gives you access to props like animate, which you can use to adjust the color, size, position, display, and add other animation effects to the DOM element.

<motion.div
    animate={{
        x: 10,
        backgroundColor: '#fff',
        boxShadow: '10px 10px 0 rgba(0, 0, 0, 0.2)',
    }}
>
    <h1>Hi</h1>
    <img src={myImage} alt="" />
</motion.div>

Code language: HTML, XML (xml)

In the example above, the background color changes to white. A box shadow is added to the div when it loads, and the elements contained in the div moves 10px to the right.

It is also important to know that you can apply any form of animation based on CSS attributes. For example, you use x, y, and z to move elements similar to translateX, translateY, and translateZ

You can also scale the size of an element using the scale attribute for both x and y or scaleX and scaleY if you wish to apply separate values. Example:

<motion.div animate={{ scale: 0.8 }} >
    <h1>Hi</h1>
    <motion.img animate={{ scaleX: 1.2 }} src={myImage} alt="" />
</motion.div>

Code language: HTML, XML (xml)

The same applies to transformation values like skew and rotate. It’s also important to mention that it supports all forms of value types, such as numbers, strings, and colors in Hex, RGB, and HSLA as strings. You can also calculate values using the calc() function.

<motion.img animate={{ x: "calc(100vw - 50%)" }} src={myImage} alt="" />

Code language: HTML, XML (xml)

Setting initial animation state

At this point, you have only used the animate prop, which makes you animate elements from the default CSS style to your specified values. But this is not always what you want; sometimes, you want to specify where your animation starts and ends. For example, you might want your text to slide from the left of your screen to the middle.

You can specify initial animation values using the initial props, which work similarly to the animate prop and uses similar attributes and values.

<motion.div
    initial={{ opacity: 0, x: '-100vh' }}
    animate={{ opacity: 1, x: 0 }}
>
    <h1>Hi</h1>
    <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
        perspiciatis voluptates nihil dolores eum architecto eligendi
    </p>
</motion.div>

Code language: HTML, XML (xml)

How to add transition options to animation

You will notice that these animations happen fast to the extent that you might not see them unless you pay close attention. 

The page animates a block of Lorem ipsum text by indenting it and reverting it to its original position.

 

You can fix this by adding transition effects using the transition prop. This transition prop defines the type of animation used when animating between two values and how these values animate from one state to another.

For example, if you add a duration of 1, the animation will run for 1 second.

<motion.div
    initial={{ opacity: 0, x: '-100vh' }}
    animate={{ opacity: 1, x: 0 }}
    transition={{ duration: 1 }}
>
    <h1>Hi</h1>
    <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
        perspiciatis voluptates nihil dolores eum architecto eligendi
    </p>
</motion.div>

Code language: HTML, XML (xml)The page animates a block of Lorem ipsum text for a second by indenting it and reverting it to its original position.

There are three major transition types, and they all have their specific effect; they include Tween, Spring, or Inertia. Tween is the default type for all animation, so if you want a spring form of animation, you will need to specify the transition type as Spring

<motion.div
    initial={{ opacity: 0, x: '-100vh' }}
    animate={{ opacity: 1, x: 0 }}
    transition={{ type: 'spring', duration: 1 }}
>
    <h1>Hi</h1>
    <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
        perspiciatis voluptates nihil dolores eum architecto eligendi
    </p>
</motion.div>

Code language: HTML, XML (xml)

Each type has some attributes peculiar to them. For example, when you use the transition type of spring, you have access to an attribute like bounce which specifies how elastic the spring effect is on the element.

<motion.div
    initial={{ opacity: 0, x: '-100vh' }}
    animate={{ opacity: 1, x: 0 }}
    transition={{ type: 'spring', bounce: 0.6 }}
>
    <h1>Hi</h1>
    <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
        perspiciatis voluptates nihil dolores eum architecto eligendi
    </p>
</motion.div>

Code language: HTML, XML (xml)Spring animation.

There are other attributes like delay, which you can use to set a delay time before the animation renders.

How to use keyframes and repeat animation in Framer Motion

Sometimes, you may want your elements to animate through several different animation values, which may be from left to right, depending on what you want. In CSS, this is handled with keyframes, but for Framer Motion, you can do this with a square bracket holding as many values as you want.

<motion.button
    animate={{ x: [0, -20, 20, -20, 20, 0] }}
    transition={{ delay: 1 }}
>
    My Button
</motion.button>

The page animates a button to the left after a second from the initial render.

Note that in the example above, the animation waited for 1 second before moving the button to the left 20px and right 20px twice before returning to its original position. This can be applied to any animation transform attribute such as x, y, scale, rotate and others.

<motion.button
    animate={{ scale: [1, 1.2, 1, 1.2, 1] }}
    transition={{ delay: 1 }}
>
    My Button
</motion.button>

Code language: HTML, XML (xml)

You will notice that these animations stop after it has completed the number of times specified. The example above will start at 1, which is the default. It will then scale up and down twice to its default value.

However, you may want the animation effect to repeat by using the transition property yoyo and set its value to Infinity or the number of times you wish your animation repeats.

💡 The transition property yoyo lets you specify the number of times you want an animation to repeat.

<motion.button
    animate={{ scale: 1.2 }}
    transition={{ delay: 1, yoyo: Infinity }}
>
    My Button
</motion.button>

Code language: HTML, XML (xml)

In the code block above, you will notice you no longer need the square bracket. All you need is the value it should change to when it leaves the default, 1.

The page animates a Generate Quote button once the button is hovered on.

Implement hover animation gestures

You often want to apply hover gestures to buttons, cards, and other elements to draw the user’s attention. You might want a button to scale up and down when a user hovers over the button instead of just scaling up and down without any action from the user. To do this, you can use the whileHover prop, which works similarly to previous props.

<motion.button
    whileHover={{
        scale: 1.2,
        transition: { yoyo: Infinity },
    }}
>
    My Button
</motion.button>

Code language: HTML, XML (xml)

ℹ️ The transition property for whileHover prop is placed within the curly braces and not outside the whileHover prop.

The page animation transitions once the Generate Quote button is hovered on.

Variants: A better way to use Framer Motion in React

At this point, you have learned the basics of Framer Motion, how it works and how you could use it to implement animations directly on your DOM elements. You must have started asking yourself why you should add all animation properties and values directly on each element because it tends to make your code clumsy and not easy to understand.

This is where variants come in. You use variants to remove the props object and place them outside your component, so you only use the object names within your DOM element. This also helps you use the same animation effect for multiple elements within your component to avoid repetition.

import { Link } from 'react-router-dom';
import logo from './../images/logo.svg';
import { motion } from 'framer-motion';

const headerVariants = {
    initial: {
        y: '-100vh',
    },
    animate: {
        y: 0,
        transition: {
            delay: 0.5,
            duration: 0.5,
            type: 'spring',
        },
    },
};

const Header = () => {
    return (
        <div className="container">
            <motion.div
                className="header"
                variants={headerVariants}
                initial="initial"
                animate="animate"
            >
                <Link to="/">
                    <img src={logo} alt="" />
                </Link>
                <h1>Quotes Circle</h1>
            </motion.div>
        </div>
    );
};

export default Header;

Code language: JavaScript (javascript)

In the code block above, an object (variant) is created to hold all the animation properties and values. This object contained two child objects, one to hold the initial animation and the second to hold the final animation (animate). You can give them any name:

const headerVariants = {
    initial: {
        y: '-100vh',
    },
    animate: {
        y: 0,
        transition: {
            delay: 0.5,
            duration: 0.5,
            type: 'spring',
        },
    },
};

Code language: JavaScript (javascript)

To make use of this variant in your React DOM elements, then you will use the variants prop and pass the variant name into it. Also, you will assign the initial and animate prop with the name you used when creating your variant, but this time as a string and not a dynamic value.

<motion.div
    variants={headerVariants}
    initial="initial"
    animate="animate"
>
    <Link to="/">
        <img src={logo} alt="" />
    </Link>
    <h1>Quotes Circle</h1>
</motion.div>

Code language: HTML, XML (xml)

You can have as many variants as possible, and if you use the same initial and animate value, you would not need to declare that for children elements in your component.

const headerVariants = {
    initial: {
        y: '-100vh',
    },
    animate: {
        y: 0,
        transition: {
            delay: 0.5,
            duration: 0.5,
            type: 'spring',
        },
    },
};

const logoVariants = {
    initial: {
        x: '-100vw',
    },
    animate: {
        x: 0,
        transition: {
            delay: 1,
        },
    },
};

const Header = () => {
    return (
        <div className="container">
            <motion.div
                className="header"
                variants={headerVariants}
                initial="initial"
                animate="animate"
            >
                <Link to="/">
                    <motion.img src={logo} variants={logoVariants} />
                </Link>
                <h1>Quotes Circle</h1>
            </motion.div>
        </div>
    );
};

Code language: JavaScript (javascript)

If you look at the logo image element, you will notice the variants prop was only defined. There is no need to define the initial and animate prop because it has the same name as the previous one you already declared in the parent element.

How to animate routes in React with Framer Motion

When building applications that have more than one page, you will want to add animation between each page. These animations may not be conspicuous but can add a nice experience rather than having content suddenly leave the screen.

The page animates a new component once the route changes.

The GIF above almost looks like the routes are animated, but you will notice that it only animates in but not out. This means that the components disappear when they unmount, so you will want to add an animation instead.

This is done with the AnimatePresence component, which notifies components when they will be unmounted and allows them to defer that unmounting until after the animation is complete. This animation is added with the exit prop to your component’s parent element.

To implement this, you will first import AnimatePresence component to the App.js file where you configured your routes or if it’s in the index.js file. Once that is done, you will wrap the Routes component with the AnimatePresence component:

import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import QuotesPage from './pages/QuotesPage';
import Header from './components/Header';
import { AnimatePresence } from 'framer-motion';

const App = () => {

    return (
    <>
        <Header />
        <AnimatePresence>
        <Routes location={location} key={location.key}>
            <Route path="/" element={<Home />} />
            <Route path="/quote" element={<QuotesPage />} />
        </Routes>
        </AnimatePresence>
    </>
    );
};

export default App;

Code language: JavaScript (javascript)

Then you will need to use useLocation router hook to know when the route changes. This will be attached to the Route component:

import { Routes, Route, useLocation } from 'react-router-dom';
import Home from './pages/Home';
import QuotesPage from './pages/QuotesPage';
import Header from './components/Header';
import { AnimatePresence } from 'framer-motion';

const App = () => {
    const location = useLocation();

    return (
    <>
        <Header />
        <AnimatePresence>
        <Routes location={location} key={location.key}>
            <Route path="/" element={<Home />} />
            <Route path="/quote" element={<QuotesPage />} />
        </Routes>
        </AnimatePresence>
    </>
    );
};

export default App;

Code language: JavaScript (javascript)

At this point, you can now add exit animation to all your component’s parent elements, and the exit animation will work very fine.

For example, if you want to add it to the Home component, which is a route as seen above. You can use variants or add the animation object directly to the exit prop.

// ...
import { motion } from 'framer-motion';

const Home = () => {
    // ...

    const containerVariants = {
        hidden: {
            opacity: 0,
            x: '100vw',
        },
        visible: {
            opacity: 1,
            x: 0,
            transition: {
                type: 'spring',
                mass: 0.4,
                damping: 8,
                when: 'beforeChildren',
                staggerChildren: 0.4,
            },
        },
        exit: {
            x: '-100vw',
            transition: {
                ease: 'easeInOut',
            },
        },
    };

    return (
        <motion.div
            className="container"
            variants={containerVariants}
            initial="hidden"
            animate="visible"
            exit="exit"
        >
            { // ... component elements }
        </motion.div>
    );
};

export default Home;

Code language: JavaScript (javascript)

At this point, your routes will be animated when any component leaves the screen. It will animate out by sliding to the left as specified in the exit object:

exit: {
    x: '-100vw',
    transition: {
        ease: 'easeInOut',
    },
},

Code language: JavaScript (javascript)

But you will notice that the animation of the new component already happens when the previous component leaves the screen. You can fix this by adding an exitBeforeEnter prop to the <AnimatePresence> component you used to wrap the App.js component.

// ... imports
const App = () => {
    const location = useLocation();
    return (
    <>
        <Header />
        <AnimatePresence exitBeforeEnter>
        { // ... routes }
        </AnimatePresence>
    </>
    );
};

export default App;

Code language: JavaScript (javascript)Each page is animated once the route is changed.

How to animate SVGs with Framer Motion

Framer Motion allows you to animate your Scalable Vector Graphics (SVGs) via their path (A way of drawing your SVGs). This is possible by attaching the motion component to the path element of your SVG and then adding your preferred animation alongside the pathlength property with a value of 0 and 1 for when the animation starts and when it ends.

Suppose you have an SVG, you will notice that these SVGs usually have a path or paths defined with so many attributes and values:

const AnimateSVG = () => {
    return (
        <div className="container">
            <svg
                className="my-svg"
                viewBox="0 0 256 256"
                xmlns="http://www.w3.org/2000/svg"
            >
                <rect fill="none" height="256" width="256" />
                <path
                    d="M108,144H40a8,8,0,0,1-8-8V72a8,8,0,0,1,8-8h60a8,8,0,0,1,8,8v88a40,40,0,0,1-40,40"
                    fill="none"
                    stroke="#000"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="12"
                />
                <path
                    d="M224,144H156a8,8,0,0,1-8-8V72a8,8,0,0,1,8-8h60a8,8,0,0,1,8,8v88a40,40,0,0,1-40,40"
                    fill="none"
                    stroke="#000"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="12"
                />
            </svg>
        </div>
    );
};

export default AnimateSVG;

Code language: JavaScript (javascript)

You can attach the motion component to the path element and then use the initial and animate props to add animation to the path:

import { motion } from 'framer-motion';

const AnimateSVG = () => {
    return (
        <div className="container">
            <svg
                className="my-svg"
                viewBox="0 0 256 256"
                xmlns="http://www.w3.org/2000/svg"
            >
                <rect fill="none" height="256" width="256" />
                <motion.path
                    d="M108,144H40a8,8,0,0,1-8-8V72a8,8,0,0,1,8-8h60a8,8,0,0,1,8,8v88a40,40,0,0,1-40,40"
                    fill="none"
                    stroke="#000"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="12"
                    initial={{ pathLength: 0 }}
                    animate={{ pathLength: 1 }}
                    transition={{ duration: 2 }}
                />
                <motion.path
                    d="M224,144H156a8,8,0,0,1-8-8V72a8,8,0,0,1,8-8h60a8,8,0,0,1,8,8v88a40,40,0,0,1-40,40"
                    fill="none"
                    stroke="#000"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="12"
                    initial={{ pathLength: 0 }}
                    animate={{ pathLength: 1 }}
                    transition={{ duration: 2 }}
                />
            </svg>
        </div>
    );
};

export default AnimateSVG;

Code language: JavaScript (javascript)

In the code block above, you will notice that pathLength is used to add animation to the SVG. The initial animation is set to 0, meaning nothing shows, and then within 2 seconds, the SVG will draw.

Animated SVG.

Instead of adding the animation directly, you can use variants and add that single variant to both paths. You can also add more forms of animation, such as opacity if you wish.

import { motion } from 'framer-motion';

const AnimateSVG = () => {
    const pathVariants = {
        hidden: {
            opacity: 0,
            pathLength: 0,
        },
        visible: {
            opacity: 1,
            pathLength: 1,
            transition: {
                duration: 2,
                ease: 'easeInOut',
            },
        },
    };

    return (
        <div className="container">
            <motion.svg
                className="my-svg"
                viewBox="0 0 256 256"
                xmlns="http://www.w3.org/2000/svg"
            >
                <rect fill="none" height="256" width="256" />
                <motion.path
                    d="M108,144H40a8,8,0,0,1-8-8V72a8,8,0,0,1,8-8h60a8,8,0,0,1,8,8v88a40,40,0,0,1-40,40"
                    fill="none"
                    stroke="#000"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="12"
                    variants={pathVariants}
                    initial="hidden"
                    animate="visible"
                />
                <motion.path
                    d="M224,144H156a8,8,0,0,1-8-8V72a8,8,0,0,1,8-8h60a8,8,0,0,1,8,8v88a40,40,0,0,1-40,40"
                    fill="none"
                    stroke="#000"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="12"
                    variants={pathVariants}
                    initial="hidden"
                    animate="visible"
                />
            </motion.svg>
        </div>
    );
};

export default AnimateSVG;

Code language: JavaScript (javascript)

Run the sandbox to preview the application in action:

ta-da 🎉!

In this guide, you have learned how to use Framer Motion to add animation to your React application elements, routes, and SVGs. It is important to note that the Framer Motion offers more than what has been covered in this guide, with many more animation options.

This guide has laid a proper foundation to help you navigate through and use the library in your React application for the first time. You can now check out the Framer Motion documentation to understand more options and animate your React application better. You can also get the animated demo project from this article’s GitHub repository.

Have fun coding!

I’m Joel Olawanle, a frontend developer and technical writer interested in making the web accessible to everyone by always looking for ways to give back to the tech community. Follow me and connect with me on Twitter.

Original article source at: https://coderpad.io

#react #application #motion 

Animate A React Application with Framer Motion

Heroku to Deploy Golang Application

Introduction to Heroku Cloud

Heroku is a popular platform-as-a-service (PaaS) that allows developers to deploy and run applications on the cloud. It supports multiple programming languages, including Go, making it easy for developers to build and deploy their Go applications. In this article, we will discuss how to use Heroku to deploy Golang application.

Step-by-step Guide to Use Heroku to Deploy Golang Application

To deploy Golang app on Heroku cloud platform, follow the steps mentioned below. Before you begin, here are the pre-requirements that you must consider.

Prerequisites before using Heroku to deploy Golang application

  • Basic knowledge of Golang and Git.
  • Install git in your system if not already installed because Heroku will depend on it for deployment.
  • If your project is unavailable in Git, then commit your application changes in git.

Step 1: Set Up a Go Development Environment

To get started, you need to have a Go development environment set up on your local machine. You can download and install Go from the official website.

Step 2: Initialize a Go Module

Go Modules is a package management system for Go that provides versioning and dependency management. By using Go Modules, developers can easily manage their dependencies and ensure that their applications run smoothly on different systems, without the need to set up a GOPATH environment variable.

To create a Go application with Go Modules, you need to initialize a new Go Modules project. You can do this by running the following command in the terminal:

go mod init <module-name>

Step 3: Create a Basic Golang Application

Next, you can create a simple Go application, such as a basic Hello World program. The code for this program is as follows:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello World!")
    })
    http.ListenAndServe(":8080", nil)
}

Now comes the essential part of Golang hosting.

Step 4: Create a Heroku Account

To deploy your application on Heroku, you need to create a Heroku account. Sign-up for a free account on the official website.

Step 5: Verify Heroku Account

To verify your Heroku account, you can follow these steps:
1. Log in to your Heroku account.
2. Go to the “Account Settings” page.
3. Click on the “Verify Account” button.
4. Follow the steps to provide and verify your personal information, including your full name, address, and phone number.
5. Provide payment information to verify your account, which can be a credit card or PayPal account.

Step 6: Install the Heroku CLI

The Heroku CLI (Command Line Interface) allows you to manage and deploy your applications from the terminal. To install the Heroku CLI, follow the instructions below
1. Go to the Heroku CLI download page: Heroku CLI.
2. Select your operating system (Windows, MacOS, or Linux) and follow the instructions to download and install the Heroku CLI.
3. Open a terminal or command prompt window & type the command:

heroku login

4. Enter your Heroku credentials to log in.

Step 7: Create a New Heroku Application

To create a new Heroku application, run the following command in the terminal:

heroku create

Step 8: Deploy Golang App on Heroku

To use Heroku to deploy Golang application, you need to create a Procfile file that specifies the command to run the application. The contents of the Procfile file should be as follows:

web: go run main.go

Next, add the files in your Go application to a Git repository and push the repository to Heroku using the following commands:

git init
git add .
git commit -m "Initial commit"
git push heroku master

Step 9: Launch the Application

After the application is successfully deployed, you can launch it by running the following command:

heroku open

The Go application was deployed to Heroku and opened using the heroku open command. The application’s output, “Hello, World!” is displayed in a web browser. The URL of the application on Heroku is also shown in the web browser’s address bar.

You are successful with Heroku Golang now. Your Go application is now running on Heroku. You can access it through the URL in the terminal as an output of the above heroku open command.

Conclusion

Heroku is a convenient platform for deploying and running Go applications. Its ease of use and support for multiple programming languages make it a popular choice for many developers. Additionally, Heroku Go combination offers a variety of tools and services that make it simple to manage and scale your applications as they grow. Whether you are a beginner or an experienced developer, Heroku is an excellent option for hosting your Go applications.

We hope you found the tutorial to use Heroku to deploy Golang application. For more such valuable lessons, find our Golang tutorials.

Original article source at: https://www.bacancytechnology.com/

#heroku #deploy #golang #application 

Heroku to Deploy Golang Application

ChatGPT: ChatGPT Desktop Application (Mac, Windows and Linux)

ChatGPT

ChatGPT Desktop Application (Mac, Windows and Linux)

📦 Install

Windows

ChatGPT_0.10.3_x64_en-US.msi: Direct download installer

Use winget:

# install the latest version
winget install --id=lencx.ChatGPT -e

# install the specified version
winget install --id=lencx.ChatGPT -e --version 0.10.0

Note: If the installation path and application name are the same, it will lead to conflict (#142)

Mac

brew tap lencx/chatgpt https://github.com/lencx/ChatGPT.git
brew install --cask chatgpt --no-quarantine
  • Also, if you keep a Brewfile, you can add something like this:
repo = "lencx/chatgpt"
tap repo, "https://github.com/#{repo}.git"
cask "chatgpt", args: { "no-quarantine": true }

Linux

  • chat-gpt_0.10.3_amd64.deb: Download .deb installer, advantage small size, disadvantage poor compatibility
  • chat-gpt_0.10.3_amd64.AppImage: Works reliably, you can try it if .deb fails to run
  • Available on AUR with the package name chatgpt-desktop-bin, and you can use your favourite AUR package manager to install it.
  • Also, Aur available with the package name chatgpt-desktop-git.

📢 Announcement

ChatGPT Prompts!

This is a major and exciting update. It works like a Telegram bot command and helps you quickly populate custom models to make chatgpt work the way you want it to. This project has taken a lot of my spare time, so if it helps you, please help spread the word or star it would be a great encouragement to me. I hope I can keep updating it and adding more interesting features.

How does it work?

You can look at awesome-chatgpt-prompts to find interesting features to import into the app. You can also use Sync Prompts to sync all in one click, and if you don't want certain prompts to appear in your slash commands, you can disable them.

chatgpt cmd chatgpt sync prompts

  • In the chatgpt text input area, type a character starting with / to bring up the command prompt, press the spacebar, and it will fill the input area with the text associated with the command by default (note: if it contains multiple command prompts, it will only select the first one as the fill, you can keep typing until the first prompted command is the one you want, then press the spacebar.
  • Or use the mouse to click on one of the multiple commands). When the fill is complete, you simply press the Enter key.
  • Under the slash command, use the tab key to modify the contents of the {q} tag (only single changes are supported #54). Use the keyboard (arrow up) and (arrow down) keys to select the slash command.

chatgpt chatgpt-cmd

✨ Features

  • Multi-platform: macOS Linux Windows
  • Export ChatGPT history (PNG, PDF and Markdown)
  • The main window and system tray support custom URLs to wrap any website into a desktop application
  • Automatic application upgrade notification
  • Common shortcut keys
  • System tray hover window
  • Powerful menu items
  • Support for slash commands and their configuration (can be configured manually or synchronized from a file #55)
  • Customize global shortcuts (#108)
  • Pop-up Search (#122 mouse selected content, no more than 400 characters): The application is built using Tauri, and due to its security restrictions, some of the action buttons will not work, so we recommend going to your browser.

#️⃣ MenuItem

  • Preferences
    • Theme - Light, Dark, System (Only macOS and Windows are supported).
    • Stay On Top: The window is stay on top of other windows.
    • Titlebar: Whether to display the titlebar, supported by macOS only.
    • Hide Dock Icon (#35): Hide application icons from the Dock(support macOS only).
      • Right-click on the SystemTray to open the menu, then click Show Dock Icon in the menu item to re-display the application icon in the Dock (SystemTrayMenu -> Show Dock Icon).
    • Inject Script: Using scripts to modify pages.
    • Control Center: The control center of ChatGPT application, it will give unlimited imagination to the application.
      • Theme, Stay On Top, Titlebar, ...
      • User Agent (#17): Custom user agent, which may be required in some scenarios. The default value is the empty string.
      • Switch Origin (#14): Switch the site source address, the default is https://chat.openai.com, please make sure the mirror site UI is the same as the original address. Otherwise, some functions may not be available.
    • Go to Config: Open the configuration file directory (path: ~/.chatgpt/*).
    • Clear Config: Clear the configuration file (path: ~/.chatgpt/*), dangerous operation, please backup the data in advance.
    • Restart ChatGPT: Restart the application, for example: the program is stuck or the injection script can take effect by restarting the application after editing.
    • Awesome ChatGPT: Recommended Related Resources.
  • Edit - Undo, Redo, Cut, Copy, SelectAll, ...
  • View - Go Back, Go Forward, Scroll to Top of Screen, Scroll to Bottom of Screen, Refresh the Screen, ...
  • Help
    • Update Log: ChatGPT changelog.
    • Report Bug: Report a bug or give feedback.
    • Toggle Developer Tools: Developer debugging tools.

⚙️ Application Configuration

PlatformPath
Linux/home/lencx/.chatgpt
macOS/Users/lencx/.chatgpt
WindowsC:\Users\lencx\.chatgpt
  • [.chatgpt] - application configuration root folder
    • chat.conf.json - preferences configuration
    • chat.awesome.json - Custom URL lists, similar to browser bookmarks. Any URL can be used as the main window or tray window (Control Conter -> Awesome)
    • chat.model.json - prompts configuration,contains three parts:
      • user_custom - Requires manual data entry (Control Conter -> Language Model -> User Custom)
      • sync_prompts - Synchronizing data from f/awesome-chatgpt-prompts (Control Conter -> Language Model -> Sync Prompts)
      • sync_custom - Synchronize custom json and csv file data, support local and remote (Control Conter -> Language Model -> Sync Custom)
    • chat.model.cmd.json - filtered (whether to enable) and sorted slash commands
    • [cache_model] - caching model data
      • chatgpt_prompts.json - Cache sync_prompts data
      • user_custom.json - Cache user_custom data
      • ae6cf32a6f8541b499d6bfe549dbfca3.json - Randomly generated file names, cache sync_custom data
      • 4f695d3cfbf8491e9b1f3fab6d85715c.json - Randomly generated file names, cache sync_custom data
      • bd1b96f15a1644f7bd647cc53073ff8f.json - Randomly generated file names, cache sync_custom data

Sync Custom

Currently, only json and csv are supported for synchronizing custom files, and the following formats need to be met, otherwise the application will be abnormal:

JSON format:

[
  {
    "cmd": "a",
    "act": "aa",
    "prompt": "aaa aaa aaa"
  },
  {
    "cmd": "b",
    "act": "bb",
    "prompt": "bbb bbb bbb"
  }
]

CSV format

"cmd","act","prompt"
"a","aa","aaa aaa aaa"
"b","bb","bbb bbb bbb"

📌 TODO

  • Control Center enhancement
  • Pop-up Search enhancement
  • ...

👀 Preview

install popup search control center export dalle2 tray auto update

❓FAQ

Can't open ChatGPT

If you cannot open the application after the upgrade, please try to clear the configuration file, which is in the ~/.chatgpt/* directory.

Out of sync login status between multiple windows

If you have already logged in in the main window, but the system tray window shows that you are not logged in, you can fix it by restarting the application (Menu -> Preferences -> Restart ChatGPT).

Is it safe?

It's safe, just a wrapper for OpenAI ChatGPT website, no other data transfer exists (you can check the source code).

Developer cannot be verified?


How do I build it?

PreInstall

Start

# step1:
git clone https://github.com/lencx/ChatGPT.git

# step2:
cd ChatGPT

# step3: install deps
yarn

# step4:
yarn dev

# step5:
# bundle path: src-tauri/target/release/bundle
yarn build

❤️ Thanks

  • The core implementation of the share button code was copied from the @liady extension with some modifications.
  • Thanks to the Awesome ChatGPT Prompts repository for inspiring the custom command function for this application.

Star History Chart

Download Details:

Author: lencx
Source Code: https://github.com/lencx/ChatGPT 
License: Apache-2.0 license

#chatgpt #desktop #application #windows #macos #linux 

ChatGPT: ChatGPT Desktop Application (Mac, Windows and Linux)
Bongani  Ngema

Bongani Ngema

1675963680

NewsFeed-MVI-Dagger: Android News Application Built in Kotlin

NewsFeed-MVI-Dagger

Project Overview

NewsFeed, provides live top and breaking headlines for a country, specific category in a country, single source, or multiple sources, by interacting to News API

Screenshots

Headlines headline_dialog Sources source-articles favorites

API Key Note

Define key in build.gradle

In your Android studio root directory, locate the gradle.properties under .gradle folder and add the following: Add NEWS_APIKEY = "YOUR-API-KEY".

Language

Kotlin

Features

  • MVI with Android Architecture Components(Room, LiveData, ViewModel)
  • Leverage NetworkBoundResource
  • Dagger2 for Dependency injection architectural pattern
  • Discover the top headlines news in a country
  • Look for top headlines news based on Sources and categories
  • Users can mark an article as favorite in the details view by tapping a heart icon
  • Pagination and endless scrolling using custom pagination.
  • Handle network status and network failures
  • ConstraintLayout(guidelines, barriers... etc)
  • ViewPager2
  • Material design.
  • Custom Navigation Controller for Multiple navigation graph
  • Bottom Navigation Bar
  • Kotlin Coroutines

Libraries

External Resources

NewsFeed uses the News API but is not endorsed or certified by NewsApi.

Download Details:

Author: HadySalhab
Source Code: https://github.com/HadySalhab/NewsFeed-MVI-Dagger 

#kotlin #android #application 

NewsFeed-MVI-Dagger: Android News Application Built in Kotlin

How to Deploy Ruby on Rails Application on Heroku

Introduction

For any developer, the most satisfying thing is to make their development available to each individual after building it as a reference source. So, after locally previewing and developing a Rails application on your system, the following step is to put it online so that others can observe it. This is called deploying the application. Now here comes Heroku.

It allows you to deploy your Ruby on Rails application quickly and is prominent for learners because it’s an open-source and “effortless” push-to-deploy system. Concisely, Heroku handles pretty much everything for the individual. Let us check how you can deploy Ruby on Rails application on Heroku with the following steps.

Steps to Deploy Ruby on Rails Application on Heroku Cloud Platform

To publish your app on the cloud, here are the steps you need to follow. Deploying Ruby on Rails app to Heroku platform as a service is not that tricky. This guide will show you how to begin with your RoR app from local server to deploying it on Heroku.

Local Setup

1. Create a new Heroku account.
2. Install the Heroku CLI on your machine.

$ sudo snap install --classic heroku

3. After installation, the heroku command is now available in your system. Use your Heroku account credentials to log in.

admin1@admin1-Latitude-3510:~$ heroku login
heroku: Press any key to open up the browser to login or q to exit: 

4. Create a new ssh key if not available otherwise, press Enter instantly to upload the existing ssh key used for pushing the code later.

$ heroku login
heroku: Enter your Heroku credentials Email: schneems@example.com
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub

Create a Rails Application

Fire the following commands to create a rails application.

rails new app -d postgresql
cd app
bundle a tailwindcss-rails
rails tailwindcss:install

Disclaimer:- Here we are using Ruby2.7.2 and Rails 6.1.7 running on Ubuntu 22.04.1

Working with Ruby is entertaining, but you can’t deploy the application running on SQLite3 on Heroku. PostgreSQL is the practical standard for databases on Heroku. Add the gem ‘pg’ if you’re using your current RoR application.

gem 'sqlite3'

To this:

gem 'pg'

Note:- During development PostgreSQL is the highly approved database to use. Because of differences between your development and deployment environments, an analogy is maintained which helps to prevent devious bugs from being established in the application. Install Postgres locally if it is yet to be available on your system.

In Gemfile, add rails_12factor gem if you use former Rails versions to authorize static asset serving and logging on Heroku.

gem 'rails_12factor', group: :production

During deploying a new application, the rails_12factor gem is not needed. But if you are upgrading an already existing application, you can remove the rails_12factor gem provided you have the proper configuration in your config/environments/production.rb file:

# config/environments/production.rb
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
if ENV["RAILS_LOG_TO_STDOUT"].present?
Logger                       = ActiveSupport::Logger.new(STDOUT)
   Logger.formatter  = config.log_formatter
    config.Logger = ActiveSupport::TaggedLogging.new(Logger)
end

Now reinstall your dependencies (to generate a new Gemfile.lock):

$ bundle install

Amend the database.yml with your data and make sure the config/database.yml is using the postgresql adapter.

production:      
   <<: *default      
   database: app_production

Tоproduction:
    <<: *default
   adapter: postgresql    
    database: app_production

Run the scaffold command to create the Post.

$ rails g scaffold posts title:string content:text

Create and Migrate the database.

$ rails db:create 
$ rails db:migrate

Change the main page route in routes.rb and start the server

root "posts#index"
rails s

Push your code changes to git

git init
git add .
git commit -m "Deploying Rails application

Source Code: deploying-rails-app

You can also clone the code. Here’s the source code of the repository: https://github.com/ishag-bac/Deploy

Prerequisites

As we want to deploy Ruby on Rails application on Heroku, we will need the following.

  • Basic knowledge of Ruby/Rails and Git.
  • An installed version of Ruby 2.5.0+ and Rails 6+ in your local machine.
  • A verified Heroku account.
  • Install git in your system if not already installed because Heroku will depend on it for deployment.
  • If your project is not available in Git, then commit your application changes in git.

Specify Ruby Version

Rails 6 requires Ruby 2.5.0 or above. By default, a recent version of Ruby is installed in Heroku. However, you can specify the exact version in your Gemfile using the ruby domain-specific languages. Depending on the current Ruby version running in the application, it might look like this:

ruby '2.7.2'

The same version of Ruby should be running locally as well. You can check the ruby version by running $ ruby -v.

Deploy Ruby on Rails application on Heroku

After installing Heroku CLI and logging into your Heroku account, ensure you are in the correct directory path containing your application, then follow the instructions below.

Create an application in Heroku using the below command in the terminal.

$ heroku create

Push your code to Heroku on the master branch.

$ git push heroku master

Note:- Check the default branch name before deployment. If it uses master, use git push heroku master. Otherwise ,use git push heroku main.

Migrate the database of your application by running.

$ heroku run rails db:migrate

To seed your database with data, run.

$ heroku run rails db:seed

Get the URL of your application and visit in the browser.

$ heroku apps:info

Visit Your Application

The deployment of the source code to Heroku is done. Now you can instruct to execute a process type to Heroku. Heroku implements this process by running the associated command in a dyno. [Dyno is the basic unit of composition, a container on the Heroku server.]

Ensure that you have a dyno running the web process type with the command:

$ heroku ps:scale web=1

You can check the state of the app’s dynos. All the running dynos of your application can be listed out by applying the heroku ps command.

Using heroku open, we can open the deploying application.

View Logs

If the application is not functioning correctly or you run into any problems, you must check the logs. With the help of heroku logging commands, you can get information about your application.

By running the command with the –tail flag option like this, you can also get the entire stream of logs:

$ heroku logs --tail

Troubleshooting

Check your logs if you push up your application, and it crashes (heroku ps shows state crashed) to find out what exactly went wrong while pushing up the application. Here are some issues.

Runtime Dependencies on Development Gems and Test Gems

Check your Bundler groups if you’re missing a gem while deploying. Heroku builds your application without the development or test groups, and if your app depends on a gem from one of these groups to run, you should move it out of the group. Therefore before deploying Ruby on Rails app to Heroku, test if it works locally, then push it to Heroku.

Conclusion

We hope you found our comprehensive guide useful and would try to deploy ruby on rails application on Heroku. In case of any queries, feel free to reach out to us. We will be glad to assist you in your technical endeavors. You can find relevant Ruby on Rails tutorials if that interests you. Do share this blog on social media and with your friends, and comment if you have any suggestions. Happy to help!

Original article source at: https://www.bacancytechnology.com/

#ruby #rails #application #heroku 

How to Deploy Ruby on Rails Application on Heroku
Bongani  Ngema

Bongani Ngema

1675588320

Heyyoo: A Sample Modern Kotlin Application

Heyyoo

A sample modern Kotlin application - Documentation still under maintenance

Content

It is an exemplary social media application where users motivate each other.

Architecture components

Ideally, ViewModels shouldn’t know anything about Android. This improves testability, leak safety and modularity. ViewModels have different scopes than activities or fragments. While a ViewModel is alive and running, an activity can be in any of its lifecycle states. Activities and fragments can be destroyed and created again while the ViewModel is unaware.

Passing a reference of the View (activity or fragment) to the ViewModel is a serious risk. Lets assume the ViewModel requests data from the network and the data comes back some time later. At that moment, the View reference might be destroyed or might be an old activity that is no longer visible, generating a memory leak and, possibly, a crash.

The communication between the different layers follow the above diagram using the reactive paradigm, observing changes on components without need of callbacks avoiding leaks and edge cases related with them.

Patterns

  • Repository Pattern - The Repository Pattern is one of the most popular patterns to create an enterprise level application. It restricts us to work directly with the data in the application and creates new layers for database operations, business logic, and the application's UI.
  • Observer Pattern - The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

Usage

Values ​​in Constants.kt file must be filled.

        const val API_URL = "https://sample-node-social-app.herokuapp.com/"
        const val PREF_USER_TOKEN_VALUE = "PREF_USER_TOKEN_VALUE"
        const val PREF_USER_ID_VALUE = "PREF_USER_ID_VALUE"
        const val PREF_USER_TOKEN = "user_token_code.xml" 
        const val ALGOLIA_APPLICATION_ID = "xxxx"
        const val ALGOLIA_SEARCH_ONLY_API_KEY = "xxxxx"
        const val ALGOLIA_ADMIN_API_KEY = "xxxxx"
        const val ALGOLIA_INDEX_NAME = "user-list"

Features

Followed - Following System

User Search System

Content Share(Location,Text) System

User Profile System

Register - Login System

...

BackEnd

NodeJs

Mongoose

MongoDb

Libraries

  • Retrofit : type-safe HTTP client.
  • Coroutines : managing background threads with simplified code and reducing needs for callbacks.
  • Room Library
  • Lifecycle : perform actions in response to a change in the lifecycle status of another component, such as activities and fragments.
  • ViewModel : designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
  • LiveData : lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services.
  • Data Binding - allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.
  • Navigation
  • Gson : makes it easy to parse JSON into Kotlin objects.
  • Glide : image loading library for Android.
  • CircleImageView
  • EasyValidation
  • Toasty
  • Dexter
  • RxImagePicker
  • Secure-Preferences
  • Algolia - instantsearch
  • Paging
  • Splashy
  • Locgetter
  • ReactiveNetwork
  • Lottie
  • ...

Resources

Projects

This is project is a sample, to inspire you and should handle most of the common cases, but obviously not all. If you need to take a look at additional resources to find solutions for your project, visit these interesting projects:

Libraries

The open-source community create and maintains tons of awesome libraries making your job more easy, giving the opportunity to use them in your developments. Here are a very important collection of them:

Best practices

Avoid reinventing the wheel by following these guidelines:

Codelabs

Google Developers Codelabs provide a guided, tutorial, hands-on coding experience. Most codelabs will step you through the process of building a small application, or adding a new feature to an existing application. They cover a wide range of android concepts to learn and practice:

Images

Download Details:

Author: Ardakazanci
Source Code: https://github.com/ardakazanci/Heyyoo 
License: LICENSE-2.0

#kotlin #android #application 

Heyyoo: A Sample Modern Kotlin Application