Giter Club home page Giter Club logo

chandu0101 / sri Goto Github PK

View Code? Open in Web Editor NEW
634.0 35.0 35.0 39.98 MB

Build truly native cross platform (web,ios,android) apps using scalajs and react, react-native ,This project moved to new organization : https://github.com/scalajs-react-interface/sri#sri, new chat room : https://gitter.im/scalajs-react-interface/sri

License: Apache License 2.0

Scala 99.85% HTML 0.03% Objective-C 0.12%
scalajs react android react-native ios web reactjs cross-platform scala

sri's Introduction

sri

This Project Moved to new organization https://github.com/scalajs-react-interface/sri#sri , please join our new chat room : https://gitter.im/scalajs-react-interface/sri

Join the chat at https://gitter.im/chandu0101/sri

Sri (Scala React interface) is a scalajs library to build truly native cross platform (mobile (ios and android) and web) applications. It is based on reactjs and react-native, so you must be familiar with them in order to use this library.

sri

moviesapp

Index

#Mobile Use this module to build iOS/Android mobile applications:

libraryDependencies += "com.github.chandu0101" %%% "sri-mobile" % "0.7.1"

#Web Use this module to build browser based applications:

libraryDependencies += "com.github.chandu0101" %%% "sri-web" % "0.7.1"

#Documentation

#RelatedProjects

#Examples

#Templates

#Apps

Projects that are using Sri in production

sri's People

Contributors

adgelbfish avatar chandu0101 avatar dispalt avatar gitter-badger avatar hamazy avatar kschweppe avatar mkotsbak avatar ramnivas avatar simerplaha avatar xsistens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sri's Issues

How to use custom component inside other

I am new to React as well as Sri and Scalajs. I am backend developer working on scala and trying to write app using scala and Sri. I am not able to figure out how to use custom component inside root component See snippet below. Counter is my custom component. I am returning array of View and Counter in render method. I tried putting Counter at leaf level as well inside outermost View.

So how do i use custom comonent?

object HelloSriMobile {

  @ScalaJSDefined
  class Component extends ReactComponent[Unit, Unit] {
    def render() = {
      Array(View(style = styles.container)(
        Text(style = styles.text)(s"Welcome to Sri Mobile(${ReactNative.Platform.OS})"),
        Image(style = styles.image, source = ImageSource(uri = "http://www.scala-js.org/images/scala-js-logo-256.png"))(),
        Text(style = styles.text)("Scala.js - Future of app development!")
      ),
      Counter())
    }
  }

Code for Counter.scala

@ScalaJSDefined
class Counter extends ReactComponent[Props,State] {

  def border = {
    val borderStl = if(state.showBorder) "dashed" else "dotted"
    style(borderWidth := 1, borderStyle := borderStl , padding := 5)
  }

  initialState(State())

  def render() = {
    TouchableWithoutFeedback(style = border)(
      ///iew(onClick = tick _)(s"Clicks: ${state.count}")
      View(style = styles.container)(
        View(style = border)(
          Text(style = styles.text2)("Dashed border style")
        )
      )
    )
  }

  def tick():  Unit = {
    setState(state.copy(count = state.count + 1, showBorder = (!showBorder)))
  }

}
case class Props(initialCount: Int = 0)
case class State(count: Int = 0, showBorder: Boolean = true)

object Counter {
  def apply() = {
    new Counter()
  }
}

Investigate npm/node.js-free possibility

I see that the project is depending heavily on npm packages and dependencies as well as sbt. It would be easier to use if only sbt was required to build and use the library.

Do you think that is possible? All dependencies from npm/bower is possible to find/import to webjars.org and get from sbt.

TimeoutError on building mobile example

Hi,

I encountered TimeoutError when I tried to run the mobile example included in this project.

$ node node_modules/react-native/local-cli/cli.js start --reset-cache
......
[11:39:04 PM] <START> request:/index.ios.bundle?platform=ios&dev=true&hot=true
[11:39:04 PM] <START> find dependencies
Error: TimeoutError: transforming /Users/hamazy/Documents/programming/javascript/sri/mobile-examples/index.ios.js took longer than 301 seconds.
You can adjust timeout via the 'transformTimeoutInterval' option
    at index.js:101:30
    at tryCallOne (/Users/hamazy/Documents/programming/javascript/sri/mobile-examples/node_modules/promise/lib/core.js:37:12)
    at /Users/hamazy/Documents/programming/javascript/sri/mobile-examples/node_modules/promise/lib/core.js:123:15
    at flush (/Users/hamazy/Documents/programming/javascript/sri/mobile-examples/node_modules/asap/raw.js:50:29)
    at nextTickCallbackWith0Args (node.js:452:9)
    at process._tickCallback (node.js:381:13)
Error: TimeoutError: transforming /Users/hamazy/Documents/programming/javascript/sri/mobile-examples/index.ios.js took longer than 301 seconds.
You can adjust timeout via the 'transformTimeoutInterval' option
    at index.js:101:30
    at tryCallOne (/Users/hamazy/Documents/programming/javascript/sri/mobile-examples/node_modules/promise/lib/core.js:37:12)
    at /Users/hamazy/Documents/programming/javascript/sri/mobile-examples/node_modules/promise/lib/core.js:123:15
    at flush (/Users/hamazy/Documents/programming/javascript/sri/mobile-examples/node_modules/asap/raw.js:50:29)
    at nextTickCallbackWith0Args (node.js:452:9)
    at process._tickCallback (node.js:381:13)

Although @chandu0101 reported the same issue in facebook/react-native#6830 and it was already closed, the problem still exists in the example. It would be nice if it runs right out of the box.

A possible solution would be fix-transform-timeout branch in hamazy/sri but I'm not sure the direction is ok. I will create a pull request if it's needed.

Modal component crashes on IOS 10.2 (iPhone 5)

Running the mobile-examples on Simulator (MacOS Sierra):

