Browse Source

Chat data property binding implemented

master
Rohan Sircar 4 years ago
parent
commit
8402c2f59e
  1. 7
      src/main/resources/fxml/Chat.fxml
  2. 13
      src/main/scala/wow/doge/chatto/ApplicationController.scala
  3. 7
      src/main/scala/wow/doge/chatto/control/UserBox2.scala
  4. 171
      src/main/scala/wow/doge/chatto/controller/ChatController.scala
  5. 3
      src/main/scala/wow/doge/chatto/service/UserService.scala

7
src/main/resources/fxml/Chat.fxml

@ -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="content" fx:id="dataContent" text="User2" />
<Label id="currentUser" fx:id="curUsr" text="User1" />
<Label id="lastActive" fx:id="dataContent" text="User2" />
<Label id="online" text="User2" />
</children> </children>
</HBox> </HBox>
</center> </center>

13
src/main/scala/wow/doge/chatto/ApplicationController.scala

@ -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")

7
src/main/scala/wow/doge/chatto/control/UserBox2.scala

@ -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() {
val usernameLabel = new Label(_username)
class UserBox2(val username: String, val chatData: ChatData) extends HBox() {
val usernameLabel = new Label(username)
// lazy val chatDataBean = FXBean[ChatData](chatData)
this.children ++= Seq { this.children ++= Seq {
usernameLabel usernameLabel
} }

171
src/main/scala/wow/doge/chatto/controller/ChatController.scala

@ -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 BeanConversions {
with LazyLogging {
// @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 chatDataBuffer = ObservableMap[String, FXBean[User]]()
private val usersListProperty = new SimpleListProperty(
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 =
FXBean(User(newValue.usernameLabel.text(), Data("test data")))
curUserAdapter
.set(dataBean)
// val dataBean =
// FXBean(User(newValue.usernameLabel.text(), Data("test data")))
// curUserAdapter
// .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 => {
usersListView.items() ++= userBoxes
// val x = new SimpleListProperty(ObservableBuffer(userBoxes))
// usersListView.items <== x
// maybeUserBoxes.map(userBoxes => {
// chatDataBuffer ++= userBoxes
// // usersListView.items() ++= userBoxes
// // 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()

3
src/main/scala/wow/doge/chatto/service/UserService.scala

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