Andrei D.

Andrei D.

С нами с 09 января 2014; Место в рейтинге пользователей: #54
Andrei D.
28 июня 2017, 15:42
0
А по WebRTC уже есть прогресс, на apple девайсах уже поддерживается в режиме разработчика. Думаю, к сентябрю в релиз выкатят. Качество видео тоже хорошее, но нужно программно работать над потоком, чтобы с слабым интернетом не было сбоев
Andrei D.
28 июня 2017, 15:40
0
Да, сейчас только 9 основных (на наш взгляд) категорий вместе с подкатегориями
По запросам пользователей будем добавлять
Пока еще статистика небольшая, heat map не составить
Andrei D.
28 июня 2017, 15:32
0
Спасибо!
Да, очень много всего нужно по логике переделать
Там самое интересное начинается на этапе добавления направления консультации) попробуйте!
Andrei D.
28 июня 2017, 15:29
+2
В личном кабинете почти везде Office, но планирую убрать, тк возникла проблема с обязательными полями, если вызывать сниппет на нескольких страницах.
Т.е. если поле «страна» не заполнено Office не дает выйти с этой страницы (js), но если юзер каким-то чудом перешел по другой ссылке/почистил кэш, то со страницы, где можно поменять только пароль тоже невозможно выйти.
Плюс слишком много различных полей, к которым нужны отдельные правила. Т.е. сейчас пакет не обновляемый, к сожалению, а хочется ту же авторизацию на профили юзеров затестить…
Поэтому личный кабинет будет с нуля переработан, на всплывающих окнах и т.д. Просто эту платформу мы уже доработали на другом сайте, это небо и земля, если сравнивать по юзабилити
Andrei D.
28 июня 2017, 15:23
1
+2
личный кабинет дорабатывается

TokBox php SDK – генерация сессий и токенов
Кастомные таблицы для самих звонков и участников, контроллеры для смены статусов, пересчета заработка и оставшихся средств и т.д.
Текстовый чат отдельно от видео
Вывод посредством React.js и процессоров getdata & etc
Ну и вся логика вызова, приёма звонка, контроль платной сессии – всё с нуля
Andrei D.
28 июня 2017, 15:18
0
можете отправить мне эмейл с временным аккаунтом, только напишите, где и что должно выводиться
Andrei D.
28 июня 2017, 12:37
0
Поля, полагаю, имеют свой className, поэтому с ними можно работать как с обычными объектами

Делаете query на tv, потом пересохраняете всё полученное в бд уже в новом формате
Andrei D.
28 июня 2017, 12:30
+1
У меня для студии своя CRM система и Workplace для клиентов (на тикетах, кстати). Причем полностью в стилистике и направлении студии, красиво и удобно.
Также есть платформа для интернет-журнала (!) с удобством публикации материалов.
А на недавнем сайте есть еще и модераторская система случайно подсмотренная во вконтакте. Т.е. в обычном кабинете дополнительные функции для модераторов. Планируется сделать мощный инструмент управления юзерами. hd-labs.com/wh/gglobal/screen.jpg Куда это зайдет зависит только от степени упоротости)

Также, прежде всего, я написал в предыдущем комментарии, что это просто мысли вслух. Не спорю, что многим удобнее оформлять боксами (мне почему-то сейчас вспомнилась мною премного нелюбимая Тильда, которую все почему-то хвалят). Но все же считаю, что контент-мейкер может и html разметку понимать.
Andrei D.
28 июня 2017, 10:58
+1
Было время, когда был заинтересован в покупке дополнений modmore, но после впечатляющих демок желание пропало.

Вполне возможно, что у меня паранойя высшей степени, но я не нахожу оправдания для выдачи доступа в manager всем желающим эдиторам и контент-мейкерам. Для клиента должна быть сделана удобная админка во фронте хотя бы без редактирования контента на второстепенной вкладке (привет, Redactor).

ContentBlocks. Developers love it too! Нет, девелопер нажмет на иконку plain code в любом случае. Автоматизировать верстку? Хорошо, ровно через год редизайн. А на сайте 20.000 статей (в ресурсах, к тому же, увы).

MoreGallery – снова бэкэнд. Простите, но мне с телефона нужно срочно загрузить фото в новый репортаж, благо не только благодаря импортозамещению (по-русски так говорится?) есть компоненты гораздо удобнее

Formalicious. Наверное, самое первое «сложное» заданьеце для зеленого модэксера заключалось как раз таки в установке на сайт формы контактов. Вот уже более 30 сайтов сделано, а вот та первая форма так и кочует копипастом, потому что обросла в последствии своей валидацией, аяксом и коллбэками. Так у всех ведь, да?

Commerce, SimpleCart – для рынка за океаном идеально. Stripe – вещь.

SimpleAB 10/10
Scheduler +

А вообще, ребята молодцы, благодаря их модулю AB-тестирования, однажды поднял стоимость проекта в два раза.
С тех пор так и пользуюсь лайфхаком

