diff --git a/ChatUIClass.php b/ChatUIClass.php deleted file mode 100644 index 75be514..0000000 --- a/ChatUIClass.php +++ /dev/null @@ -1,109 +0,0 @@ - $roleVal) - { - $tempCast = []; - $tempArray = explode(":",$roleVal); - list($name, ,$img) = $tempArray; - $tempCast['name'] = $name; - $tempCast['img'] = $img; - array_push($chat['roles'],$tempCast); - } - // structure lines - $linesArray = array_values(array_filter(explode(PHP_EOL,$linesData))); - foreach($linesArray as $lineKey => $lineVal) - { - if($lineVal != '---') - { - $chat['dialog'] = $chat['dialog'] + 1; - $tempLine = []; - $tempArray = explode(":",$lineVal); - list($name, $sentence) = $tempArray; - $tempLine['name'] = $name; - $tempLine['sentence'] = $sentence; - array_push($chat['lines'],$tempLine); - } - } - // var_dump($chat); - $this->dialogue = $chat; - } - public function read(){ - $tempHtml = ''; - foreach($this->dialogue['lines'] as $dialogue) - { - switch($dialogue['name']) - { - case 'Narator': - $tempHtml .= $this->role_narator($dialogue); - break; - case $this->dialogue['roles'][0]['name']: - $tempHtml .= $this->role_rightSide($dialogue); - break; - default: - $tempHtml .= $this->role_leftSide($dialogue); - break; - } - } - return $tempHtml; - } - private function role_narator($dialogue) - { - $tempHtml = '

'.$dialogue['sentence'].'

'; - return $tempHtml; - } - private function role_leftSide($dialogue) - { - $tempHtml = '
'; - $tempHtml .= '
'; - $tempHtml .= ''.$dialogue['name']; - $tempHtml .= '
'; - $tempHtml .= '

'.$dialogue['sentence'].'

'; - $tempHtml .= '
'; - return $tempHtml; - } - private function role_rightSide($dialogue) - { - $tempHtml = '
'; - $tempHtml .= '
'; - $tempHtml .= $dialogue['name'].''; - $tempHtml .= '
'; - $tempHtml .= '

'.$dialogue['sentence'].'

'; - $tempHtml .= '
'; - return $tempHtml; - } - private function loadChatHeaderImg($castName) - { - foreach($this->dialogue['roles'] as $cast) - { - if($cast['name'] == $castName) - { - return $cast['img']; - } - } - } -} // EOF -?> \ No newline at end of file diff --git a/README.md b/README.md index 235f29f..77452a1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -# PHP Chat UI -PHP Class for simulate conversation dialog. - +# PHP Chat Block +A dialogue chat block display component for php project. A UI component for conversational novel community. - +Date: 30 Aug, 2021 Author: Tang Hoong # Screenshot @@ -10,7 +9,7 @@ Author: Tang Hoong ![](sample-02.png "sample") # Description -Just dump the string format which same as sample.txt then ChatUIClass will render them perfect and nice. +Just dump the string format which exactly same as sample.txt then ChatBlock will render them into perfect and nice chat blocks. # How Follow the format from sample.txt: @@ -22,10 +21,10 @@ Snake: Wanna eat apple 苹果 🍎🍎🍎? ``` then ``` -include 'ChatUIClass.php'; -$sample = file_get_contents('./sample.txt'); -$dialogue = new ChatUI($sample); -echo $dialogue->read(); +include 'ChatBlock.php'; +$lines = file_get_contents('./chapter-1.txt'); +$cb = new ChatBlock($lines); +echo $cb->read(); ``` become diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e6f6eb1 --- /dev/null +++ b/composer.json @@ -0,0 +1,15 @@ +{ + "name": "tanghoong/php-chat-block", + "description": "an dialogue chat block display component for php project", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Tang Hoong", + "email": "tanghoong.com@gmail.com" + } + ], + "require": { + "php": ">=7.1" + } +} \ No newline at end of file diff --git a/index.php b/demo.php similarity index 79% rename from index.php rename to demo.php index 8f91950..d9355aa 100644 --- a/index.php +++ b/demo.php @@ -1,6 +1,9 @@ @@ -20,10 +23,10 @@
-

Text Soap

+

打赏宣言#1

read(); + $cb = new ChatUI($sample); + echo $cb->read(); ?>
diff --git a/imessage.css b/imessage.css index afc68b2..4c50b58 100644 --- a/imessage.css +++ b/imessage.css @@ -203,4 +203,68 @@ } .imessage .chat-name-them{ text-align: left; +} + +.imessage .text-center{ + text-align: center; +} + +.imessage .text-bold{ + font-weight: bold; +} + +.imessage .text-muted{ + font-size: 12px; + margin: 5px; +} + +.container-image{ + padding: 30px; +} + +.container-image img{ + border-radius: 1.15rem; +} +.container-mp3{ + display: flex; + flex-direction: column; + align-items: center; + color: #000; + border-radius: 1.15rem; + line-height: 1.25; + padding: 0.5rem .875rem; + position: relative; + word-wrap: break-word; + font-size: 12px; + margin: 5px; +} +.container-youtube{ + height: 300px; + width: 400px; + margin: 0px auto; +} +.container-youtube iframe{ + border-radius: 1.15rem; +} +.container-decision{ + display: flex; + justify-content: space-between; +} + +.container-decision .decision-option{ + cursor: pointer; + background-color: #e5e5ea; + color: #000; + border-radius: 1.15rem; + line-height: 1.25; + padding: 0.5rem .875rem; + margin: 0 auto 1rem; + position: relative; + word-wrap: break-word; + text-align: center; +} + +.container-decision .decision-option:focus, +.container-decision .decision-option:hover{ + background-color: #bdbdbe; } \ No newline at end of file diff --git a/old/chat-ui.css b/old/chat-ui.css new file mode 100644 index 0000000..25c0ac3 --- /dev/null +++ b/old/chat-ui.css @@ -0,0 +1,62 @@ +#chatUI{ + padding: 10px; + background-color: white; +} + +#chatUI .chat-header{ + border-radius: 30px; + width: 20px; + height: 20px; + margin: 3px; +} + +#chatUI .chat-container{ + white-space: pre-wrap; + border-radius: 5px; + margin: 10px; + padding: 5px; +} + +#chatUI .chat-container-me{ + background-color: #d5fdf0; + margin-left: 40%; +} + +#chatUI .chat-container-them{ + background-color: #2db688; + margin-right: 40%; +} + +#chatUI .chat-container .chat-name{ + font-weight: bold; + display: flex; + align-items: center; +} +#chatUI .chat-container .chat-name-me{ + text-align: right; + justify-content: flex-end; +} +#chatUI .chat-container .chat-name-them{ + text-align: left; +} + +#chatUI .chat-container .chat-block{ + margin: 5px 0px; +} +#chatUI .chat-container .chat-block-me{ + text-align: right; +} +#chatUI .chat-container .chat-block-them{ + text-align: left; +} + +#chatUI .chat-block-system{ + text-align: center; + white-space: pre-wrap; + margin-left: 20%; + margin-right: 20%; + background-color: #cccccc; + padding: 10px; + border-radius: 5px; + margin-bottom: 10px; +} diff --git a/sample.txt b/sample.txt index 39d0d7e..3a18e54 100644 --- a/sample.txt +++ b/sample.txt @@ -1,16 +1,27 @@ -Adam: https://i.imgur.com/pW71NE5.jpeg -Eve: https://i.imgur.com/Jvh1OQm.jpeg -Snake: https://i.imgur.com/FEiFVeO.png +Adam: //i.imgur.com/pW71NE5.jpeg?color=red +Eve: //i.imgur.com/Jvh1OQm.jpeg?color=blue +Snake: //i.imgur.com/FEiFVeO.png?color=green --- +Background: //filesamples.com/samples/audio/mp3/sample3.mp3 Narator: Once upon a time... Snake: Wanna eat apple 苹果 🍎🍎🍎? Eve: Ya sure, why not? why not? why not? why not? why not? why not? why not? why not? why not? why not? why not? Narator: Eve took the apple and bite. Adam: Dont! Dont! Dont! Dont! Dont! Dont! Dont! Dont! Dont! Snake: It is too late! hahaha! -Narator: Thats why human have been cast away away away away away away away away away away away away away. -Narator: Thats why human have been cast away. -Narator: Thats why human have been cast away. -Narator: Thats why human have been cast away. -Narator: Thats why human have been cast away. -Narator: end of the story.FIN.👍 \ No newline at end of file +Tiger: It is too late! hahaha! +Dog: It is too late! hahaha! +Cat: It is too late! hahaha! +Narator: Thats why human have been cast away away away away away away away away away away away away away. +Narator: Thats why human have been cast away. +Narator: Thats why human Here have been cast away. +Narator: Thats why human
have been cast away. + +Narator: end of the story.FIN.👍 + + +Image: //i.imgur.com/pW71NE5.jpeg?color=red +MP3: //filesamples.com/samples/audio/mp3/sample3.mp3 +Youtube: //www.youtube.com/embed/tgbNymZ7vqY?controls=0 +Decision: 左边,中间,右边,上面,下面 + diff --git a/src/ChatBlock.php b/src/ChatBlock.php new file mode 100644 index 0000000..a998b87 --- /dev/null +++ b/src/ChatBlock.php @@ -0,0 +1,205 @@ + $roleVal) + { + $tempCast = []; + $tempArray = explode(":",$roleVal); + list($name, $img) = $tempArray; + $tempCast['name'] = $name; + $tempCast['img'] = $img; + array_push($chat['roles'],$tempCast); + } + // structure lines + $linesArray = array_values(array_filter(explode(PHP_EOL,$linesData))); + foreach($linesArray as $lineKey => $lineVal) + { + if($lineVal != '---') + { + $chat['dialog'] = $chat['dialog'] + 1; + $tempLine = []; + $tempArray = explode(":",$lineVal); + list($name, $sentence) = $tempArray; + $tempLine['name'] = $name; + $tempLine['sentence'] = $sentence; + array_push($chat['lines'],$tempLine); + } + } + $this->dialogue = $chat; + } + /** + * To allow using as Json format for frontend rendering + */ + public function json(){ + return json_encode($this->dialogue); + } + /** + * Using default html rendered chat blocks + */ + public function read(){ + $tempHtml = ''; + foreach($this->dialogue['lines'] as $dialogue) + { + switch($dialogue['name']) + { + case 'Narator': + $tempHtml .= $this->role_narator($dialogue); + break; + case 'Image': + $tempHtml .= $this->render_image_holder($dialogue); + break; + case 'MP3': + case 'Background': + $tempHtml .= $this->render_sound_holder($dialogue); + break; + case 'Youtube': + $tempHtml .= $this->render_video_holder($dialogue); + break; + case 'Decision': + $tempHtml .= $this->render_decisions_holder($dialogue); + break; + case $this->dialogue['roles'][0]['name']: + $tempHtml .= $this->role_rightSide($dialogue); + break; + default: + $tempHtml .= $this->role_leftSide($dialogue); + break; + } + } + return $tempHtml; + } + // Multimedia + private function render_image_holder($dialogue) + { + $link = $this->fn_valid_link($dialogue['sentence']); + $tempHtml = '
'; + $tempHtml .= 'Image'; + $tempHtml .= '
'; + return $tempHtml; + } + private function render_sound_holder($dialogue) + { + $link = $this->fn_valid_link($dialogue['sentence']); + $tempHtml = '
'; + $tempHtml .= ''; + if($dialogue['name'] == 'Background') + { + $tempHtml .= '
Background Music
'; + } + $tempHtml .= '
'; + return $tempHtml; + } + private function render_video_holder($dialogue) + { + $link = $this->fn_valid_link($dialogue['sentence']); + $tempHtml = '
'; + $tempHtml .= ''; + $tempHtml .= '
'; + return $tempHtml; + } + private function render_decisions_holder($dialogue) + { + $optionList = explode(',',$dialogue['sentence']); + $tempHtml = '

Your decisions are

'; + $tempHtml .= '
'; + foreach($optionList as $option) + { + $tempHtml .= '
'.$option.'
'; + } + $tempHtml .= '
'; + return $tempHtml; + } + // Misc + private function fn_filter($dialogue) + { + $newStr = strip_tags($dialogue,""); + return trim($newStr); + } + private function fn_valid_link($dialogue) + { + return $dialogue; + // $url = filter_var($dialogue, FILTER_SANITIZE_URL); + // if (filter_var($url, FILTER_VALIDATE_URL)) { + // return $url; + // } + // return false; + } + // Chat Blocks + private function role_narator($dialogue) + { + $sentence = $this->fn_filter($dialogue['sentence']); + $tempHtml = '

'.$sentence.'

'; + return $tempHtml; + } + private function role_leftSide($dialogue) + { + $sentence = $this->fn_filter($dialogue['sentence']); + $tempHtml = '
'; + $tempHtml .= '
'; + $chatHeaderImg = $this->loadChatHeaderImg($dialogue['name']); + if($chatHeaderImg == false) + { + $tempHtml .= $dialogue['name']; + }else{ + $tempHtml .= ''.$dialogue['name']; + } + $tempHtml .= '
'; + $tempHtml .= '

'.$sentence.'

'; + $tempHtml .= '
'; + return $tempHtml; + } + private function role_rightSide($dialogue) + { + $sentence = $this->fn_filter($dialogue['sentence']); + $tempHtml = '
'; + $tempHtml .= '
'; + $chatHeaderImg = $this->loadChatHeaderImg($dialogue['name']); + if($chatHeaderImg == false) + { + $tempHtml .= $dialogue['name']; + }else{ + $tempHtml .= ''.$dialogue['name']; + } + $tempHtml .= '
'; + $tempHtml .= '

'.$sentence.'

'; + $tempHtml .= '
'; + return $tempHtml; + } + private function loadChatHeaderImg($castName) + { + foreach($this->dialogue['roles'] as $cast) + { + if($cast['name'] == $castName) + { + return $cast['img']; + } + } + return false; // If not match + } +} // EOF +?> \ No newline at end of file