sitemap.xml works with articles

This commit is contained in:
tmshv committed 2017-05-26 19:57:55 +03:00
1 parent f2d26a510d
commit 96c966e427
66 files changed
+3 -1836

No files matched your search

-21
View File
@@ -1,21 +0,0 @@
import APITimeline from './APITimeline';
import APIAlbum from './APIAlbum';
import APIDocument from './APIDocument';
import APITeacher from './APITeacher';
import APISchedule from './APISchedule';
import APIEvent from './APIEvent';
import APIArticle from './APIArticle';
import APIPage from './APIPage';
export default class API {
constructor(request) {
this.timeline = new APITimeline(request);
this.album = new APIAlbum(request);
this.document = new APIDocument(request);
this.teacher = new APITeacher(request);
this.schedule = new APISchedule(request);
this.event = new APIEvent(request);
this.article = new APIArticle(request);
this.page = new APIPage(request);
}
}
-16
View File
@@ -1,16 +0,0 @@
import EndPoint from './EndPoint';
export default class APIAlbum extends EndPoint {
list(){
return this.get(`/gallery`);
}
year(year) {
return this.get(`/gallery/${year}`);
}
fetch(id, doPopulate) {
let url = `/album/${id}?populate=${doPopulate}`;
return this.get(url);
}
}
-8
View File
@@ -1,8 +0,0 @@
import EndPoint from './EndPoint';
export default class APIArticle extends EndPoint {
id(id) {
let url = `/article/${id}`;
return this.get(url);
}
}
-9
View File
@@ -1,9 +0,0 @@
import EndPoint from './EndPoint';
export default class APICollective extends EndPoint {
list(sort=null) {
let url = '/collective';
if(sort) url = `/collective?sort=${sort.join(',')}`;
return this.get(url);
}
}
-18
View File
@@ -1,18 +0,0 @@
import EndPoint from './EndPoint';
export default class APIDocument extends EndPoint {
documents(){
let url = '/documents/type/document';
return this.get(url);
}
awards() {
let url = '/documents/type/award';
return this.get(url);
}
id(id){
let url = `/documents/${id}`;
return this.get(url);
}
}
-11
View File
@@ -1,11 +0,0 @@
import EndPoint from './EndPoint';
export default class APIEvent extends EndPoint {
list(page = 1) {
let limit = 5;
let skip = (page - 1) * limit;
let url = `/events?skip=${skip}&limit=${limit}`;
return this.get(url);
}
}
-12
View File
@@ -1,12 +0,0 @@
import EndPoint from './EndPoint';
export default class APIGallery extends EndPoint {
year(year) {
return this.get(`/gallery/${year}`);
}
album(year, course, album, doPopulate) {
let url = `/gallery/${year}/${course}/${album}?populate=${doPopulate}`;
return this.get(url);
}
}
-7
View File
@@ -1,7 +0,0 @@
import EndPoint from './EndPoint';
export default class APIPage extends EndPoint {
url(url) {
return this.get(url);
}
}
-17
View File
@@ -1,17 +0,0 @@
import EndPoint from './EndPoint';
export default class APISchedule extends EndPoint {
static buildScheduleUrl(period, semester) {
return `/schedule/${period}/${semester}`;
}
fetch(period, semester, doPopulate=true) {
let url = `/schedule/${period}/${semester}?populate=${doPopulate}`;
return this.get(url);
}
list() {
let url = '/schedule/list';
return this.get(url);
}
}
-14
View File
@@ -1,14 +0,0 @@
import EndPoint from './EndPoint';
export default class APITeacher extends EndPoint {
list(sort=null) {
let url = '/teacher/list';
if(sort) url = `/teacher/list?sort=${sort.join(',')}`;
return this.get(url);
}
fetch(id) {
let url = `/teacher/${id}`;
return this.get(url);
}
}
-9
View File
@@ -1,9 +0,0 @@
import {query} from '../../utils/net';
import EndPoint from './EndPoint';
export default class APITimeline extends EndPoint{
feed(limit=10, skip=0) {
let q = query([['limit', limit], ['skip', skip]]);
return this.get(`/news?${q}`);
}
}
-9
View File
@@ -1,9 +0,0 @@
export default class EndPoint{
constructor(http){
this.request = http;
}
get(url){
return this.request.get(url, {cache: true});
}
}
-193
View File
@@ -1,193 +0,0 @@
import {getInitialData} from './core/init'
import Navigation from './components/Navigation'
import MainMenu from './components/MainMenu'
import Breadcrumbs from './components/Breadcrumbs'
import Document from './components/Document'
import Award from './components/Award'
import GalleryItem from './components/GalleryItem'
import AlbumCollection from './components/AlbumCollection'
import TeacherProfile from './components/TeacherProfile'
import Timeline from './components/Timeline'
import TimelineRecord from './components/TimelineRecord'
import TimelineRecordInstagram from './components/TimelineRecordInstagram'
import Schedule from './components/Schedule'
import ScheduleTable from './components/ScheduleTable'
import ScheduleSlider from './components/ScheduleSlider'
import ScheduleSlide from './components/ScheduleSlide'
import ScheduleRecord from './components/ScheduleRecord'
import FooterLinks from './components/FooterLinks'
import Article from './components/Article'
import ArticlePageControl from './components/ArticlePageControl'
import Album from './components/Album'
import Parallax from './components/Parallax'
import ThemeSelector from './components/ThemeSelector'
import AccessibilityControl from './components/AccessibilityControl'
import Page from './components/CloudPage'
import PageSchool from './components/PageSchool'
import PageEvents from './components/PageEvents'
import PageArticle from './components/PageArticle'
import PageSchedule from './components/PageSchedule'
import PageCollective from './components/PageCollective'
import PageTeacher from './components/PageTeacher'
import PageGallery from './components/PageGallery'
import PageAlbum from './components/PageAlbum'
import PageDocuments from './components/PageDocuments'
import PageAwards from './components/PageAwards'
import PageDocument from './components/PageDocument'
import AppController from './controllers/AppController'
import CopyrightController from './controllers/CopyrightController'
import ContactsController from './controllers/ContactsController'
import RemoveHashtags from './filters/RemoveHashtags'
import RemoveNewline from './filters/RemoveNewline'
import Strip from './filters/Strip'
import Join from './filters/Join'
import UppercaseFirst from './filters/UppercaseFirst'
import Bytes from './filters/Bytes'
import Ext from './filters/Ext'
import IOService from './services/io'
import MenuService from './services/menu'
import API from './services/api'
import Theme from './services/theme'
import {sortByPattern} from '../utils/sort'
import {documentsSortPattern} from './config'
let app = angular.module('hudozka', [
'ngRoute',
'angulartics',
'angulartics.google.analytics',
'angularSpinner'
])
app.config(($locationProvider, $routeProvider) => {
$locationProvider.hashPrefix('!')
$locationProvider.html5Mode(true)
const pages = getInitialData().pages
.map(i => i.url)
.map(i => ({
name: i,
template: '<cloud-page data="$.data"></cloud-page>',
resolveAs: '$',
resolve: {
data: (api) => {
return api.page
.url(location.pathname)
.then(i => i.data)
}
}
}))
let routers = []
.concat(pages)
.map(i => {
let path = i.name
delete i.name
return {
path: path,
route: i
}
})
routers.forEach(i => {
$routeProvider.when(i.path, i.route)
})
$routeProvider.otherwise({
template: '',
controller: function($window) {
console.log('otherwise')
$window.location.reload()
}
})
})
app.run(($window, $location, $rootScope, $http) => {
$rootScope.$on('$routeChangeSuccess', (event, current) => {
const url = location.href
try {
const title = current['$$route'].title
if (title) $rootScope.title = title
} catch (e) {
}
setTimeout(() => {
try {
DISQUS.reset({
reload: true,
config: function () {
this.page.identifier = url
this.page.url = url
}
})
} catch (e) {
}
}, 500)
})
$rootScope.$on('$routeChangeError', (event, current) => {
// let title = current['$$route'].title;
// if (title) $rootScope.title = title;
})
$http.defaults.headers.common['Accept'] = 'application/json'
});
[
API,
IOService,
MenuService,
Theme,
RemoveHashtags,
RemoveNewline,
Strip,
Join,
UppercaseFirst,
Bytes,
Ext,
MainMenu,
Navigation,
Breadcrumbs,
Timeline,
TimelineRecord,
TimelineRecordInstagram,
Article,
ArticlePageControl,
Album,
Parallax,
Document,
Award,
GalleryItem,
AlbumCollection,
TeacherProfile,
Page,
PageSchool,
PageArticle,
PageEvents,
PageSchedule,
PageCollective,
PageTeacher,
PageGallery,
PageAlbum,
PageDocuments,
PageAwards,
PageDocument,
AppController,
CopyrightController,
ContactsController,
Schedule,
ScheduleTable,
ScheduleSlider,
ScheduleSlide,
ScheduleRecord,
FooterLinks,
ThemeSelector,
AccessibilityControl,
].map(i => i(app))
@@ -1,48 +0,0 @@
import template from '../../templates/components/accessibility-control.html'
export default function (app) {
app.component('accessibilityControl', {
template,
controller: ($scope, theme) => {
$scope.scopes = {
color: [
['bw', 'белым по черному'],
['wb', 'черным по белому'],
],
fontSize: [
['normal', 'нормальный'],
['big', 'большой'],
['biggest', 'огромный'],
],
fontFamily: [
['sans', 'без засечек'],
['serif', 'с засечками'],
],
image: [
['yesImg', 'отображаются'],
['noImg', 'спрятаны'],
],
kerning: [
['normal', 'обычный'],
['big', 'увеличенный'],
],
}
$scope.isActive = (scope, [name,]) => theme.isActive(scope, name)
$scope.setDefaultTheme = () => theme.toggle()
$scope.setDefaultSettings = () => theme.setDefaultAccessibilityTheme()
$scope.setColorTheme = theme.setColorTheme.bind(theme)
$scope.setFontTheme = theme.setFontTheme.bind(theme)
$scope.setFontFamilyTheme = theme.setFontFamilyTheme.bind(theme)
$scope.setImageTheme = theme.setImageTheme.bind(theme)
$scope.setKerningTheme = theme.setKerningTheme.bind(theme)
},
})
}
-26
View File
@@ -1,26 +0,0 @@
import template from '../../templates/components/album.html';
export class AlbumController {
constructor($sce) {
if(this.album){
//this.post = $sce.trustAsHtml(this.album.post);
}
}
}
export default function (app) {
app.component('album', {
bindings: {
//album: '<'
title: '@'
},
transclude: true,
template: template,
controllerAs: '$',
//controller: function ($sce) {
// if(this.album){
// this.post = $sce.trustAsHtml(this.album.post);
// }
//}
});
};
-12
View File
@@ -1,12 +0,0 @@
import template from '../../templates/components/album-collection.html';
export default function (app) {
app.component('albumCollection', {
bindings: {
title: '@',
albums: '<'
},
template: template,
controllerAs: '$'
});
};
-38
View File
@@ -1,38 +0,0 @@
import template from '../../templates/components/article.html';
export default function (app) {
app.component('hArticle', {
bindings: {
post: '<'
},
template: template,
controllerAs: '$',
controller: function ($sce) {
//this.message = $sce.trustAsHtml(this.post.post);
this.url = `/article/${this.post.id}`;
const isVertical = ({width, height}) => width < height;
const temp = document.createElement('div');
temp.innerHTML = this.post.post;
const vs = [...temp.querySelectorAll('img')]
.filter(isVertical)
.filter(i => i.parentNode)
.map(i => [i.parentNode, i])
.map(([container, img]) => {
const url = img.src;
const elem = document.createElement('div');
elem.innerHTML = `<div class="vertical-image">
<div class="vertical-image__back"><img src="${url}" alt="" /></div>
<img src="${url}" alt="" />
</div>`;
return container.replaceChild(elem, img);
});
this.message = $sce.trustAsHtml(temp.innerHTML);
}
});
};
@@ -1,17 +0,0 @@
import template from '../../templates/components/article-page-control.html';
export default function (app) {
app.component('articlePageControl', {
bindings: {
direction: '@',
page: '@'
},
template: template,
controllerAs: '$',
controller: function () {
let i = this.direction === 'direct' ? 1 : 0;
this.text = ['↑ Предыдущая страница', '↓ Следующая страница'][i];
this.style = ['article-page-control__top', 'article-page-control__bottom'][i];
}
});
};
-11
View File
@@ -1,11 +0,0 @@
import template from '../../templates/components/award.html';
export default function (app) {
app.component('award', {
bindings: {
document: '<'
},
template: template,
controllerAs: '$'
});
};
-10
View File
@@ -1,10 +0,0 @@
import template from '../../templates/components/breadcrumbs.html';
export default function (app) {
app.component('breadcrumbs', {
bindings: {
crumbs: '='
},
template: template
});
};
-15
View File
@@ -1,15 +0,0 @@
import template from '../../templates/components/cloud-page.html';
export default function (app) {
app.component('cloudPage', {
bindings: {
page: '<data'
},
template: template,
controllerAs: '$',
controller: function ($rootScope, $sce) {
if (this.page) $rootScope.title = this.page.title;
this.content = $sce.trustAsHtml(this.page.data);
}
});
};
-19
View File
@@ -1,19 +0,0 @@
import template from '../../templates/components/document.html';
export default function (app) {
app.component('document', {
bindings: {
document: '<',
preview: '@'
},
controllerAs: '$',
controller: function () {
const size = this.preview || 'medium';
this.imageClass = `document__image--${size}`;
this.previewUrl = this.document.preview.data[size].url;
this.file = this.document.file;
},
template: template
});
};
-11
View File
@@ -1,11 +0,0 @@
import template from '../../templates/components/footer-links.html';
export default function (app) {
app.component('footerLinks', {
bindings: {
title: '@',
links: '<'
},
template: template
});
};
-14
View File
@@ -1,14 +0,0 @@
import template from '../../templates/components/gallery-item.html';
export default function (app) {
app.component('galleryItem', {
bindings: {
record: '<'
},
template: template,
controllerAs: '$',
controller: function () {
this.previewImage = this.record.preview.url;
}
});
};
-14
View File
@@ -1,14 +0,0 @@
import template from '../../templates/components/main-menu.html';
export default function (app) {
app.component('mainMenu', {
bindings: {
menu: '=items'
},
controller: function(menu){
this.isActive = item => menu.current ? item.url == menu.current.url : false;
this.isValid = item => 'url' in item;
},
template: template
});
};
-12
View File
@@ -1,12 +0,0 @@
import template from '../../templates/components/navigation.html'
export default function (app) {
app.component('navigation', {
bindings: {
menu: '<',
rightText: '@'
},
template: template,
controllerAs: '$'
})
};
-31
View File
@@ -1,31 +0,0 @@
import template from '../../templates/components/page-album.html';
export default function (app) {
app.component('pageAlbum', {
bindings: {
album: '<'
},
template: template,
controllerAs: '$',
controller: function ($rootScope,$sce, menu) {
menu.activate('/gallery');
this.post = $sce.trustAsHtml(this.album.post);
//this.crumbs = [
// {
// url: '/gallery',
// name: 'Галерея'
// },
// {
// name: 1010
// },
// {
// name: album.title
// }
//];
$rootScope.title = this.album.title;
}
});
};
-30
View File
@@ -1,30 +0,0 @@
import template from '../../templates/components/page-article.html';
export default function (app) {
app.component('pageArticle', {
bindings: {
article: '<'
},
template: template,
controllerAs: '$',
controller: function ($rootScope, $routeParams, api, menu) {
menu.activate('/events');
if(this.article){
$rootScope.title = this.article.title;
}
//this.posts = [this.article];
//let id = $routeParams.id;
//if(!id) return;
//
//api.article.id(id)
// .then(i => i.data)
// .then(post => {
// $rootScope.title = post.title;
// this.posts = [post];
// });
}
});
};
-11
View File
@@ -1,11 +0,0 @@
import template from '../../templates/components/page-awards.html'
export default function (app) {
app.component('pageAwards', {
bindings: {
items: '<',
},
template: template,
controllerAs: '$',
})
}
-41
View File
@@ -1,41 +0,0 @@
import template from '../../templates/components/page-collective.html';
export default function (app) {
app.component('pageCollective', {
bindings:{
members: '<'
},
template: template,
controller: function() {
//api.collective.list(collectiveSortPattern)
// .success(collective => {
// this.members = collective;
// });
//let rangelen = r => r[1] - r[0];
//let interpolate = (r, i) => (i - r[0]) / rangelen(r);
//let extrapolate = (r, i) => r[0] + rangelen(r) * i;
//
//let mapValue = (from, to) =>
// i => extrapolate(
// to, interpolate(
// from, i
// ));
//
//let mapImageScroll = mapValue([0, 400], [0, -100]);
//
//$(window).scroll(() => {
// let scroll = $(window).scrollTop();
//
// let v = mapImageScroll(scroll);
// console.log(v);
//
// this.$apply(() => {
// this.imageStyle = {
// top: v
// };
// });
//});
}
});
};
-12
View File
@@ -1,12 +0,0 @@
import template from '../../templates/components/page-document.html';
import {unique} from '../../utils/common';
export default function (app) {
app.component('pageDocument', {
bindings: {
item: '<'
},
template: template,
controllerAs: '$'
});
};
-94
View File
@@ -1,94 +0,0 @@
import template from '../../templates/components/page-documents.html'
import {unique} from '../../utils/common'
const compose = (...fns) => value => fns
.map(fn => fn)
.reverse()
.reduce((acc, fn) => fn(acc), value)
const pass = fn => value => {
fn(value)
return value
}
const subtract = (acc, i) => acc - i
const uniqueCategories = unique(i => i.category)
const priority = {
'Основные документы': [
'https://static.shlisselburg.org/art/uploads/ustav-2015.pdf',
'https://static.shlisselburg.org/art/uploads/obrazovatelnaia-litsenziia-2015.pdf',
'https://static.shlisselburg.org/art/uploads/svidetelstvo-na-pomeshchenie.pdf',
'https://static.shlisselburg.org/art/uploads/egriul.pdf',
'https://static.shlisselburg.org/art/uploads/inn.pdf',
'https://static.shlisselburg.org/art/uploads/reshenie-o-sozdanii-shkoly.pdf',
'https://static.shlisselburg.org/art/uploads/kopiia-resheniia-o-naznachenii-rukovoditelia.pdf',
'https://static.shlisselburg.org/art/uploads/postanovlenie-o-sozdanii-munitsipalnogo-obrazovatelnogo-uchrezhdeniia-kultury-detskaia-khudozhestvennaia-shkola.pdf',
],
'Учебные программы': [
'https://static.shlisselburg.org/art/uploads/uchebnaia-programma-zhivopis.pdf',
]
}
const CATEGORY_PRIORITY = [
'Основные документы',
'Планы ФХД',
'Самообследование деятельности',
'Инструкции',
'Образование',
'Учебные программы',
'Платные образовательные услуги',
'Дополнительные общеразвивающие программы',
'Документы для поступления',
]
const getPriorityFn = list => value => list.includes(value)
? list.indexOf(value)
: 10000
const safeSelect = (d, store, key) => key in store
? store[key]
: d
const documentPriority = ({category, url}) => compose(
getPriorityFn,
safeSelect.bind(null, [], priority)
)(category)(url)
//const documentPriority = ({category, url}) => {
// const list = safeSelect([], priority, category)
// return getPriorityFn(list)(url)
//}
const categoryPriority = getPriorityFn(CATEGORY_PRIORITY)
const sortBy = fn => (a, b) => [a, b]
.map(fn)
.reduce(subtract)
export default function (app) {
app.component('pageDocuments', {
bindings: {
documents: '<'
},
template: template,
controllerAs: '$',
controller: function () {
const documents = this.documents
const documentsOf = category => documents.filter(i => i.category === category)
const sorted = documents => documents.sort(sortBy(documentPriority))
const collectDocumentsByCategory = compose(sorted, documentsOf)
this.collections = uniqueCategories(documents)
.sort(sortBy(categoryPriority))
.reduce((acc, name) => (
[...acc, {
name,
documents: collectDocumentsByCategory(name)
}]
), [])
}
})
}
-22
View File
@@ -1,22 +0,0 @@
import template from '../../templates/components/page-events.html';
export default function (app) {
app.component('pageEvents', {
bindings: {
posts: '<',
page: '@',
totalPages: '@'
},
template: template,
controllerAs: '$',
controller: function (api, menu) {
menu.activate('/events');
this.page = parseInt(this.page);
this.totalPages = parseInt(this.totalPages);
this.prevPage = this.page === 1 ? null : this.page - 1;
this.nextPage = this.page === this.totalPages ? null : this.page + 1;
}
});
};
-38
View File
@@ -1,38 +0,0 @@
import template from '../../templates/components/page-gallery.html';
import {branch} from '../../utils/common';
export default function (app) {
let branchYears = branch(
i => 'date' in i ? i.date.getFullYear() : 'XXXX'
);
app.component('pageGallery', {
bindings: {
albums: '<'
},
template: template,
controllerAs: '$',
controller: function () {
this.pageClass = 'page-gallery';
let years = branchYears(
this.albums
.map(i => {
i['date'] = new Date(i['date']);
return i;
})
);
this.collections = Object
.keys(years)
.map(i => parseInt(i))
.sort((a, b) => b - a)
.map(i => {
return {
title: i,
albums: years[i]
}
});
}
});
};
-40
View File
@@ -1,40 +0,0 @@
import template from '../../templates/components/page-gallery.html';
export default function (app) {
app.component('pageGalleryAlbum', {
template: template,
controller: function ($rootScope, $routeParams, api, menu) {
this.pageClass = 'page-gallery-album';
menu.activate('/gallery');
let year_uri = $routeParams.year;
let course_uri = $routeParams.course;
let album_uri = $routeParams.album;
api.gallery.album(year_uri, course_uri, album_uri)
.success(album => {
//album.teacherName = team.name(album['teacher']);
album.teacherName = album['teacher'];
this.album = album;
this.crumbs = [
{
url: '/gallery',
name: 'Галерея'
},
{
name: year_uri
},
{
name: album.course
},
{
name: album.title
}
];
$rootScope.title = album.title;
});
}
});
};
-57
View File
@@ -1,57 +0,0 @@
import template from '../../templates/components/page-schedule.html';
import APISchedule from '../api/APISchedule';
export default function (app) {
app.component('pageSchedule', {
template: template,
bindings: {
schedules: '<'
},
controller: function($http, $location, $routeParams, api, menu) {
menu.activate('/schedule');
const period = $routeParams.period;
const semester = $routeParams.semester;
const useRoute = Boolean(period) && Boolean(semester);
const stringPeriod = period => period.join('-');
this.loadSchedule = (record, doUpdateUrl) => {
let id = record._id;
let scheduleItem = getScheduleById(id);
if (scheduleItem) {
let p = scheduleItem.period.join('-');
let s = scheduleItem.semester;
api.schedule.fetch(p, s, true)
.then(i => i.data)
.then(i => {
this.schedule = i;
if (doUpdateUrl) $location.url(APISchedule.buildScheduleUrl(p, s));
});
}
};
const getScheduleById = id => this.schedules
.find(i => i._id === id);
const getSchedule = (period, semester) => this.schedules
.find(i => stringPeriod(i.period) === period && i.semester === semester);
let last = list => list.length ? list[list.length - 1] : null;
let getDefaultSchedule = list => last(list);
let word = semester => [['spring', 'Весна'], ['autumn', 'Осень']]
.find(i => i[0] === semester)
[1];
this.schedules.forEach(i => {
let periodIndex = i.semester === 'spring' ? 1 : 0;
let year = i.period[periodIndex];
i.text = `${word(i.semester)} ${year} года`;
});
this.currentSchedule = useRoute ? getSchedule(period, semester) : getDefaultSchedule(this.schedules);
if(this.currentSchedule) this.loadSchedule(this.currentSchedule, useRoute);
}
});
};
-46
View File
@@ -1,46 +0,0 @@
import template from '../../templates/components/page-school.html';
import {mobileMatchSelector} from '../config';
export default function (app) {
app.component('pageSchool', {
template: template,
controllerAs: '$',
controller: function() {
this.helloBlock = 'parallax';
try {
if (window.matchMedia(mobileMatchSelector).matches) {
this.helloBlock = 'mobile-image';
}
} catch (e) {
}
//let fotorama;
//let $tape = $('.tape-block');
//let $fotorama = $tape.find('.tape-block__content');
//
//$tape.addClass('simplified');
//$fotorama.on('fotorama:ready', () => {
// $tape.removeClass('simplified');
// fotorama.setOptions({
// nav: 'dots',
// transition: 'crossfade',
// autoplay: '6000',
// arrows: 'false',
// width: '100%',
// fit: 'cover',
// loop: 'true'
// });
//});
//
//fotorama = $fotorama.fotorama().data('fotorama');
//setTimeout(() => {
// fotorama.load([
// {img: 'https://static.shburg.org/art/img/cat1.jpg'},
// {img: 'https://static.shburg.org/art/img/cat2.jpg'},
// {img: 'https://static.shburg.org/art/img/cat3.jpg'}
// ]);
//}, 100);
}
});
};
-14
View File
@@ -1,14 +0,0 @@
import template from '../../templates/components/page-teacher.html';
export default function (app) {
app.component('pageTeacher', {
bindings:{
member: '<'
},
template: template,
controllerAs: '$',
controller: function(menu){
menu.activate('/collective');
}
});
};
-68
View File
@@ -1,68 +0,0 @@
import template from '../../templates/components/parallax.html'
export default function (app) {
app.directive('parallax', function () {
return {
restrict: 'E',
template: template,
controllerAs: '$',
link: function (scope, element) {
let map_range = (i, low1, high1, low2, high2) => low2 + (high2 - low2) * (i - low1) / (high1 - low1);
scope.layers = [
{x: 0, y: 0, s: 0, url: 'https://static.shlisselburg.org/art/graphics/main/11.jpg'},
//{x: 716, y: 127, s: -0.4, url: 'https://static.shlisselburg.org/art/graphics/main/10.png'},
//{x: 0, y: 216, s: -0.3, url: 'https://static.shlisselburg.org/art/graphics/main/9.png'},
{x: 0, y: 450, s: -0.2, url: 'https://static.shlisselburg.org/art/graphics/main/8.png'},
{x: 683, y: 378, s: -0.25, url: 'https://static.shlisselburg.org/art/graphics/main/7.png'},
{x: 0, y: 522, s: -0.3, url: 'https://static.shlisselburg.org/art/graphics/main/6.png'},
{x: 414, y: 585, s: -0.4, url: 'https://static.shlisselburg.org/art/graphics/main/5.png'},
{x: 0, y: 213, s: -.5, url: 'https://static.shlisselburg.org/art/graphics/main/4.png'},
{x: 206, y: 667, s: -.6, url: 'https://static.shlisselburg.org/art/graphics/main/3.png'},
{x: 556, y: 506, s: -0.7, url: 'https://static.shlisselburg.org/art/graphics/main/2.png'},
{x: 0, y: 914, s: -0.7, url: 'https://static.shlisselburg.org/art/graphics/main/1.png'},
{x: 13, y: 88, s: 0, url: 'https://static.shlisselburg.org/art/graphics/main/title.png'}
];
function mapper(range1, range2, fit) {
let [r1, r2] = range1;
let [d1, d2] = range2;
let constrain = value => {
var min = Math.min(d1, d2);
var max = Math.max(d1, d2);
return Math.min(max, Math.max(min, value));
};
return value => fit ? constrain(map_range(value, r1, r2, d1, d2)) : map_range(value, r1, r2, d1, d2);
}
const hm = mapper([0, 900], [0, 900], true);
const em = mapper([340, 900], [0, 400], true);
function updateHead(value) {
const v = hm(value);
try {
[...document.querySelectorAll('.parallax .parallax__layer')]
.forEach((e, i) => {
let layer = scope.layers[i];
e.style.top = `${layer.y + v * layer.s}px`;
});
const end = document.querySelector('.parallax .parallax__end');
if (end) end.style.height = `${em(value)}px`;
} catch (error) {
}
}
updateHead(0);
$(window).scroll(() => {
updateHead($(window).scrollTop())
});
}
};
});
}
-21
View File
@@ -1,21 +0,0 @@
import template from '../../templates/components/schedule.html';
import {mobileMatchSelector} from '../config';
export default function(app) {
app.component('schedule', {
bindings: {
schedule: '<'
},
template: template,
controller: function () {
this.type = 'table';
try {
if (window.matchMedia(mobileMatchSelector).matches) {
this.type = 'slider';
}
} catch (e) {
}
}
});
};
-16
View File
@@ -1,16 +0,0 @@
import template from '../../templates/components/schedule-record.html';
import {shortName} from '../../models/collective';
import {nullSafe} from "../../utils/common";
export default function(app) {
app.component('scheduleRecord', {
bindings: {
record: '<',
i: '<'
},
template: template,
controller: function() {
this.short = nullSafe(shortName);
}
})
};
-10
View File
@@ -1,10 +0,0 @@
import template from '../../templates/components/schedule-slide.html';
export default function(app) {
app.component('scheduleSlide', {
bindings: {
day: '<'
},
template: template
})
};
-71
View File
@@ -1,71 +0,0 @@
import template from '../../templates/components/schedule-slider.html';
import {getDates} from '../../utils/date';
function week(schedule) {
let now = new Date();
let dates = getDates(now);
return ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота']
.map((day, i) => {
return {
current: i === now.getDay() - 1,
day: day,
date: dates[i],
groups: schedule.groups.map(group => ({
name: group.group,
time: group.time,
content: group.week[i]
}))
}
});
}
export default function(app) {
app.directive('scheduleSlider', ($compile) => {
return {
restrict: 'E',
template: template,
scope:{
schedule: '='
},
link: function (scope, element) {
let $slick = element.find('.schedule-slick');
scope.$watch('schedule', value => {
try {
$slick.slick('unslick');
} catch (e) {
}
if (value) {
const days = week(value);
scope.days = days;
$slick.html(
days.map((day, i) => {
return `<schedule-slide day="days[${i}]"></schedule-slide>`
}).join('')
).show();
$compile($slick.contents())(scope);
$slick.slick({
mobileFirst: true,
infinite: false,
dots: false,
arrows: false,
touchThreshold: 20,
speed: 250,
slidesToShow: 1,
centerMode: false
});
let now = new Date();
let currentWeekIndex = now.getDay() - 1;
$slick.slick('slickGoTo', currentWeekIndex);
}
});
}
}
});
};
-59
View File
@@ -1,59 +0,0 @@
import template from '../../templates/components/schedule-table.html';
import {getDates} from '../../utils/date';
import {shortName} from '../../models/collective';
export default function(app) {
app.component('scheduleTable', {
bindings: {
schedule: '<'
},
template: template,
controller: function () {
const now = new Date();
const dates = getDates(now);
this.days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
this.isToday = weekDayIndex => (now.getDay() - 1) === weekDayIndex;
this.weekDay = weekDayIndex => dates[weekDayIndex];
this.short = shortName;
//var $tbody = element.find('table tbody');
//var $thead = element.find('table thead');
//let setHeadWidth = () => {
// var $td_list = element.find('table tbody tr:first-child td');
// $td_list.each(function (i) {
// var w = this.offsetWidth;
// $thead.find('th')[i].style.width = `${w}px`;
// });
//};
//let resetHeadWidth = () => {
// var $td_list = element.find('table tbody tr:first-child td');
// $td_list.each(function (i) {
// var w = this.offsetWidth;
// $thead.find('th')[i].style.width = null;
// });
//};
//var min;
//var max;
//$(window).scroll(function () {
// const scrollOffset = 150;
// if(!min) min = element.find('table tbody tr:first-child')[0].offsetTop + scrollOffset;
// if(!max) max = element.find('table tbody tr:last-child')[0].offsetTop + scrollOffset;
//
// var scroll = $(this).scrollTop();
// if (scroll >= min && scroll <= max) {
// setHeadWidth();
// $thead.addClass('fix animated fadeInDown');
// $tbody.addClass('fix');
// } else {
// resetHeadWidth();
// $thead.removeClass('fix animated fadeInDown');
// $tbody.removeClass('fix');
// }
//});
}
});
};
-29
View File
@@ -1,29 +0,0 @@
import {splitName} from '../../models/collective';
import {stringToBoolean} from '../../utils/string';
import template from '../../templates/components/teacher-profile.html';
export default function (app) {
app.component('teacherProfile', {
bindings: {
profile: '<',
showUrl: '@'
},
template: template,
controllerAs: '$',
controller: function($sce){
this.url = this.showUrl === 'true';
//this.showUrl = stringToBoolean(this.showUrl);
const [_, first, middle, last] = splitName(this.profile.name);
this.firstName = first;
this.middleName = middle;
this.lastName = last;
if (this.profile.picture) {
this.image = this.profile.picture.data.big;
}
this.biography = $sce.trustAsHtml(this.profile.biography);
}
});
};
-22
View File
@@ -1,22 +0,0 @@
export default function (app) {
app.component('themeSelector', {
template: `
<p ng-click="toggleTheme()">
<span ng-hide="isMainTheme" title="Выключить версию для слабовидящих"><i class="fa fa-eye" aria-hidden="true"></i></span>
<span ng-show="isMainTheme" title="Включить версию для слабовидящих"><i class="fa fa-eye-slash" aria-hidden="true"></i></span>
</p>
`,
controller: ($scope, theme) => {
const update = () => {
$scope.isMainTheme = theme.isDefaultTheme()
}
$scope.toggleTheme = () => {
theme.toggle()
update()
}
update()
},
})
};
-104
View File
@@ -1,104 +0,0 @@
import template from '../../templates/components/timeline.html';
import {createInstance as createInstagram} from '../../models/TimelinePostInstagram';
// function personByInstagram(list, instagram){
// list = list.filter(function (member) {
// try {
// return member.contacts.instagram === instagram;
// } catch (error) {
// return false;
// }
// });
//
// if(list.length){
// return list[0].id;
// }else{
// return null;
// }
// }
// function postText(post){
// try{
// return post.data.caption.text.replace(/#[\w_]+/, '')
// }catch(error){
// return "";
// }
// }
// function toInstagram(post){
// //var author_id = personByInstagram(team.team, post.data.author);
// //var name = author_id ? team.short(author_id) : post.data.author;
// let name = 'hudozka';
//
// return {
// date: post.date,
// image: post.data.image.standard_resolution.url,
// url: post.data.url,
// username: name,
// userpic: 'https://igcdn-photos-a-a.akamaihd.net/hphotos-ak-xaf1/t51.2885-19/11357496_464997000344800_2124591831_a.jpg',
// text: post.body,
// //text: postText(post),
// type: post.type
// };
// }
const createPost = post => post.type === 'post' ? post : null;
const createPosts = items => items
.map(createRecord)
.filter(Boolean);
function createRecord(post){
for (let fn of [createInstagram, createPost]){
let result = fn(post);
if(result) return result;
}
return null;
}
export default function (app) {
app.component('timeline', {
template: template,
controller: function ($timeout, usSpinnerService, api, io) {
let skip = 0;
let limit = 10;
this.feed = [];
this.timelineUpdating = false;
usSpinnerService.stop('timelineMore');
this.loadNext = () => {
this.timelineUpdating = true;
usSpinnerService.spin('timelineMore');
api.timeline.feed(limit, skip)
.then(i => i.data)
.then(feed => {
this.timelineUpdating = false;
usSpinnerService.stop('timelineMore');
// let feed2 = feed.map(post => {
// if (post.type == 'instagram') return toInstagram(post);
// else return post;
// });
feed = createPosts(feed);
skip += limit;
this.feed = this.feed.concat(feed);
this.showFooter = this.feed && this.feed.length;
});
};
this.loadNext();
io.on('feed', feed => {
console.log(feed);
feed = createPosts(feed instanceof Array ? feed : [feed]);
$timeout(()=> {
this.feed = feed.concat(this.feed);
}, 0);
});
}
});
};
-11
View File
@@ -1,11 +0,0 @@
import template from '../../templates/components/timeline-record.html';
export default function (app) {
app.component('timelineRecord', {
bindings: {
post: '<',
type: '@'
},
template: template
});
};
@@ -1,10 +0,0 @@
import template from '../../templates/components/timeline-record-instagram.html';
export default function (app) {
app.component('timelineRecordInstagram', {
bindings: {
post: '<'
},
template: template
});
};
-45
View File
@@ -1,45 +0,0 @@
import {stringReplace} from '../utils/string';
const nbsp = 0xA0;
export const mobileMatchSelector = '(max-device-width: 30em)';
export const contacts = {
telephone: '+7 (81362) 76-312',
email: 'hudozka@gmail.com',
address: ['г. Шлиссельбург', 'ул. 18 января', 'д. 3']
.map(stringReplace(' ', String.fromCharCode(nbsp)))
.join(' ')
};
export const collectiveSortPattern = [
'mg-timasheva',
'va-sarzhin',
'od-gogoleva',
'my-valkova',
'vv-voronova',
'nv-andreeva'
];
export const documentsSortPattern = [
'Основные документы',
'Документы для поступления',
'Учебные программы',
'Прочее',
'Архив'
];
export const footer = {
links: {
docs: {
title: 'Документы',
links: [
{url: '/document/edu-license', link: 'Лицензия на осуществление образовательной деятельности'},
{url: '/document/gov-certificate', link: 'Свидетельство о государственной регистрации права'},
{url: '/document/EGRYL1', link: 'Свидетельство о внесении в «ЕГРЮЛ»'},
{url: '/document/VAT', link: 'ИНН'},
{url: '/document/statue-2013', link: 'Устав школы'}
]
}
}
};
-19
View File
@@ -1,19 +0,0 @@
import {footer, mobileMatchSelector, contacts} from '../config'
export default function (app) {
app.controller('AppController', ($scope, menu) => {
try {
if (window.matchMedia(mobileMatchSelector).matches) {
$scope.navigation = 'navigation'
} else {
$scope.navigation = 'main-menu'
}
} catch (e) {
$scope.navigation = 'main-menu'
}
$scope.phone = contacts.telephone
$scope.menuProvider = menu.items
$scope.footer = footer
})
};
@@ -1,9 +0,0 @@
import {contacts} from '../config';
export default function (app) {
app.controller('ContactsController', $scope => {
$scope.address = contacts.address;
$scope.telephone = contacts.telephone;
$scope.email = contacts.email;
});
};
@@ -1,17 +0,0 @@
export default function (app) {
app.controller('CopyrightController', ($scope, $rootScope) => {
$scope.developer = true;
$scope.now = new Date().getFullYear();
$rootScope.$on('$routeChangeSuccess', (event, current) => {
let originalPath;
try{
originalPath = current['$$route'].originalPath;
}catch(e){
originalPath = null;
}
$scope.developer = originalPath == '/';
});
});
};
-3
View File
@@ -1,3 +0,0 @@
export function getInitialData(){
return window.hudozka;
}
-13
View File
@@ -1,13 +0,0 @@
export default function(app) {
app.filter('bytes', () => {
return (bytes, precision=1) => {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '';
const units = ['байт', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПБ'];
const number = Math.floor(Math.log(bytes) / Math.log(1024));
const size = (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision);
return `${size} ${units[number]}`
}
});
};
-16
View File
@@ -1,16 +0,0 @@
export default function(app) {
app.filter('ext', () => {
return (filname) => {
let getExt = name => /\.(\w+)$/.exec(name)[1];
let defaultExt = ext => ext.toUpperCase();
const exts = ['png', 'pdf', 'jpg', 'jpeg', 'gif', 'doc'];
const extd = ['ПНГ', 'ПДФ', 'ЖПГ', 'ЖПГ', 'ГИФ', 'ДОК'];
let ext = getExt(filname);
const i = exts.indexOf(ext);
if(i > -1) return extd[i];
return defaultExt(ext);
}
});
};
-6
View File
@@ -1,6 +0,0 @@
export default function(app) {
app.filter('join', () => {
return (list, sep=',') =>
list == null ? '' : list.join(sep);
});
};
-5
View File
@@ -1,5 +0,0 @@
export default function(app) {
app.filter('removeHashtags', () => {
return string => string ? string.replace(/(#[^\s]+)/g, '') : string;
});
};
-5
View File
@@ -1,5 +0,0 @@
export default function(app) {
app.filter('uppercaseFirst', () => {
return string => string.charAt(0).toUpperCase() + string.slice(1);
});
};
-5
View File
@@ -1,5 +0,0 @@
export default function(app) {
app.filter('removeNewline', () =>{
return string => string.replace(/(\n)/g, ' ');
});
};
-7
View File
@@ -1,7 +0,0 @@
export default function (app) {
app.filter('strip', () => {
return string => string
.replace(/^\s+/, '')
.replace(/\s+$/, '');
});
};
-5
View File
@@ -1,5 +0,0 @@
import API from '../api/API';
export default function (app) {
app.factory('api', $http => new API($http));
};
-12
View File
@@ -1,12 +0,0 @@
export default function (app) {
let socket;
function init(){
socket = io();
}
app.service('io', () => {
if (!socket) init();
return socket;
});
};
-33
View File
@@ -1,33 +0,0 @@
import menuItems from '../../models/menu';
class Menu {
constructor(items) {
this.items = items;
this.current = null;
}
activate(path) {
let filteredItems = this.items.filter(i => i.url === path);
if (filteredItems.length) {
this.current = filteredItems[0];
}
}
}
export default function (app) {
app.factory('menu', ($rootScope) => {
const menu = new Menu(menuItems);
$rootScope.$on('$routeChangeSuccess', (event, current) => {
try {
let path = current['$$route'].originalPath;
menu.activate(path);
} catch (e) {
}
});
return menu;
});
};
-171
View File
@@ -1,171 +0,0 @@
const defaultTheme = 'theme-default'
const themeScheme = {
accessibility: 'accessibility',
color: {
wb: 'theme-accessibility-white-black',
bw: 'theme-accessibility-black-white',
},
font: {
sans: 'theme-accessibility-font-sans',
serif: 'theme-accessibility-font-serif',
},
fontSize: {
normal: '',
big: 'theme-accessibility-font-big',
biggest: 'theme-accessibility-font-biggest',
},
image: {
yesImg: '',
noImg: 'theme-accessibility-no-image',
},
kerning: {
normal: '',
big: 'theme-accessibility-kerning-big',
},
}
const defaultAccessibilityTheme = () => ({
version: '1',
theme: {
accessibility: 'accessibility',
color: 'wb',
font: 'sans',
fontSize: 'normal',
image: 'yesImg',
kerning: 'normal',
},
})
function loadTheme() {
const theme = localStorage.getItem('theme')
try {
return JSON.parse(theme)
} catch (error) {
return null
}
}
function saveTheme(theme) {
if (!theme) return theme
const str = typeof theme === 'string'
? theme
: JSON.stringify(theme)
localStorage.setItem('theme', str)
return theme
}
function resetTheme() {
localStorage.removeItem('theme')
}
function compileTheme(item) {
if (!item) return defaultTheme
const {theme, version} = item
if (!version) return defaultTheme
const cssClass = ([scope, name]) => {
try {
return themeScheme[scope][name]
} catch (error) {
return null
}
}
return Object
.entries(theme)
.map(cssClass)
.filter(Boolean)
.join(' ')
}
class Theme {
constructor($rootScope) {
this.mainTheme = defaultTheme
this.themeSetup = defaultAccessibilityTheme()
this.__scope = $rootScope
this.setTheme(loadTheme())
}
toggle() {
if (this.isDefaultTheme()) {
this.setTheme(this.themeSetup)
} else {
this.setMainTheme()
}
}
setMainTheme() {
resetTheme()
this.__scope.theme = this.mainTheme
}
setTheme(theme) {
if (!theme) {
this.setMainTheme()
} else {
const css = compileTheme(theme)
saveTheme(theme)
this.themeSetup = theme
this.__scope.theme = css
}
}
setColorTheme(theme) {
this.themeSetup.theme.color = theme
this.install()
}
setFontTheme(theme) {
this.themeSetup.theme.fontSize = theme
this.install()
}
setFontFamilyTheme(theme) {
this.themeSetup.theme.font = theme
this.install()
}
setImageTheme(theme) {
this.themeSetup.theme.image = theme
this.install()
}
setKerningTheme(theme) {
this.themeSetup.theme.kerning = theme
this.install()
}
install() {
this.setTheme(this.themeSetup)
}
isDefaultTheme() {
return this.__scope.theme === this.mainTheme
}
isActive(scope, name) {
if (this.isDefaultTheme()) return false
try {
return this.themeSetup.theme[scope] === name
} catch (e) {
return false
}
}
setDefaultAccessibilityTheme () {
this.setTheme(defaultAccessibilityTheme())
}
}
export default function (app) {
app.service('theme', Theme)
}
+3 -17
View File
@@ -13,8 +13,7 @@ export default function () {
getPageUrls(),
getGalleryUrls(),
getTeacherUrls(),
getEventsUrls(),
getNewsUrls()
getArticleUrls(),
]);
urls = urls.reduce((urls, i) => urls.concat(i));
@@ -72,8 +71,8 @@ async function getTeacherUrls() {
});
}
async function getEventsUrls() {
let docs = await c('events')
async function getArticleUrls() {
let docs = await c('articles')
.find({})
.toArray();
@@ -84,16 +83,3 @@ async function getEventsUrls() {
}
});
}
async function getNewsUrls() {
let docs = await c('timeline')
.find({type: 'post'})
.toArray();
return docs.map(i => {
return {
url: `/article/${i.id}`,
changefreq: 'monthly'
}
});
}