Просто мысли вслух
Andrei D.
30 мая 2017, 06:22
1
+6
На самом деле это реализуется за несколько часов
Вот примерная простейшая архитектура без излишеств:

1. Своя кастомная таблица с полями [key][name][unit][max_manual][max_mech][max_mats], в которую можно все наименования работ с экселя закинуть
2. Сверху формы добавления:
<input class="search-input" type="text" name="task_key" placeholder="Номенклатура"/>
<input class="search-input" type="text" name="task_name" placeholder="Наименование"/>
3. Сразу под поиском:
<div class="search-items"></div>
<ul class="added-items"></ul>
4. Создать страницу с пустым шаблоном для ajax запросов, например, website.com/app, в которую поместить сниппет обработки запросов, в самом сниппете на $action повесить case «search» «select» «create»
5. Добавить скрипт, который на onchange .search-input ловит $(this).attr('name') + $(this).val() и с action «search» направляет всё на /app «search» и возвращает найденные строки, джойнит их и оборачивает, например, в
<button class="selector-item" type="button" val="id_работы" style="width:100%;display:block">наименование работы</button>
6. На клик по .selector-item направить $(this).val() на сниппет с case «select», возвращать отдельную работу, например, так:
<li class="item" data-item="id_работы">
<span>* Наименование *</span><span>* Номенклатура *</span>
<span class="small">MAX ручной труд: *стоимость* / механический труд: *стоимость* / материалы: *стоимость*</span>
<input type="text" placeholder="Фактическая стоимость" value="* в сниппете сложить общую стоимость *"/>
<button type="button"><i class="fa fa-remove"></i></button>
</li>
далее брать стоимость работы по умолчанию и складывать со значением .total-sum
7. Повесить скрипт на на onchange стоимости для каждой добавленной работы и пересчитывать со значением .total-sum
8. После списка добавленных работ:
<div class="form">
<h3>Общая стоимость: <input type="hidden" class="total-sum" value="0"/><span class="total-sum">0</span></h3>
<h4>Данные заказчика</h4>
<label>ФИО заказчика</label><input type="text" name="order-name" placeholder="ФИО заказчика"/>
<label>Телефон</label><input type="text" name="order-phone" placeholder="Телефон"/>
адрес объекта и т.д.
<button type="button" class="create-order">Сохранить</button>
</div>
9. По кнопке .create-order скрипт джойнит добавленные значения из .added-items, и вместе с данными формы отправляет на /app «create»
10. Для «create» нужно создать вторую кастомную таблицу заказов с полями [order_id][works][customer_name][customer_phone][...][date_added], где «works» это список работ в json формате с idx ключом для возможности редактирования данных в будущем

Далее подперчить скриптами, сделать страницу вывода заказов и вроде всё ок

p.s. про единицу измерения не понял
p.s.s. можно вообще без добавления $action case «select» и просто объединить html из пунктов 5 и 6 в каждом результате, а уже стилями ненужное скрывать. Тогда при добавлении просто клонировать объект и подставлять в .added-items, где скрыта кнопка добавления…
Andrei D.
30 мая 2017, 05:05
+1
плагин примерно такой (не проверял):
<?php
if ($modx->event->name != 'OnPageNotFound') {return false;}
$alias = $modx->context->getOption('request_param_alias', 'q');
if (!isset($_REQUEST[$alias])) {return false;}

$request = $_REQUEST[$alias];
$tmp = explode('/', $request);
if ($tmp[0] == 'users' && count($tmp) >= 2) {
	$section = 1; //id страницы профиля
	$name = str_replace('.html', '', $tmp[1]);
	if ($tmp[1] != $name || !isset($tmp[2])) {
		$modx->sendRedirect($tmp[0] . '/' . $name);
	}

	switch($tmp[2]) {
		case 'posts':
			$page_type = 'posts';
			break;
		case 'comments':
			$page_type = 'comments';
			break;
		case 'favourites':
			$page_type = 'favourites';
			break;
		default:
			$page_type = 'main';
			break;
	}
	
	if ($user = $modx->getObject('modUser', array('username' => $name))) {
		$id = $user->get('id');
		$joined = $user->get('createdon');
		$profile = $user->getOne('Profile');
		$fullname = $profile->get('fullname');
		$photo = $profile->get('photo');
		//
		$modx->setPlaceholder('page_type', $page_type);
		$modx->setPlaceholders(array(
			'id'  => $id,
			'joined' => $joined,
			'username' => $name,
			'fullname' => $fullname,
			'photo' => $photo,
		),'user_');
		/////// может пригодиться
		$additional = $modx->getObject('TicketAuthor', $id);
		$modx->setPlaceholder('user_posts_count', $additional->tickets);
		$modx->setPlaceholder('user_comments_count', $additional->comments);
		$modx->setPlaceholder('user_favourites_count', $additional->stars_tickets);
		$modx->setPlaceholder('pagetitle', $fullname);
		/////// может пригодиться//
		$modx->sendForward($section);
	}
}