  • click on Modal demo
  • click on Present
  • it will crash

sri-2

tested on IOS 10.2 - iPhone 5 - Simulator

I fixed it modifying val flexOne = flex := 1 to val flexOne = flexGrow := 1 in universal/src/main/scala/sri/universal/styles/NativeAttrs.scala but I feel like it is a very high level to act for such a scoped issue.

rework on DOM(html,svg) tags

currently its 60k LOC(inline +noinline) (generated) , each tag defined like ..

     
 @inline
 def caption(
  tabIndex: U[Int] = undefined,
is: U[String] = undefined,
classID: U[String] = undefined,
contentEditable: U[String] = undefined,
role: U[String] = undefined,
style: U[js.Any] = undefined,
hidden: U[Boolean] = undefined,
ref: U[(_ <: dom.html.Element) => _] = undefined,
key: U[String | Int] = undefined,
dir: U[String] = undefined,
id: U[String] = undefined,
.. many more
  @exclude extraAttributes: U[js.Object] = undefined)(children: ReactNode*) : ReactElement  = {
      val props = FunctionMacro()
    if(extraAttributes.isDefined && extraAttributes != null) addJsObjects(props,extraAttributes.get)
    if (developmentMode) React.createElement("caption",props,children :_*)
    else inlineReactElement("caption",props,children :_*)
 }

In above code we used macro to create js.Object from method params which expands to bunch of updateDynamic calls and we have extrraAttributes for unknown props at compile time which will add extra execution time while combing objects ,i think with new @ScalaJSDefined trait changes came in scala.js 0.6.14 we can make it better!

New Proposal :

lets have a global trait with all dom attributes

@ScalaJSDefined
trait DOMProps extends js.Object {
var  tabIndex: U[Int] = undefined,
 var is: U[String] = undefined,
var classID: U[String] = undefined,
var contentEditable: U[String] = undefined,
var role: U[String] = undefined,
var style: U[js.Any] = undefined,
......
}

def caption(props:DOMProps)(children:ReactNode*) = React.createElement("caption",props,children:_*)

//call site 
caption(new DOMProps { id = "hello" ; tabIndex = 2})(children)

Pros :
1)we can have type safe DOM tags under 500LOC instead of 30K LOC before
2)no need of macros
3)no extra run time cost

