mirror of https://github.com/Wilfred/difftastic/
217 lines
5.7 KiB
Kotlin
217 lines
5.7 KiB
Kotlin
/*
|
|
* Copyright 2018 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.samples.apps.iosched.model
|
|
|
|
import com.google.samples.apps.iosched.model.SessionType.Companion.reservableTypes
|
|
import org.threeten.bp.ZonedDateTime
|
|
|
|
typealias SessionId = String
|
|
|
|
/**
|
|
* Describes a conference session. Sessions have specific start and end times, and they represent a
|
|
* variety of conference events: talks, sandbox demos, office hours, etc. A session is usually
|
|
* associated with one or more [Tag]s.
|
|
*/
|
|
data class Session(
|
|
/**
|
|
* Unique string identifying this session.
|
|
*/
|
|
val id: SessionId,
|
|
|
|
/**
|
|
* Start time of the session
|
|
*/
|
|
val startTime: ZonedDateTime,
|
|
|
|
/**
|
|
* End time of the session
|
|
*/
|
|
val endTime: ZonedDateTime,
|
|
|
|
/**
|
|
* Session title.
|
|
*/
|
|
val title: String,
|
|
|
|
/**
|
|
* Body of text explaining this session in detail.
|
|
*/
|
|
val description: String,
|
|
|
|
/**
|
|
* The session room.
|
|
*/
|
|
val room: Room?,
|
|
|
|
/**
|
|
* Full URL for the session online.
|
|
*/
|
|
val sessionUrl: String,
|
|
|
|
/**
|
|
* Indicates if the Session has a live stream.
|
|
*/
|
|
val isLivestream: Boolean,
|
|
|
|
/**
|
|
* Full URL to YouTube.
|
|
*/
|
|
val youTubeUrl: String,
|
|
|
|
/**
|
|
* URL to the Dory page.
|
|
*/
|
|
val doryLink: String,
|
|
|
|
/**
|
|
* The [Tag]s associated with the session. Ordered, with the most important tags appearing
|
|
* first.
|
|
*/
|
|
val tags: List<Tag>,
|
|
|
|
/**
|
|
* Subset of [Tag]s that are for visual consumption.
|
|
*/
|
|
val displayTags: List<Tag>,
|
|
|
|
/**
|
|
* The session speakers.
|
|
*/
|
|
val speakers: Set<Speaker>,
|
|
|
|
/**
|
|
* The session's photo URL.
|
|
*/
|
|
val photoUrl: String,
|
|
|
|
/**
|
|
* IDs of the sessions related to this session.
|
|
*/
|
|
val relatedSessions: Set<SessionId>
|
|
) {
|
|
|
|
/**
|
|
* Returns whether the session is currently being live streamed or not.
|
|
*/
|
|
fun isLive(): Boolean {
|
|
val now = ZonedDateTime.now()
|
|
// TODO: Determine when a session is live based on the time AND the liveStream being
|
|
// available.
|
|
return startTime <= now && endTime >= now
|
|
}
|
|
|
|
val hasPhoto inline get() = photoUrl.isNotEmpty()
|
|
|
|
/**
|
|
* Returns whether the session has a video or not. A session could be live streaming or have a
|
|
* recorded session. Both live stream and recorded videos are stored in [Session.youTubeUrl].
|
|
*/
|
|
val hasVideo inline get() = youTubeUrl.isNotEmpty()
|
|
|
|
val hasPhotoOrVideo inline get() = hasPhoto || hasVideo
|
|
|
|
/**
|
|
* The year the session was held.
|
|
*/
|
|
val year = startTime.year
|
|
|
|
/**
|
|
* The duration of the session.
|
|
*/
|
|
// TODO: Get duration from the YouTube video. Not every talk fills the full session time.
|
|
val duration = endTime.toInstant().toEpochMilli() - startTime.toInstant().toEpochMilli()
|
|
|
|
/**
|
|
* The type of the event e.g. Session, Codelab etc.
|
|
*/
|
|
val type: SessionType by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
SessionType.fromTags(tags)
|
|
}
|
|
|
|
fun levelTag(): Tag? {
|
|
return tags.firstOrNull { it.category == Tag.CATEGORY_LEVEL }
|
|
}
|
|
|
|
/**
|
|
* Whether this event is reservable, based upon [type].
|
|
*/
|
|
val isReservable: Boolean by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
type in reservableTypes
|
|
}
|
|
|
|
fun isOverlapping(session: Session): Boolean {
|
|
return this.startTime < session.endTime && this.endTime > session.startTime
|
|
}
|
|
|
|
/**
|
|
* Detailed description of this event. Includes description, speakers, and live-streaming URL.
|
|
*/
|
|
fun getCalendarDescription(
|
|
paragraphDelimiter: String,
|
|
speakerDelimiter: String
|
|
): String = buildString {
|
|
append(description)
|
|
append(paragraphDelimiter)
|
|
append(speakers.joinToString(speakerDelimiter) { speaker -> speaker.name })
|
|
if (!isLivestream && !youTubeUrl.isEmpty()) {
|
|
append(paragraphDelimiter)
|
|
append(youTubeUrl)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Represents the type of the event e.g. Session, Codelab etc.
|
|
*/
|
|
enum class SessionType(val displayName: String) {
|
|
|
|
KEYNOTE("Keynote"),
|
|
SESSION("Session"),
|
|
APP_REVIEW("App Reviews"),
|
|
GAME_REVIEW("Game Reviews"),
|
|
OFFICE_HOURS("Office Hours"),
|
|
CODELAB("Codelab"),
|
|
MEETUP("Meetup"),
|
|
AFTER_DARK("After Dark"),
|
|
UNKNOWN("Unknown");
|
|
|
|
companion object {
|
|
|
|
/**
|
|
* Examine the given [tags] to determine the [SessionType]. Defaults to [SESSION] if no
|
|
* category tag is found.
|
|
*/
|
|
fun fromTags(tags: List<Tag>): SessionType {
|
|
val typeTag = tags.firstOrNull { it.category == Tag.CATEGORY_TYPE }
|
|
|
|
return when (typeTag?.tagName) {
|
|
Tag.TYPE_KEYNOTE -> KEYNOTE
|
|
Tag.TYPE_SESSIONS -> SESSION
|
|
Tag.TYPE_APP_REVIEWS -> APP_REVIEW
|
|
Tag.TYPE_GAME_REVIEWS -> GAME_REVIEW
|
|
Tag.TYPE_OFFICEHOURS -> OFFICE_HOURS
|
|
Tag.TYPE_CODELABS -> CODELAB
|
|
Tag.TYPE_MEETUPS -> MEETUP
|
|
Tag.TYPE_AFTERDARK -> AFTER_DARK
|
|
else -> UNKNOWN
|
|
}
|
|
}
|
|
|
|
internal val reservableTypes = listOf(SESSION, OFFICE_HOURS, APP_REVIEW, GAME_REVIEW)
|
|
}
|
|
}
|