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>
<BorderPane prefHeight="41.0" prefWidth="620.0">
<center>
<HBox alignment="CENTER">
<HBox alignment="CENTER" spacing="5.0">
<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>
</HBox>
</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 javax.inject._
import javafx.application.Platform
import com.sfxcode.sapphire.core.controller.SceneControllerDidChangeEvent
import javax.enterprise.event.Observes
import com.sfxcode.sapphire.core.controller.SceneControllerWillChangeEvent
@Named
@ApplicationScoped
class ApplicationController extends DefaultWindowController {
@ -62,6 +65,16 @@ class ApplicationController extends DefaultWindowController {
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 {
super.applicationWillStop()
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.control.Label
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 {
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 com.sfxcode.sapphire.core.value.BeanConversions
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() (
userService: UserService,
appDataHandler: AppDataHandler
) extends AbstractViewController
with LazyLogging
with BeanConversions {
with LazyLogging {
// @FXML private var label: Label = _
@FXML private var flowPane: FlowPane = _
@ -49,16 +56,21 @@ class ChatController @Inject() (
@FXML private var chatInput: TextArea = _
@FXML private var usersVBox: VBox = _
@FXML var usersListView: JFXListView[UserBox2] = _
@FXML private var chatListView: JFXListView[HBox] = _
@FXML var chatListView: JFXListView[HBox] = _
@FXML private var curUsr: Label = _
@FXML private var dataContent: Label = _
// 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()}")
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 = {
super.didGainVisibilityFirstTime()
@ -99,28 +111,53 @@ class ChatController @Inject() (
// .addListener((_, _, newValue) => {
// 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.addBindings(curUserKeys)
// curUserAdapter.addBindings(curUserKeys)
chatDataAdapter.addBindings(chatDataAdapterKeys)
// curUsr.text <== chatDataAdapter.beanProperty
// .getOrElse(FXBean(ChatData.empty))
// .getStringProperty("lastActiveString")
usersListView
.getSelectionModel()
.selectedItemProperty()
.addListener((_, _, newValue) => {
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
// .getSelectionModel()
// .getSelectedItem()
// .username
// .usernameLabel
// .text
usersListView.items <== usersListProperty
}
override def didGainVisibility(): Unit = {
@ -140,7 +177,7 @@ class ChatController @Inject() (
// maybeActiveUsers.foreach(println)
logger.debug(s"$maybeActiveUsers")
val maybeUsersBoxes = maybeUsers.map(users => {
val maybeUserBoxes = maybeActiveUsers.map(users => {
// usersBuffer ++= users
users.map(user => {
// usersBuffer += FXBean(User(user))
@ -152,7 +189,21 @@ class ChatController @Inject() (
// fill <== when(hover) choose (Color.Red)
// }
// 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 {
// textProperty() = user
// // 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 {
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
}
def actionLogout = {
def actionLogout = onFX {
offFXAndWait {
appDataHandler.clearCredentials()
println(appDataHandler.appData)
}
curUserAdapter.set(User.empty)
// curUserAdapter.set(User.empty)
chatDataAdapter.set(FXBean(ChatData.empty))
usersListView.items().clear()
chatListView.items().clear()
chatDataBuffer.clear()
chatDataStore.clear()
usersListProperty.clear()
applicationController.logout()
println(appDataHandler.appData)
}
}
object ChatController {
lazy val markdownStyleSheet =
getClass().getResource("/styles/markdown.css").toExternalForm()
}
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)
object User {
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 {
val z = ZonedDateTime.now()
z.toInstant().toString()
def empty = ActiveUser("empty", false, None)
}
Loading…
Cancel
Save