Cons :
1)we need some extra typing new DOM Props{ at call site , but i think its not a big deal

prepare for 0.6.0 release

TODO :

  • Update Documentation(makeElement,changelog,ReadMe,..)
  • react-native 0.37.0
  • sri-extra (material-ui - 0.16.0)
  • update templates and examples

Runtime error on assign a value to an input in a component

With the following code:

package testinputvalue

import org.scalajs.dom
import scala.scalajs.js
import scala.scalajs.js.annotation.ScalaJSDefined
import sri.core.ElementFactory.{ createElementNoProps, getTypedConstructor }
import sri.core.{ ReactComponent, ReactElement }
import sri.web.ReactDOM
import sri.web.vdom.htmltagsPrefix_<._

@ScalaJSDefined
final class TestInputValue extends ReactComponent[Unit, Unit] {
  override def render: ReactElement = <.input(value = "foo")
}

object Main extends js.JSApp {
  override def main(): Unit =
    ReactDOM.render(
      createElementNoProps(
        getTypedConstructor(
          js.constructorOf[TestInputValue], classOf[TestInputValue])),

      dom.document getElementById "app")
}

and

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8"><title>Test Input Value</title>
  </head>
  <body>
    <div id="app"></div>

    <script src="https://unpkg.com/[email protected]/dist/react.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/react-dom.js">
    </script>

    <script
      type="text/javascript"
      src="./target/scala-2.11/dashboard-fastopt.js">
    </script>

    <script type="text/javascript">testinputvalue.Main().main();</script>
  </body>
</html>

I'm getting the following runtime error: Uncaught TypeError: Cannot call isInstance() on a Class representing a raw JS trait/object, scalajsenv.js:208

I tracked down that exception to scala-js/scala-js@f369c6b so it looks like Sri is trying to runtime cast my string foo to an UndefOr[String | Int | Double] and this is throwing the exception ... but beyond that I am confused.

rework on third party components

Current approach :

case class View(onResponderReject: js.UndefOr[js.Function] = js.undefined,
                renderToHardwareTextureAndroid: js.UndefOr[Boolean] = js.undefined,
                onStartShouldSetResponder: js.UndefOr[js.Function] = js.undefined,
                onResponderRelease: js.UndefOr[js.Function] = js.undefined,
                onMagicTap: js.UndefOr[js.Function] = js.undefined,
                onResponderMove: js.UndefOr[js.Function] = js.undefined,
                style: js.UndefOr[js.Any] = js.undefined,
                . .. more props
             ) {

  def apply(children: ReactNode*) = {
    val props = JSMacro[View](this)
    React.createElement(ReactUniversal.View, props, children: _*)
  }
}

here also we don't need any macro magic, lets follow DOM tags style

New Proposal :

@ScalaJSDefined
trait ViewProps extends js.Object {
 var onStartShouldSetResponder: js.UndefOr[js.Function] = js.undefined,
  var onResponderRelease: js.UndefOr[js.Function] = js.undefined,
  var  onMagicTap: js.UndefOr[js.Function] = js.undefined,
  var id: String
}

def View(props:ViewProps)(children:ReactNode*) =   React.createElement(ReactUniversal.View, props, children: _*)

Pros :
1)no need of macros
2)no extra run time cost
3) Some components accept ViewProps + ... , now we can extendViewProps before we have to copy all props.

Cons :
1)we need some extra typing new ViewProps{ at call site , but i think its not a big deal

rework on Web Inline Styles

Current Approach

case class WebStyle(name: String) {
  def :=(v: String | Double) = new WebStylePair(name, v)
}

class WebStylePair(val name: String, val value: Any)

trait WebStyleAttrs {
  final val/lazy val opacity = new WebStyle("opacity")
  object flexDirection extends WebStyle("flexDirection") {
    @inline final def column = this := "column"
    @inline final def columnReverse = this := "column-reverse"
    @inline final def row = this := "row"
    @inline final def rowReverse = this := "row-reverse"
  }
 ...  more
}

trait WebStyleSheet extends WebStyleAttrs {


  /** if duplicate attrs found then last one wins */
  @inline def styleE(maps: js.Dictionary[Any]*)(v: WebStylePair*) = {
    maps.fold(js.Dictionary.empty[Any])((d1, d2) => d1.++(d2).toJSDictionary)
      .++(style(v: _*))
      .toJSDictionary
  }

  @inline def style(v: WebStylePair*): js.Dictionary[Any] = {
    val p = js.Dictionary.empty[Any]
    v.foreach(t => p.update(t.name, t.value))
    p
  }

}

New Proposal:

@ScalaJSDefined
 trait WebStyles  extends js.Object { 
  var opracity: js.UndefOr[String | Int] = js.undefined
  var flexDirection : js.UndefOr[String] = js.undefined
  ....
 
}

trait WebStyleSheet extends WebStyleAttrs {
  /** if duplicate attrs found then last one wins */
  @inline def styleE(maps: js.Dictionary[Any]*) = {
    maps.fold(js.Dictionary.empty[Any])((d1, d2) => d1.++(d2).toJSDictionary)
      .toJSDictionary
  }
}

Pros :
1)no runtime overhead
2)easy to define and maintain

Cons :
1)we loose little convenience in defining enum attributes for example in previous system flexDirection.column now flexDirection = "column"

