Chat data property binding implemented

This commit is contained in:
Rohan Sircar 2020-05-20 10:46:48 +05:30
parent 1221a95c72
commit 8402c2f59e
5 changed files with 170 additions and 31 deletions

View File

@ -26,10 +26,11 @@
<children> <children>
<BorderPane prefHeight="41.0" prefWidth="620.0"> <BorderPane prefHeight="41.0" prefWidth="620.0">
<center> <center>
<HBox alignment="CENTER"> <HBox alignment="CENTER" spacing="5.0">
<children> <children>
<Label id="curUser" fx:id="curUsr" text="User1" /> <Label id="currentUser" fx:id="curUsr" text="User1" />
<Label id="content" fx:id="dataContent" text="User2" /> <Label id="lastActive" fx:id="dataContent" text="User2" />
<Label id="online" text="User2" />
</children> </children>
</HBox> </HBox>
</center> </center>

View File

@ -24,6 +24,9 @@ import org.scalafx.extras._
import wow.doge.chatto.service.UserService import wow.doge.chatto.service.UserService
import javax.inject._ import javax.inject._
import javafx.application.Platform import javafx.application.Platform
import com.sfxcode.sapphire.core.controller.SceneControllerDidChangeEvent
import javax.enterprise.event.Observes
import com.sfxcode.sapphire.core.controller.SceneControllerWillChangeEvent
@Named @Named
@ApplicationScoped @ApplicationScoped
class ApplicationController extends DefaultWindowController { class ApplicationController extends DefaultWindowController {
@ -62,6 +65,16 @@ class ApplicationController extends DefaultWindowController {
replaceSceneContent(newMainViewController) replaceSceneContent(newMainViewController)
} }
def testListener(@Observes event: SceneControllerWillChangeEvent) = {
logger.info("test success 1")
// logger.info(s"${event.newController}")
}
def testListener2(@Observes event: SceneControllerDidChangeEvent) = {
logger.info("test success 2")
// logger.info(s"${event.newController}")
}
override def applicationWillStop(): Unit = async { override def applicationWillStop(): Unit = async {
super.applicationWillStop() super.applicationWillStop()
println("stopping") println("stopping")

View File

@ -3,9 +3,12 @@ package wow.doge.chatto.control
import javafx.scene.layout.HBox import javafx.scene.layout.HBox
import javafx.scene.control.Label import javafx.scene.control.Label
import scalafx.Includes._ import scalafx.Includes._
import wow.doge.chatto.controller.ChatData
import com.sfxcode.sapphire.core.value.FXBean
class UserBox2(_username: String) extends HBox() { class UserBox2(val username: String, val chatData: ChatData) extends HBox() {
val usernameLabel = new Label(_username) val usernameLabel = new Label(username)
// lazy val chatDataBean = FXBean[ChatData](chatData)
this.children ++= Seq { this.children ++= Seq {
usernameLabel usernameLabel
} }

View File

@ -33,13 +33,20 @@ import com.sfxcode.sapphire.core.value.FXBeanAdapter
import scalafx.collections.ObservableMap import scalafx.collections.ObservableMap
import com.sfxcode.sapphire.core.value.BeanConversions import com.sfxcode.sapphire.core.value.BeanConversions
import javafx.util.converter.DateStringConverter import javafx.util.converter.DateStringConverter
import javafx.beans.binding.Bindings
import wow.doge.chatto.service.ActiveUser
import scala.collection.mutable
import scala.collection.concurrent.TrieMap
import wow.doge.chatto.messagebuble.BubbleSpec
import javafx.scene.layout.Background
import javafx.scene.layout.BackgroundFill
import javafx.geometry.Pos
class ChatController @Inject() ( class ChatController @Inject() (
userService: UserService, userService: UserService,
appDataHandler: AppDataHandler appDataHandler: AppDataHandler
) extends AbstractViewController ) extends AbstractViewController
with LazyLogging with LazyLogging {
with BeanConversions {
// @FXML private var label: Label = _ // @FXML private var label: Label = _
@FXML private var flowPane: FlowPane = _ @FXML private var flowPane: FlowPane = _
@ -49,16 +56,21 @@ class ChatController @Inject() (
@FXML private var chatInput: TextArea = _ @FXML private var chatInput: TextArea = _
@FXML private var usersVBox: VBox = _ @FXML private var usersVBox: VBox = _
@FXML var usersListView: JFXListView[UserBox2] = _ @FXML var usersListView: JFXListView[UserBox2] = _
@FXML private var chatListView: JFXListView[HBox] = _ @FXML var chatListView: JFXListView[HBox] = _
@FXML private var curUsr: Label = _ @FXML private var curUsr: Label = _
@FXML private var dataContent: Label = _ @FXML private var dataContent: Label = _
// applicationController.show // applicationController.show
private val usersBuffer = ObservableBuffer[FXBean[User]]() private val usersListProperty = new SimpleListProperty(
private val chatDataBuffer = ObservableMap[String, FXBean[User]]() ObservableBuffer[UserBox2]()
)
private val chatDataBuffer = ObservableBuffer[UserBox2]()
private val chatDataStore: mutable.Map[String, ChatDataProperty] =
TrieMap()
private lazy val curUserKeys = KeyBindings("curUser") // private lazy val curUserKeys = KeyBindings("curUser")
// bindings.add("person", "Person ${_self.name()} with age of ${_self.age()} is active: ${_self.isActive()}") // bindings.add("person", "Person ${_self.name()} with age of ${_self.age()} is active: ${_self.isActive()}")
private lazy val curUserAdapter = FXBeanAdapter[User](this) // private lazy val curUserAdapter = FXBeanAdapter[User](this)
private lazy val chatDataAdapter = FXBeanAdapter[ChatData](this)
override def didGainVisibilityFirstTime(): Unit = { override def didGainVisibilityFirstTime(): Unit = {
super.didGainVisibilityFirstTime() super.didGainVisibilityFirstTime()
@ -99,28 +111,53 @@ class ChatController @Inject() (
// .addListener((_, _, newValue) => { // .addListener((_, _, newValue) => {
// curUsr.text() = newValue.usernameLabel.text() // curUsr.text() = newValue.usernameLabel.text()
// }) // })
curUserKeys.add("content", "${_self.data().content()}") // curUserKeys.add("content", "${_self.data().content()}")
val chatDataAdapterKeys = KeyBindings()
// chatDataAdapterKeys.add("currentUser", "${_self.userName()}")
// chatDataAdapterKeys.add(
// "lastActive",
// "${_self.lastActiveString()}"
// )
// chatDataAdapterKeys.add(
// "online",
// "${_self.onlineString()}"
// )
// curUserAdapter.addDateConverter() // curUserAdapter.addDateConverter()
curUserAdapter.addBindings(curUserKeys) // curUserAdapter.addBindings(curUserKeys)
chatDataAdapter.addBindings(chatDataAdapterKeys)
// curUsr.text <== chatDataAdapter.beanProperty
// .getOrElse(FXBean(ChatData.empty))
// .getStringProperty("lastActiveString")
usersListView usersListView
.getSelectionModel() .getSelectionModel()
.selectedItemProperty() .selectedItemProperty()
.addListener((_, _, newValue) => { .addListener((_, _, newValue) => {
if (newValue != null) { if (newValue != null) {
val dataBean = // val dataBean =
FXBean(User(newValue.usernameLabel.text(), Data("test data"))) // FXBean(User(newValue.usernameLabel.text(), Data("test data")))
curUserAdapter // curUserAdapter
.set(dataBean) // .set(dataBean)
// chatDataAdapter.set(newValue.chatDataBean)
val y = chatDataStore
.get(newValue.username)
val x = y
.map(_.bean)
.getOrElse {
logger.error("Error null")
FXBean(ChatData.empty)
}
chatDataAdapter.set(x)
y.map(z => chatListView.items <== z.prop)
} }
}) })
// curUsr.text <== usersListView // curUsr.text <== usersListView
// .getSelectionModel() // .getSelectionModel()
// .getSelectedItem() // .getSelectedItem()
// .username // .usernameLabel
// .text // .text
usersListView.items <== usersListProperty
} }
override def didGainVisibility(): Unit = { override def didGainVisibility(): Unit = {
@ -140,7 +177,7 @@ class ChatController @Inject() (
// maybeActiveUsers.foreach(println) // maybeActiveUsers.foreach(println)
logger.debug(s"$maybeActiveUsers") logger.debug(s"$maybeActiveUsers")
val maybeUsersBoxes = maybeUsers.map(users => { val maybeUserBoxes = maybeActiveUsers.map(users => {
// usersBuffer ++= users // usersBuffer ++= users
users.map(user => { users.map(user => {
// usersBuffer += FXBean(User(user)) // usersBuffer += FXBean(User(user))
@ -152,7 +189,21 @@ class ChatController @Inject() (
// fill <== when(hover) choose (Color.Red) // fill <== when(hover) choose (Color.Red)
// } // }
// val hb = new HBox // val hb = new HBox
new UserBox2(user) { val chatData =
ChatData(user.userName, user, ObservableBuffer.empty[String])
// chatDataStore.updateWith(user.userName)(maybeCD =>
// maybeCD.map(cd => {
// cd.messagesStringProperty +=
// })
// )
chatDataStore.put(user.userName, new ChatDataProperty(chatData))
chatDataStore
.get(user.userName)
.map(cdp => {
cdp.prop ++= Seq("hi", "hello", "bye")
.map(s => ChatDataProperty.createMdMessageBox(s))
})
new UserBox2(user.userName, chatData) {
// this.children += new Label { // this.children += new Label {
// textProperty() = user // textProperty() = user
// // textFillProperty <== when(this.hover) choose (Color.RED) otherwise (Color.BLUE) // // textFillProperty <== when(this.hover) choose (Color.RED) otherwise (Color.BLUE)
@ -161,12 +212,22 @@ class ChatController @Inject() (
} }
}) })
}) })
// maybeUserBoxes.map(userBoxes => {
// // chatDataBuffer ++= userBoxes
// usersListProperty ++= userBoxes
// })
val messageBox = ChatDataProperty.createMdMessageBox("*hello!*")
onFX { onFX {
maybeUsersBoxes.map(userBoxes => { // maybeUserBoxes.map(userBoxes => {
usersListView.items() ++= userBoxes // chatDataBuffer ++= userBoxes
// val x = new SimpleListProperty(ObservableBuffer(userBoxes)) // // usersListView.items() ++= userBoxes
// usersListView.items <== x // // val x = new SimpleListProperty(ObservableBuffer(userBoxes))
// // usersListView.items <== x
// })
maybeUserBoxes.map(userBoxes => {
usersListProperty ++= userBoxes
}) })
chatListView.items() += messageBox
} }
} }
} }
@ -177,17 +238,26 @@ class ChatController @Inject() (
x x
} }
def actionLogout = { def actionLogout = onFX {
offFXAndWait { offFXAndWait {
appDataHandler.clearCredentials() appDataHandler.clearCredentials()
println(appDataHandler.appData) println(appDataHandler.appData)
} }
curUserAdapter.set(User.empty) // curUserAdapter.set(User.empty)
chatDataAdapter.set(FXBean(ChatData.empty))
usersListView.items().clear() usersListView.items().clear()
chatListView.items().clear() chatListView.items().clear()
chatDataBuffer.clear()
chatDataStore.clear()
usersListProperty.clear()
applicationController.logout() applicationController.logout()
println(appDataHandler.appData) println(appDataHandler.appData)
} }
}
object ChatController {
lazy val markdownStyleSheet =
getClass().getResource("/styles/markdown.css").toExternalForm()
} }
final case class Person(id: Int, age: Int, name: String) final case class Person(id: Int, age: Int, name: String)
@ -195,5 +265,58 @@ final case class Data(content: String)
final case class User(curUser: String, data: Data) final case class User(curUser: String, data: Data)
object User { object User {
def empty = User("", Data("")) def empty = User("", Data(""))
// Bindings.createObjectBinding()
}
// final case class ActiveUser(
// userName: String,
// online: Boolean,
// lastActive: String
// )
// object ActiveUser {
// def empty = ActiveUser("empty", false, "empty")
// }
final case class ChatData(
userName: String,
activeUser: ActiveUser,
messages: ObservableBuffer[String]
) {
lazy val lastActiveString =
activeUser.lastActive
.map(_.toString())
.getOrElse("User has not logged in yet")
lazy val onlineString = activeUser.online.toString()
}
object ChatData {
def empty = {
ChatData("empty", ActiveUser.empty, ObservableBuffer.empty[String])
}
}
class ChatDataProperty(chatData: ChatData) {
import ChatDataProperty._
val bean = FXBean(chatData)
val usernameProperty = bean.getStringProperty("userName")
val isActiveProperty = bean.getBooleanProperty("activeUser.online")
val lastActiveProperty = bean.getStringProperty("lastActiveString")
val messagesStringProperty = new SimpleListProperty(chatData.messages)
val prop = new SimpleListProperty(ObservableBuffer.empty[HBox])
// val x = messagesStringProperty.map(message => createMdMessageBox(message))
// prop <== messagesStringProperty.map(message => createMdMessageBox(message))
// prop <== new SimpleListProperty(x)
}
object ChatDataProperty {
def createMdMessageBox(mdfxText: String) = {
val mdfxNode = new BubbledMDFXNode(mdfxText);
mdfxNode
.getStylesheets()
.add(ChatController.markdownStyleSheet);
mdfxNode.setBubbleSpec(BubbleSpec.FACE_RIGHT_CENTER);
mdfxNode.setBackground(
new Background(new BackgroundFill(Color.LIGHTSTEELBLUE, null, null))
);
val box = new HBox();
mdfxNode.setMinWidth(100.0);
box.setAlignment(Pos.TOP_RIGHT);
box.children += mdfxNode;
box
}
} }
// final case class chatData()

View File

@ -97,6 +97,5 @@ final case class ActiveUser(
) )
object ActiveUser { object ActiveUser {
val z = ZonedDateTime.now() def empty = ActiveUser("empty", false, None)
z.toInstant().toString()
} }