если fenom включен, то на странице профиля примерно так (наобум):
<ul class="tabs">
<li class="{if $page_type == 'main'}active{/if}"><a href="/users/{$user_username}">Профиль</a></li>
<li class="{if $page_type == 'posts'}active{/if}"><a href="/users/{$user_username}/posts">Посты<span class="count">{$user_posts_count}</span></a></li>
<li class="{if $page_type == 'comments'}active{/if}"><a href="/users/{$user_username}/comments">Комменты<span class="count">{$user_comments_count}</span></a></li>
<li class="{if $page_type == 'favourites'}active{/if}"><a href="/users/{$user_username}/favourites">Избранное<span class="count">{$user_favourites_count}</span></a></li>
</ul>

<!--чанк-->[[$virtualpage_{$page_type}]]<!--чанк//-->
p.s. в чанке плейсхолдеры через [[!+плейсхолдер]], либо вызывать чанк через {$_modx->getChunk(…
Andrei D.
28 мая 2017, 12:19
+1
Как в моем комменте выше, если вы не хотите (извиняюсь, что переходил на «ты» – увидел тёзку, расслабился)) создавать отдельные ресурсы для каждой из виртуальных страниц, но у вас есть одна общая страница, то нужно передавать любой идентификатор на неё.

Если плагин и все страницы (username/posts, username/comments и т.д.) работают +
если установлен pdoTools и в настройках сайта значения: pdotools_fenom_default, pdotools_fenom_modx, pdotools_fenom_parser,pdotools_fenom_php = ДА, то с помощью Fenom это будет примерно так:

{if $page_type == 'comments'}
[[$чанк_комментов]] или контент
{elseif $page_type == 'favorites'}
[[$чанк_избранного]] или контент
{/if}

Шаблонизатор Fenom

или просто подставляете нужный чанк на странице одной строчкой:
[[$virtualpage_{$page_type}]]
или
[[$virtualpage_[[!+page_type]]]]
Andrei D.
27 мая 2017, 13:23
+1
согласен, на скорую руку добавил
Andrei D.
27 мая 2017, 13:21
+1
передавай тогда уникальный идентификатор в плейсхолдер, например,
case 'comments':
$page_type = 'comments';

$modx->setPlaceholder('page_type', $page_type);
и на общей странице через fenom выводи нужный контент

p.s. уходи от контекстов, если сайт только разрабатывается. для двух языков еще нормально, но потом будет каша из огромного количества ресурсов + по дизайну сложно что-то экстра конкретное сделать для страницы с определенным ID (3 языка = перечисление трёх id и т.д.)
Andrei D.
27 мая 2017, 12:43
0
Для профилей в виде www.website.com/sampleusername/posts:
На каждую страницу пользователя создается отдельный ресурс, в котором ловятся плейсхолдеры
<?php
if ($modx->event->name != 'OnPageNotFound') {return false;}
$alias = $modx->context->getOption('request_param_alias');
if (!isset($_REQUEST[$alias])) {return false;}

$request = $_REQUEST[$alias];
$tmp = explode('/', $request);

if (count($tmp) >= 1) {
	$section = 1;//id главной страницы профиля
	$name = str_replace('.html', '', $tmp[0]);
	if ($tmp[0] != $name || (isset($tmp[1]) && $tmp[1] == '')) {
		$modx->sendRedirect('/' . $name);
	}
	
	switch($tmp[1]) {
		case 'posts':
			$section = 2;//id страницы постов
			break;
		//
		case 'comments':
			$section = 3;//id страницы комментариев
			break;
		//
		case 'favourites':
			$section = 4;//id страницы избранного
			break;
		//
		default:
		    $section = 1;
			break;
	}
	
	if ($user = $modx->getObject('modUser', array('username' => $name))) {
		$id = $user->get('id');
		$joined = $user->get('createdon');
		$profile = $user->getOne('Profile');
        	//
        	$modx->setPlaceholders(array(
            		'id'  => $user->get('id'),
            		'username' => $name,
            		'fullname' => $profile->get('fullname'),
            		'joined' => $user->get('createdon'),
        	),'user_');
		//
	} else {
	   $section = 5;//id страницы 404
    	}
    $modx->sendForward($section);
    
}
p.s. табуляция тут спадает(
Andrei D.
23 апреля 2017, 22:57
+2
{if $_modx->resource.template == 2}
2
{elseif $_modx->resource.template == 3}
3
{/if}

Шаблонизатор Fenom
Andrei D.
20 апреля 2017, 10:32
0
спасибо за развернутый ответ!
помогло:
use ($modx){
код просто для демонстрации, в реальности он выглядит по-другому
Andrei D.
20 апреля 2017, 10:30
0
большое спасибо!
Andrei D.
14 апреля 2017, 08:37
0
Спасибо