Scalafmt

You mind if I add the scalafmt plugin, along with some default settings that people seem to like?

It's going to completely change all the source, but it enforces some consistency and uses less spacebar/tabs =).

project name space

is seems this project is mature enough to warrant own "proper" name space

please consider a move to a separate git organisation, i.e. scalajs-sri
https://github.com/scalajs-sri

as well as changing maven artifacts group name

thank you

Compatibility problem with React Native 0.26

Hi

First, thank you for this useful project.

There is a problem with React Native version 0.26. Apparently it is a packaging incompatibility, because what React Native 0.26.0 release notes says:

React API must be now required from react package (previously a warning on 0.25)

(https://github.com/facebook/react-native/releases/tag/v0.26.0)

And this is the error message when react-native run-android is executed:

undefined in not an object (evaluating '$g.React.Component.prototype')

Add fastOptMobile task

Running fullOptMobile is not super fast and also makes debugging a bit harder (due to shortened names). Would it be possible to also provide the fastJS mode, i.e. fastOptMobile?

Debug Scala.js

Is there any way to debug the Scala.js code in Chrome when running in the react-native in the iOS Simulator (or anyhow else), I'm only able to debug using the generated index.ios.js :-(?

Suspicious local dependency

In relay-mobile-examples/package.json I see:

/Users/chandrasekharkode/Desktop/Kode/Programming/relay/react-native

[Web]url based router

Even though UniversalRouter works on web( and mobile) it doesn't support urls , If any one want url based router then create one.

Options :

  1. use https://github.com/rackt/history as base and create one (2 -3 days work) ,Consider this option first it's helpful in long run as history module is actively developed by community and history module also planning to support react-native , you'll end with one more universal router ๐Ÿ‘

  2. roll your own based on HTML5 history api

Mobile examples are not building

It fails on some missing npm modules like webpack and graphql declared in package.json in subdirectories. It should be buildable out of the box.

Eliminate getTypedConstructor boilerplate

First, create a base trait

trait ReactComponentBase {
  type Props
  type State
}

then make ReactComponent extend it and fill in type members to its type arguments.

Then you can have

def typedConstructor[A](implicit ct: ConstructorTag[A]) = ct.constructor.asInstanceOf[ReactTypedConstructor[P, S]]

However I would take it a step further:

class ReactFactory[A, P, S](val ctor: js.Dynamic) {
  def typed = ctor.asInstanceOf[ReactTypedConstructor[P, S]]
  def createElement(props: P): ReactElementU[P, S] = ...
  // all the createElement variants
}
object ReactFactory {
  def apply[A <: ReactComponentBase](implicit ct: ConstructorTag[A]) = new ReactFactory[A, A#Props, A#State](ct.constructor)

Now you can write ReactFactory[MyComponent].createElement(...)

Note: createElement is necessary, we can't just call it apply and use function application syntax, since that would get interpreted as filling the implicit parameter list.

Alternatively, createElement etc. could be modified to something like

def createElement[A <: ReactComponentBase](props: A#Props, ...)(implicit ct: ConstructorTag[A]) = ...

(or take ReactFactory implicitly as a typeclass).

todo list

Mobile

Web

  • design web-examples demo
  • add more components

Relay

Misc

  • more documentation
  • test cases
  • sri-cli (to bootstrap sri projects)
  • provide template projects (relay)

"Package name com.sri-mobile is invalid"

$sri/mobile-examples$ react-native android
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: Package name com.sri-mobile is invalid
    at [object Object].module.exports.yeoman.generators.NamedBase.extend.initializing [...]

This is most likely caused by a hyphen (โ€) in the package name. It could be replaced by an underscore (_).

move to new organization scalajs-react-interface

Hi,
Till now sri is under single owner,its definitely not scalable option in long run , lets distribute owner ship(maintenance & publishing). from now onwards all future work will be done under https://github.com/scalajs-react-interface. as we're moving to more stable place lets make architecture changes and breaking changes now!.

Separate Project for each module :

Core : react core types and component/element construction helpers/factories.

Universal : Components and API's that will work across multiple platform (web,ios,android,macos,windows)

Relay : react-relay

Web: ReactDOM and html tags,svg tags etc

Mobile : react-native

Other Platforms..

by having separate project we can iterate rapidly, for example if @dispalt want some change in relay and @nafg want some change in web, they can make their changes in isolation and publish it without worrying about other projects ..

How to use sri 0.7 mobile with react-native-web?

I used version 0.6

libraryDependencies += "com.github.chandu0101" %%% "sri-mobile" % "0.6.0"

and with

    <script type="text/javascript" src="https://unpkg.com/[email protected]/dist/react.js"></script>
    <script type="text/javascript" src="https://unpkg.com/[email protected]/dist/ReactNative.js">

I could open my app in browser and it worked.
But with 0.7.1 I am not sure not to do it.
There is an js error

exports is not defined

Using a third party component

Hey, I would need some help for wrapping a third party component.
I added the dependency in my build.sbt file:
jsDependencies += ProvidedJS / "node_modules/react-native-drawer/index.js"
But in my wrapper I'm not sure how I could access it. When I try following, I always get an undefined component:

def apply(children: ReactNode*) = {
    // access real js component , make sure you wrap with createFactory (this is needed from 0.13 onwards)
    val f = React.createFactory(js.Dynamic.global.Drawer)
    f(toJS, children: _*)
  }

sri.core.InternalReactComponent needs to be imported from module 'react'

After update from 0.6 to 0.7.1 I cannot compile the project

[error] sri.core.InternalReactComponent needs to be imported from module 'react' but module support is disabled.
[error] sri.core.React$ needs to be imported from module 'react' but module support is disabled.
[error] sri.universal.ReactUniversal$ needs to be imported from module 'react-native' but module support is disabled.
[error] sri.mobile.ReactNative$ needs to be imported from module 'react-native' but module support is disabled.
[trace] Stack trace suppressed: run last compile:fastOptJS for the full output.
[error] (compile:fastOptJS) There were module imports, but module support is disabled.
[error] To enable module support, set scalaJSModuleKind := ModuleKind.CommonJSModule.
[error] Total time: 6 s, completed 10.01.2017 13:06:11

Evaluate using ScalaJS-React

ScalaJS-React is already pretty complete, and I think it'd be great if there weren't yet another way to write Scala.js + React. Is it possible to use ScalaJS-React instead of rolling your own facade?

remove sComponentX overrides from RectComponent

Currently in ReactComponent we have override methods for componentWillUpdate,shouldComponentUpdate componentDidUpdate, componentWillReceiveProps just to get scala props/state from wrapper JSProps/JSState

 class ReactComponent extends .. {
   @JSName("sComponentWillUpdate")
  def componentWillUpdate(nextProps: P, nextState: S): Unit = ()

  @JSName("componentWillUpdate")
  override def jsComponentWillUpdate(nextProps: Props,
                                     nextState: State): Unit = {
    componentWillUpdate(nextProps.sprops, nextState.sstate)
  }

  @JSName("sShouldComponentUpdate")
  def shouldComponentUpdate(nextProps: P, nextState: S): Boolean = true

  @JSName("shouldComponentUpdate")
  override def jsShouldComponentUpdate(nextProps: Props,
                                       nextState: State): Boolean = {
    shouldComponentUpdate(nextProps.sprops, nextState.sstate)
  }

  @JSName("sComponentDidUpdate")
  def componentDidUpdate(prevProps: P, prevState: S): Unit = ()

  @JSName("componentDidUpdate")
  override def jsComponentDidUpdate(prevProps: Props, prevState: State): Unit = {
    componentDidUpdate(prevProps.sprops, prevState.sstate)
  }

  @JSName("sComponentWillReceiveProps")
  def componentWillReceiveProps(nextProps: P): Unit = ()

  @JSName("componentWillReceiveProps")
  override def jsComponentWillReceiveProps(nextProps: Props): Unit = {
    componentWillReceiveProps(nextProps.sprops)
  }

}

When ever a component updated via setState they will be called. even though implementation is just unit () we still paying method call! and user component should annotate method with @JSName("sShouldComponentUpdate"), etc how about removing this overrides ?

Current User Component with overrides of sComponetX

class HeaderComponent extends ReactComponent {

    @JSName("sShouldComponentUpdate")
  override def shouldComponentUpdate(nextProps: P,
                                       nextState: S): Boolean = {
   (nexProps ne props) && (nextState ne state)
  }

}

New after removing overrides from ReactComponent

class HeaderComponent extends ReactComponent {

  override def shouldComponentUpdate(nextJSProps: JSProps[P],
                                       nextJSState: JSState[S]): Boolean = {
 (nextJSProps.sprops ne props) && (nextJSState.sstate ne state)
  }

this way we can eliminate extra method calls , and no JSName annotations required, but user should call .sprops/.sstate when they need scala props/state.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

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

  • D3 photo D3

    Data-Driven Documents codes.