hw 15 - garevna/js-course GitHub Wiki
Напилить код класса ClimaticZones,
экземпляры которого имеют собственное свойство region,
и наследуют неперечислимое свойство climates следующего содержания:
{
"Экваториальные области Африки": "Экваториальный",
"Экваториальные области Южной Америки": "Экваториальный",
"Экваториальные области Океании": "Экваториальный",
"Южная и Юго-Восточная Азия": "Тропический муссонный",
"Западная и Центральная Африка": "Тропический муссонный",
"Северная Австралия": "Тропический муссонный",
"Северная Африка": "Тропический сухой",
"Центральная Австралия": "Тропический сухой",
"Средиземноморье": "Средиземноморский",
"Южный берег Крыма": "Средиземноморский",
"Южная Африка": "Средиземноморский",
"Юго-Западная Австралия": "Средиземноморский",
"Западная Калифорния": "Средиземноморский",
"Западные части Евразии": "Умеренный морской",
"Западные части Северной Америки": "Умеренный морской",
"Внутренние части материков": "Умеренный континентальный",
"Восточная окраина Евразии": "Умеренный муссонный",
"Северные окраины Евразии": "Субарктический",
"Северные окраины Северной Америки": "Субарктический",
"Акватория Северного Ледовитого океана": "Арктический"
}Собственное свойство region может принимать одно из значений, перечисленных в унаследованном свойстве climates
Унаследованный метод getClimate() должен возвращать климат для региона, который указан в значении свойства region
Заверните в оболочку класса свой чатик на json-server
Соберите приложение
Запустите json-server
Откройте index.html в нескольких вкладках
В одной вкладке задаете вопрос
В другой вкладке отвечаете
Вопросы приведены в конце
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>REST API samples</title>
<meta name="description" content="JSON server: Simple chat"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="chat/a-level-ico.png" type="image/x-icon">
<link rel="stylesheet" href="chat/main.css">
</head>
<body>
<script src = "chat/index.js"></script>
</body>
</html>* {
font-family: Roboto, monospace, Arial;
}
.inputMessage {
position: fixed;
bottom: 20px;
left: 3%;
right: 3%;
height:70px;
width: 95%;
border: inset 1px;
padding: 5px 10px;
overflow: auto;
}
.chatContainer {
position: fixed;
top: 3%;
bottom: 100px;
left: 3%;
right: 3%;
border: inset 1px;
padding: 10px 20px;
overflow: auto;
}
sup {
font-size: 9px;
position: absolute;
right: 20px;
color: #888;
}
.ico {
margin-right: 10px;
}class SimpleChat {
constructor () {
if ( this.constructor.instance ) {
console.warn ( "It's a singleton. You can't create one more instance of this class" )
return null
}
window.addEventListener( "unload", function ( event ) {
SimpleChat.closeChat ()
})
this.constructor.instance = this
this.users = null
this.currentUser = null
this.getAllData ()
this.chatContainer = this.addElement ( "section" )
this.chatContainer.id = "chatContainer"
this.chatContainer.className = "chatContainer"
this.chatContainer.addEventListener ( "updated", this.updateChat.bind ( this ) )
this.inputMessage = this.addElement ( "input" )
this.inputMessage.className = "inputMessage"
this.inputMessage.onchange = function ( event ) {
fetch ( "http://localhost:3000/messages", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify ({
user: this.currentUser.id,
date: new Date().toLocaleString(),
body: event.target.value
})
})
fetch ( "http://localhost:3000/lastUpdate", {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify ({
date: new Date().toLocaleString()
})
})
event.target.value = ""
}.bind ( this )
this.interval = setInterval (
function() {
document.querySelector ( "section#chatContainer" )
.dispatchEvent ( new Event ( "updated" ))
},
500
)
}
addElement ( tagName, container ) {
return ( container && container.nodeType === 1 ?
container : document.body )
.appendChild (
document.createElement ( tagName )
)
}
getData ( ref ) {
return fetch ( `http://localhost:3000/${ref}` )
.then ( response => response.json() )
}
createUserAvatar ( user ) {
return fetch( `https://api.github.com/users/${user.id}` )
.then ( response => response.json()
.then ( response => {
let img = new Image ( 40 )
img.src = response.avatar_url
img.className = "ico"
return img
})
)
}
async updateChat () {
let updated = await this.getData ( "lastUpdate" )
if ( updated.date === this.lastUpdate.date || !this.users ) return
this.lastUpdate.date = updated.date
this.messages = await this.getData ( "messages" )
this.initChat()
}
async getAllData () {
this.lastUpdate = await this.getData ( "lastUpdate" )
let users = await this.getData ( "users" )
this.currentUser = users.filter ( user => !user.active )[0]
if ( this.currentUser ) {
this.currentUser.active = true
fetch ( `http://localhost:3000/users/${this.currentUser.id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify ( this.currentUser )
})
}
async function mutateUser ( user, callback ) {
return Object.assign ( {},
{ [ user.id ]: await callback ( user ) }
)
}
let lim = users.length
let k = 0
while ( k++ < lim ) {
users.push (
await mutateUser ( users.shift(), this.createUserAvatar )
)
}
this.users = Object.assign ( {}, ...users )
this.messages = await this.getData ( "messages" )
this.initChat ()
}
initChat () {
this.chatContainer.innerHTML = ""
this.messages.forEach (
message => {
let mess = this.addElement ( "div", this.chatContainer )
mess.appendChild ( this.users [ message.user ] )
this.addElement ( "span", mess ).innerText = message.user
this.addElement ( "span", mess ).innerHTML = `<sup>${message.date}</sup>`
this.addElement ( "p", mess ).innerText = message.body
}, this
)
this.chatContainer.scrollTop = this.chatContainer.offsetHeight
}
static closeChat () {
this.instance.currentUser.active = false
fetch ( `http://localhost:3000/users/${this.instance.currentUser.id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify ( this.instance.currentUser )
})
}
}
Object.defineProperty (
SimpleChat.prototype,
"messages",
{
enumerable: false,
writable: true,
value: []
}
)
const chat = new SimpleChat
const oneMoreChat = new SimpleChat{
"lastUpdate": {
"date": "15.03.2019, 12:03:10"
},
"users": [
{
"id": "jvantuyl",
"active": false
},
{
"id": "BrianTheCoder",
"active": false
},
{
"id": "freeformz",
"active": false
},
{
"id": "hassox",
"active": false
},
{
"id": "automatthew",
"active": false
},
{
"id": "mojombo",
"active": false
},
{
"id": "defunkt",
"active": false
},
{
"id": "queso",
"active": false
},
{
"id": "lancecarlson",
"active": false
},
{
"id": "lukesutton",
"active": false
},
{
"id": "garevna",
"active": false
}
],
"messages": [
{
"id": 1,
"date": "05.02.2019, 10:18:32",
"user": "mojombo",
"body": "Hello everybody here! What do you prefer: static or dynamic import?"
},
{
"id": 2,
"date": "05.02.2019, 10:19:11",
"user": "hassox",
"body": "The static import syntax can only be used at the top-level of the file"
},
{
"id": 3,
"user": "BrianTheCoder",
"date": "05.02.2019, 10:22:15",
"body": "Dynamic import() introduces a new function-like form of import that caters to those use cases"
},
{
"id": 4,
"date": "05.02.2019, 11:10:18",
"user": "defunkt",
"body": "Since import() returns a promise, it's possible to use async/await instead of the then-based callback style"
},
{
"id": 5,
"date": "07.02.2019, 18:34:12",
"user": "queso",
"body": "Although import() looks like a function call, it is specified as syntax that just happens to use parentheses"
},
{
"id": 6,
"date": "07.02.2019, 18:38:05",
"user": "lancecarlson",
"body": "The lazy-loading capabilities enabled by dynamic import() can be quite powerful when applied correctly"
},
{
"id": 7,
"date": "13.03.2019, 10:21:20",
"user": "lukesutton",
"body": "Static import and dynamic import() are both useful"
},
{
"id": 8,
"date": "13.03.2019, 11:14:33",
"user": "garevna",
"body": "ws-json-server adds a little abstraction to websocket"
}
]
}- Что делает функция mutateUser ?
- Что возвращает метод createUserAvatar ?
- Что происходит при вводе сообщения ?
- Можно ли создать в одной вкладке более одного экземпляра класса SimpleChat ?
- Откуда берутся аватарки пользователей чата ?
- Совпадает ли структура данных о юзерах чата на клиенте со структорой данных в базе на сервере ?
- Как определяется логин нового пользователя чата при подключении ?
- Что делает метод closeChat и когда он вызывается ?
.
Homework
Required
Additionally