diff --git a/lib/src/components/containers/lecture_container/lecture_container.dart b/lib/src/components/containers/lecture_container/lecture_container.dart index a16ac6f..0a02101 100644 --- a/lib/src/components/containers/lecture_container/lecture_container.dart +++ b/lib/src/components/containers/lecture_container/lecture_container.dart @@ -73,6 +73,8 @@ class LectureContainerComponent extends StatefulComponent implements OnInit, OnD String get title => !lecture.section.isCustom ? 'Доклад' : 'Событие'; + String getFigure(int number) => '#figure-${number}'; + String get endTime => _selectors.getEndTimeText(lecture); bool get isAuthorized => _selectors.isAuthorized(state); diff --git a/lib/src/components/containers/lecture_container/lecture_container.html b/lib/src/components/containers/lecture_container/lecture_container.html index 0d1efcd..8fb1907 100644 --- a/lib/src/components/containers/lecture_container/lecture_container.html +++ b/lib/src/components/containers/lecture_container/lecture_container.html @@ -42,6 +42,19 @@ content class="event"> +
+ +
+ diff --git a/lib/src/components/containers/lecture_container/lecture_container.scss b/lib/src/components/containers/lecture_container/lecture_container.scss index 27f1f2d..e7d3b06 100644 --- a/lib/src/components/containers/lecture_container/lecture_container.scss +++ b/lib/src/components/containers/lecture_container/lecture_container.scss @@ -21,6 +21,21 @@ // event --- + .event__hero { + height: 176px; + margin-bottom: 24px; + position: relative; + + svg { + display: block; + width: 176px; + position: absolute; + top: 0; + right: 0; + pointer-events: none; + } + } + .event__meta { color: $fg-color-secondary; margin-bottom: 4px; diff --git a/lib/src/components/containers/lecture_talk/lecture_talk.dart b/lib/src/components/containers/lecture_talk/lecture_talk.dart index d7c09a0..cfadaa5 100644 --- a/lib/src/components/containers/lecture_talk/lecture_talk.dart +++ b/lib/src/components/containers/lecture_talk/lecture_talk.dart @@ -32,7 +32,6 @@ class LectureTalkComponent extends StatefulComponent { final Dispatcher _dispatcher; @HostBinding('class.messages') final bool isHostMarked = true; - bool get canCreatePost => _authStore.isAuth; @ViewChild('input') TalkPostInputComponent input; diff --git a/lib/src/components/containers/lecture_talk/lecture_talk.html b/lib/src/components/containers/lecture_talk/lecture_talk.html index 6c5fe02..7e3c18c 100644 --- a/lib/src/components/containers/lecture_talk/lecture_talk.html +++ b/lib/src/components/containers/lecture_talk/lecture_talk.html @@ -8,7 +8,6 @@ diff --git a/lib/src/components/containers/lecture_talk/lecture_talk.scss b/lib/src/components/containers/lecture_talk/lecture_talk.scss index 7e60b2b..133d569 100644 --- a/lib/src/components/containers/lecture_talk/lecture_talk.scss +++ b/lib/src/components/containers/lecture_talk/lecture_talk.scss @@ -16,4 +16,9 @@ bottom: 0; background-image: linear-gradient(to bottom, rgba(242, 243, 250, 0), #f2f3fa5e 24%, #f2f3fa); } +} + +:host-context(html.event) +.messages__container-input { + background: none; } \ No newline at end of file diff --git a/lib/src/components/containers/lectures_container/lectures_container.html b/lib/src/components/containers/lectures_container/lectures_container.html index 5f46f2b..217ed66 100644 --- a/lib/src/components/containers/lectures_container/lectures_container.html +++ b/lib/src/components/containers/lectures_container/lectures_container.html @@ -1,126 +1,6 @@ -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
_selectors.isReady(state); + + void onLectureSelect(Lecture lecture) { + final url = RoutePaths.lecture.toUrl( + parameters: {idParam: lecture.id}, + ); + + _router.navigate(url); + } } diff --git a/lib/src/components/containers/rating_container/rating_container.html b/lib/src/components/containers/rating_container/rating_container.html index 5e38e31..8c53a54 100644 --- a/lib/src/components/containers/rating_container/rating_container.html +++ b/lib/src/components/containers/rating_container/rating_container.html @@ -1,18 +1,53 @@ - + + -
+
+ + + + + {{ lecture.location.title }} + + + &ngsp;•&ngsp; + + + + {{ lecture.section.title }} + + + - - -
- + + +
+
+
\ No newline at end of file diff --git a/lib/src/components/containers/rating_container/rating_container.scss b/lib/src/components/containers/rating_container/rating_container.scss new file mode 100644 index 0000000..959054f --- /dev/null +++ b/lib/src/components/containers/rating_container/rating_container.scss @@ -0,0 +1,25 @@ +@import "../../../../../web/assets/styles/variables.scss"; + +:host { + .like-count { + flex-shrink: 0; + margin-left: -8px; + margin-right: 16px; + width: 5ch; + padding-top: 16px; + color: $fg-color-primary; + @include font-title; + + .icon { + color: $fg-color-secondary; + vertical-align: top; + transform: translate(0, -3px); + } + } + + .events__list { + display: grid; + grid-gap: 8px; + margin: 12px 0; + } +} \ No newline at end of file diff --git a/lib/src/components/containers/release_notes_container/release_notes_container.dart b/lib/src/components/containers/release_notes_container/release_notes_container.dart index 111fc0e..f93d806 100644 --- a/lib/src/components/containers/release_notes_container/release_notes_container.dart +++ b/lib/src/components/containers/release_notes_container/release_notes_container.dart @@ -1,5 +1,6 @@ import 'package:angular/angular.dart'; import 'package:codefest/src/components/ui/event_card/event_card.dart'; +import 'package:codefest/src/components/ui/event_card/event_time/event_time.dart'; import 'package:codefest/src/models/release.dart'; import 'package:codefest/src/models/speaker.dart'; import 'package:codefest/src/services/releases_factory.dart'; @@ -10,7 +11,8 @@ import 'package:codefest/src/services/releases_factory.dart'; templateUrl: 'release_notes_container.html', directives: [ NgFor, - EventCardComponent + EventCardComponent, + EventTimeComponent, ], preserveWhitespace: true, changeDetection: ChangeDetectionStrategy.OnPush, @@ -18,11 +20,13 @@ import 'package:codefest/src/services/releases_factory.dart'; class ReleaseNotesContainerComponent { final Iterable releases = ReleasesFactory.all; - Speaker createSpeaker(Release release) => Speaker( - id: "", - description: "", - name: release.author, - company: release.company, - avatarPath: release.avatar, - ); + List createSpeakers(Release release) => [ + Speaker( + id: "", + description: "", + name: release.author, + company: release.company, + avatarPath: release.avatar, + ) + ]; } diff --git a/lib/src/components/containers/release_notes_container/release_notes_container.html b/lib/src/components/containers/release_notes_container/release_notes_container.html index 6fa42c5..2b350b2 100644 --- a/lib/src/components/containers/release_notes_container/release_notes_container.html +++ b/lib/src/components/containers/release_notes_container/release_notes_container.html @@ -1,8 +1,11 @@ - + side> + + \ No newline at end of file diff --git a/lib/src/components/containers/release_notes_container/release_notes_container.scss b/lib/src/components/containers/release_notes_container/release_notes_container.scss index 1b8c67c..1038a3f 100644 --- a/lib/src/components/containers/release_notes_container/release_notes_container.scss +++ b/lib/src/components/containers/release_notes_container/release_notes_container.scss @@ -1,12 +1,5 @@ :host { - ::ng-deep .event { - margin-right: -16px; - - article { - width: 100%; - } - } - ::ng-deep .event + .event { - margin-top: 8px; - } + display: grid; + grid-gap: 8px; + margin: 8px 0 16px; } diff --git a/lib/src/components/ui/button/button.dart b/lib/src/components/ui/button/button.dart index cd99cfb..7ab5d5e 100644 --- a/lib/src/components/ui/button/button.dart +++ b/lib/src/components/ui/button/button.dart @@ -1,3 +1,5 @@ +import 'dart:html'; + import 'package:angular/angular.dart'; @Component( @@ -8,6 +10,10 @@ import 'package:angular/angular.dart'; preserveWhitespace: false, ) class ButtonComponent { + final Element nativeElement; + @HostBinding('class.button') final bool isHostMarked = true; + + ButtonComponent(this.nativeElement); } diff --git a/lib/src/components/ui/event_card/event_card.dart b/lib/src/components/ui/event_card/event_card.dart index 2d97d03..093c5d6 100644 --- a/lib/src/components/ui/event_card/event_card.dart +++ b/lib/src/components/ui/event_card/event_card.dart @@ -1,3 +1,6 @@ +import 'dart:async'; +import 'dart:html'; + import 'package:angular/angular.dart'; import 'package:codefest/src/models/speaker.dart'; @@ -6,12 +9,16 @@ import 'package:codefest/src/models/speaker.dart'; templateUrl: 'event_card.html', styleUrls: const ['event_card.css'], directives: [ + NgFor, NgIf, + NgIf ], changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespace: false, ) class EventCardComponent { + final _onClickStreamController = StreamController.broadcast(); + @Input() String title; @@ -22,15 +29,29 @@ class EventCardComponent { String endTime; bool get hasEndTime => endTime != null; + bool get isTimeShown => false; @Input() String description; @Input() - Speaker speaker; + List speakers = const []; + + @Input() + @HostBinding('class.stand-out') + bool standOut = false; + + @Input() + bool clickable = false; + + @Output() + Stream get onClick => _onClickStreamController.stream; - void onClick() {} + bool get sameCompany => speakers.fold>(new Set(), (prev, next) => + prev..add(next.company) + ).length == 1; - @HostBinding('class.event') - final bool isHostMarked = true; + void onClickHandler(MouseEvent event) { + _onClickStreamController.add(event); + } } diff --git a/lib/src/components/ui/event_card/event_card.html b/lib/src/components/ui/event_card/event_card.html index 1dce2f5..086ede9 100644 --- a/lib/src/components/ui/event_card/event_card.html +++ b/lib/src/components/ui/event_card/event_card.html @@ -1,25 +1,13 @@ - - -
- - - - - - -
+ + + -
+
@@ -36,34 +24,91 @@ [innerHTML]="description">
- -
- - -
- - - - - - -
+ +
- -
+ - {{ speaker.company }} + +
+ +
+
\ No newline at end of file diff --git a/lib/src/components/ui/event_card/event_card.scss b/lib/src/components/ui/event_card/event_card.scss index de0e05a..49443c8 100644 --- a/lib/src/components/ui/event_card/event_card.scss +++ b/lib/src/components/ui/event_card/event_card.scss @@ -1,67 +1,31 @@ @import "../../../../../web/assets/styles/variables.scss"; @import "../../../styles/common.scss"; +:host(.stand-out) { + margin: 0 -24px; + padding: 0 8px 0px 24px; +} + :host { display: flex; - - .event__time { - flex-shrink: 0; - margin-right: 16px; - width: 5ch; - padding-top: 16px; - color: $fg-color-secondary; - position: relative; - - &::before { - content: ""; - display: block; - width: 2px; - position: absolute; - top: 0; - bottom: 0; - left: -22px; - background-image: repeating-radial-gradient(circle, #b9bac1 0px, #b9bac1 1px, transparent 1px, transparent 100%); - background-size: 2px 14px; - background-position-y: -10px; - background-position-x: 0px; - background-repeat: repeat-y; - } - } - - .event__time-item { - display: block; - - + .event__time-item { - margin-top: 4px; - } - - &.event__time-item--start { - font-weight: $font-weight-bold; - position: relative; - - &::before { - content: ""; - display: block; - background: #94959b; - width: 16px; - height: 2px; - position: absolute; - top: 8px; - left: -22px; - } - } - } - + .event-card { padding: 16px 24px 16px 16px; // todo position: relative; // for actions border-radius: 6px; // todo background-color: #ffffff; // todo box-shadow: 0 2px 23px 0 rgba(0, 0, 0, 0.06); // todo + flex-grow: 1; + + &.event-card--clickable { + cursor: pointer; + } } + .event-card__title { @include font-title; } + .event-card__description { ::ng-deep h3 { @include font-main; diff --git a/lib/src/components/ui/event_card/event_time/event_time.dart b/lib/src/components/ui/event_card/event_time/event_time.dart new file mode 100644 index 0000000..3c0e42c --- /dev/null +++ b/lib/src/components/ui/event_card/event_time/event_time.dart @@ -0,0 +1,23 @@ +import 'package:angular/angular.dart'; + +@Component( + selector: 'event-time', + templateUrl: 'event_time.html', + styleUrls: const ['event_time.css'], + directives: [ + NgFor, + NgIf, + NgIf + ], + changeDetection: ChangeDetectionStrategy.OnPush, + preserveWhitespace: false, +) +class EventTimeComponent { + @Input() + String startTime; + + @Input() + String endTime; + + bool get hasEndTime => endTime != null; +} diff --git a/lib/src/components/ui/event_card/event_time/event_time.html b/lib/src/components/ui/event_card/event_time/event_time.html new file mode 100644 index 0000000..566cfd0 --- /dev/null +++ b/lib/src/components/ui/event_card/event_time/event_time.html @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/lib/src/components/ui/event_card/event_time/event_time.scss b/lib/src/components/ui/event_card/event_time/event_time.scss new file mode 100644 index 0000000..7d45b71 --- /dev/null +++ b/lib/src/components/ui/event_card/event_time/event_time.scss @@ -0,0 +1,53 @@ +@import "../../../../../../web/assets/styles/variables.scss"; + +:host { + flex-shrink: 0; + margin-right: 16px; + width: 5ch; + padding-top: 16px; + color: $fg-color-secondary; + position: relative; + + :empty { + display: none; + } + + &::before { + content: ""; + display: block; + width: 2px; + position: absolute; + top: 0; + bottom: 0; + left: -22px; + background-image: repeating-radial-gradient(circle, #b9bac1 0px, #b9bac1 1px, transparent 1px, transparent 100%); + background-size: 2px 14px; + background-position-y: -10px; + background-position-x: 0px; + background-repeat: repeat-y; + } + + .item { + display: block; + + + .item { + margin-top: 4px; + } + + &.item--start { + font-weight: $font-weight-bold; + position: relative; + + &::before { + content: ""; + display: block; + background: #94959b; + width: 16px; + height: 2px; + position: absolute; + top: 8px; + left: -22px; + } + } + } +} \ No newline at end of file diff --git a/lib/src/components/ui/talk_post_input/talk_post_input_component.dart b/lib/src/components/ui/talk_post_input/talk_post_input_component.dart index 32d8166..ce331c1 100644 --- a/lib/src/components/ui/talk_post_input/talk_post_input_component.dart +++ b/lib/src/components/ui/talk_post_input/talk_post_input_component.dart @@ -2,7 +2,10 @@ import 'dart:async'; import 'dart:html'; import 'package:angular/angular.dart'; import 'package:angular_forms/angular_forms.dart'; +import 'package:angular_router/angular_router.dart'; import 'package:codefest/src/components/ui/button/button.dart'; +import 'package:codefest/src/route_paths.dart'; +import 'package:codefest/src/services/auth_store.dart'; @Component( selector: 'talk-post-input', @@ -18,6 +21,9 @@ import 'package:codefest/src/components/ui/button/button.dart'; preserveWhitespace: false, ) class TalkPostInputComponent { + final AuthStore _authStore; + final Router _router; + bool get isAllowToSend => newPostText.length > 1 && newPostText.length <= 255; final _onSend = new StreamController(); @@ -27,11 +33,18 @@ class TalkPostInputComponent { @ViewChild('input') InputElement input; + @ViewChild('loginButton') + ButtonComponent loginButton; + @Output() Stream get onSend => _onSend.stream; String newPostText = ''; + bool get canCreatePost => _authStore.isAuth; + + TalkPostInputComponent(this._authStore, this._router); + void send() { if (isAllowToSend) { _onSend.add(newPostText); @@ -40,7 +53,11 @@ class TalkPostInputComponent { } void focus() { - input.focus(); + if (canCreatePost) input.focus(); + else loginButton.nativeElement.focus(); } + void onLoginButtonClick() { + _router.navigateByUrl(RoutePaths.login.toUrl()); + } } diff --git a/lib/src/components/ui/talk_post_input/talk_post_input_component.html b/lib/src/components/ui/talk_post_input/talk_post_input_component.html index cdef7ab..792c4f3 100644 --- a/lib/src/components/ui/talk_post_input/talk_post_input_component.html +++ b/lib/src/components/ui/talk_post_input/talk_post_input_component.html @@ -1,4 +1,18 @@ + + +
>> _getGroupedByDay(List> lectures) { + return _groupBy(lectures, (last, next) { + return last.last.startTime.day == next.last.startTime.day; + }); + } + List>> _getGroupedVisibleLectures(Iterable lectures) { final groupedByTime = _groupBy(lectures.toList(), (last, next) { return last.startTime == next.startTime && last.duration == next.duration; }); - final groupedByDay = _groupBy(groupedByTime, (last, next) { - return last.last.startTime.day == next.last.startTime.day; - }); - - return groupedByDay; + return _getGroupedByDay(groupedByTime); } Iterable _getLectureFullSearchFields(Lecture lecture) => [lecture.title, lecture.description] @@ -212,7 +214,7 @@ class Selectors { } Iterable _getRatingSortedLectures(Iterable lectures) => - lectures.where((lecture) => lecture.likesCount > 3).toList() + lectures.where((lecture) => lecture.likesCount > 0).toList() ..sort((lecture1, lecture2) => lecture1.likesCount < lecture2.likesCount ? 1 : -1); Iterable
_getSelectedSections(Iterable
sections, Iterable sectionIds) => diff --git a/lib/src/route_paths.dart b/lib/src/route_paths.dart index 35d3ad8..7844e5e 100644 --- a/lib/src/route_paths.dart +++ b/lib/src/route_paths.dart @@ -23,7 +23,7 @@ class RoutePaths { static final List _menu = [ lectures, -// rating, + rating, map, what, login, diff --git a/lib/src/services/releases_factory.dart b/lib/src/services/releases_factory.dart index 578c31e..a37381d 100644 --- a/lib/src/services/releases_factory.dart +++ b/lib/src/services/releases_factory.dart @@ -5,35 +5,47 @@ const WRIKE_AUTHOR = 'Wrike dream team'; class ReleasesFactory { static List get all => [ + Release( + version: '1.2.0', + author: WRIKE_AUTHOR, + avatar: WRIKE_AVATAR, + title: 'Обший рейтинг докладов', + description: + 'Добавили страницу с лучшими докладами на CodeFest по мнению посетителей конференции. ' + 'Голосуйте за доклады, которые вам понравились, а Wrike наградит докладчика, ' + 'набравшего наибольшее количество голосов!' + ), Release( version: '1.1.0', author: WRIKE_AUTHOR, avatar: WRIKE_AVATAR, title: 'Обсуждения докладов для CodeFest X', - description: 'Добавили возможность обсуждения докладов! Не смогли пообщаться со спикером в экспетной зоне - можете сделать это у нас.', + description: + 'Добавили возможность обсуждения докладов!' + 'Не смогли пообщаться со спикером в экспетной зоне - можете сделать это у нас.', + ), + Release( + version: '1.0.1', + author: 'Алексей Дорохов', + avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0UlCZ8gU8Pl4XeFVuYOVUyFWnvY3oc04UD2hkEx1TwmW5egBe', + title: 'Индикатор популярности доклада', + description: '

Что мы приготовили:

' + '
    ' + '
  • Теперь в расписании есть индикатор популярности доклада.
  • ' + '
', + ), + Release( + version: '1.0.0', + author: WRIKE_AUTHOR, + avatar: WRIKE_AVATAR, + title: 'MVP расписания для CodeFest X', + description: '

Что мы приготовили:

' + '
    ' + '
  • Программа Codefest X, адаптированная под мобилки.
  • ' + '
  • События вне основной программы: партнерские активности, стихийные лекции и воркшопы.
  • ' + '
  • Возможность создать своё расписание. Мы напомним об избранных событиях, чтобы вы не пропустили их.
  • ' + '
  • Лайки для интересных докладов, лучшие из которых мы наградим.
  • ' + '
', ), - Release( - version: '1.0.1', - author: 'Алексей Дорохов', - avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0UlCZ8gU8Pl4XeFVuYOVUyFWnvY3oc04UD2hkEx1TwmW5egBe', - title: 'Индикатор популярности доклада', - description: '

Что мы приготовили:

' - '
    ' - '
  • Теперь в расписании есть индикатор популярности доклада.
  • ' - '
', - ), - Release( - version: '1.0.0', - author: WRIKE_AUTHOR, - avatar: WRIKE_AVATAR, - title: 'MVP расписания для CodeFest X', - description: '

Что мы приготовили:

' - '
    ' - '
  • Программа Codefest X, адаптированная под мобилки.
  • ' - '
  • События вне основной программы: партнерские активности, стихийные лекции и воркшопы.
  • ' - '
  • Возможность создать своё расписание. Мы напомним об избранных событиях, чтобы вы не пропустили их.
  • ' - '
  • Лайки для интересных докладов, лучшие из которых мы наградим.
  • ' - '
', - ), - ]; + ]; } diff --git a/web/index.html b/web/index.html index 0bca912..8081761 100644 --- a/web/index.html +++ b/web/index.html @@ -33,5 +33,121 @@ Loading... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +