Running workout (-15C, 17km @ 2h02m)

- Posted in Uncategorized by

Endomondo Running Workout

Для статистики по одежде и погоде - записи на память.

2012-01-31. -15C, ветер. Футболка с длинным рукавом + виндблок = оптимум. При -5..-8 было жарко, снимал куртку. Но ходить прохладно. Луна светит так, что никакие фонарики не нужны.

Стандартно - баф на шею-нос, шапка из виндблока. Ну и перчатки (тоже виндблок).

Opencart 1.5.1.2: Модуль категорий: третий уровень (без оптимизации запросов)

- Posted in Uncategorized by

Запоздало публикую рецепт вывода 3-го уровня категорий для версии 1.5.1.2. Способ стандартный опенкартовский, чудовищно неоптимальный, но мне надо было сделать быстро, поэтому не стал голову морочить. Для 1.5.1.3 надо будет сделать получше (если это ещё не сделано кем-то ещё).

Количество категорий - 91. Первого уровня - около десятка. Визуально на скорости загрузки страниц это добавление третьего уровня никак не сказалось. Цифры не смотрел.

Заодно было убрано отображение количества товаров в скобках: при большом количестве категорий и узкой колонке внешний вид сильно страдает от их наличия, список выглядит неряшливо.

Тем, кому количество товаров в категориях захочется оставить - верните на место закомментированные в паре мест $product_total, я их оставил в коде. Но это вам и тормозов добавит. Я бы, если и оставлял отображение количества , то на небольших списках и желательно с короткими названиями (не многострочными).

commit 2f6f47af0cfe0bea4815b76579940eb8139f11cb
Author: Ruslan Brest <rb@labtodo.com>
Date:   Mon Jan 30 02:21:17 2012 +0200
    [+] oc1512 Модуль категорий: третий уровень (без оптимизации запросов)
    
    убрано отображение количества товаров в категориях (так гораздо аккуратней при большом кол-ве категорий)
    убраны точки и улучшены отступы -- для более аккуратного внешнего вида
diff --git a/public_html/catalog/controller/module/category.php b/public_html/catalog/controller/module/category.php
index 09a4bd1..5a9fcaa 100644
--- a/public_html/catalog/controller/module/category.php
+++ b/public_html/catalog/controller/module/category.php
@@ -23,6 +23,12 @@ class ControllerModuleCategory extends Controller {
            $this->data['child_id'] = 0;
        }
 
+       if (isset($parts[2])) {
+           $this->data['ch3_id'] = $parts[2];
+       } else {
+           $this->data['ch3_id'] = 0;
+       }
+
        $this->load->model('catalog/category');
        $this->load->model('catalog/product');
 
@@ -40,12 +46,22 @@ class ControllerModuleCategory extends Controller {
                    'filter_category_id'  => $child['category_id'],
                    'filter_sub_category' => true
                );
-
-               $product_total = $this->model_catalog_product->getTotalProducts($data);
+               // $product_total = $this->model_catalog_product->getTotalProducts($data);
+
+               $level3 = $this->model_catalog_category->getCategories($child['category_id']);
+               $l3_data = array();
+               foreach ($level3 as $l3) {
+                   $l3_data[] = array(
+                       'category_id' => $l3['category_id'],
+                       'name'        => $l3['name'],
+                       'href'        => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id']. '_' . $l3['category_id'])
+                   );
+               }
 
                $children_data[] = array(
                    'category_id' => $child['category_id'],
-                   'name'        => $child['name'] . ' (' . $product_total . ')',
+                   'name'        => $child['name'], // . ' (' . $product_total . ')',
+                   'children'    => $l3_data,
                    'href'        => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
                );
            }
@@ -55,11 +71,11 @@ class ControllerModuleCategory extends Controller {
                'filter_sub_category' => true
            );
 
-           $product_total = $this->model_catalog_product->getTotalProducts($data);
+           // $product_total = $this->model_catalog_product->getTotalProducts($data);
 
            $this->data['categories'][] = array(
                'category_id' => $category['category_id'],
-               'name'        => $category['name'] . ' (' . $product_total . ')',
+               'name'        => $category['name'], // . ' (' . $product_total . ')',
                'children'    => $children_data,
                'href'        => $this->url->link('product/category', 'path=' . $category['category_id'])
            );
diff --git a/public_html/catalog/view/theme/crista_grey/stylesheet/stylesheet.css b/public_html/catalog/view/theme/crista_grey/stylesheet/stylesheet.css
index d215d29..7eff032 100644
--- a/public_html/catalog/view/theme/crista_grey/stylesheet/stylesheet.css
+++ b/public_html/catalog/view/theme/crista_grey/stylesheet/stylesheet.css
@@ -830,6 +830,12 @@ a.button:hover span {
 .box-category > ul > li ul > li > a.active {
    font-weight: bold;
 }
+
+.box-category > ul > li ul > li ul > li {
+   padding: 5px 0 0 10px;
+}
+
+
 /* content */
 #content .content {
    padding: 10px;
diff --git a/public_html/catalog/view/theme/default/template/module/category.tpl b/public_html/catalog/view/theme/default/template/module/category.tpl
index fca707f..5157259 100644
--- a/public_html/catalog/view/theme/default/template/module/category.tpl
+++ b/public_html/catalog/view/theme/default/template/module/category.tpl
@@ -16,17 +16,33 @@
                <?php foreach ($category['children'] as $child) { ?>
                    <li>
                    <?php if ($child['category_id'] == $child_id) { ?>
-                       <a href="<?php echo $child['href']; ?>" class="active">• <?php echo $child['name']; ?></a>
+                       <a href="<?php echo $child['href']; ?>" class="active"><?php echo $child['name']; ?></a>
                    <?php } else { ?>
-                       <a href="<?php echo $child['href']; ?>">· <?php echo $child['name']; ?></a>
+                       <a href="<?php echo $child['href']; ?>"><?php echo $child['name']; ?></a>
                    <?php } ?>
+
+                   <?php if ($child['children']) { ?>
+                   <ul>
+                   <?php foreach ($child['children'] as $ch3) { ?>
+                       <li>
+                       <?php if ($ch3['category_id'] == $ch3_id) { ?>
+                           <a href="<?php echo $ch3['href']; ?>" class="active"><?php echo $ch3['name']; ?></a>
+                       <?php } else { ?>
+                           <a href="<?php echo $ch3['href']; ?>"><?php echo $ch3['name']; ?></a>
+                       <?php } ?>
+                       </li>
+                   <?php } ?>
+                   </ul>
+                   <?php } ?>
+
+
                    </li>
                <?php } ?>
                </ul>
-           <?php } ?>
+               <?php } ?>
            </li>
        <?php } ?>
        </ul>
        </div>
    </div>
-</div>
+</div>
\ No newline at end of file

Форум для интеграции с Opencart

- Posted in Uncategorized by

Встречайте форум для Опенкарт 1.5.1.x. Интегрируется с базой Опенкарт (как пользователями, так и покупателями), настраивается из админки. Написан на CakePHP. Живёт на гитхабе.

GitHub: https://github.com/horechek/ocforum

Демо: http://demoshop.tvorzasp.com/forum/

Оригинал новости на сайте автора: http://tvorzasp.com/blog/forum-dlya-opencart

UPD 2012-09-02: Новый OC Forum 0.2.0alpha. -CakePHP, +Yii

Opencart 1.5.1.x: Указание размеров картинок в product/category

- Posted in Uncategorized by

Указание размеров картинок в product/category, чтобы не ехала вёрстка (при медленной подгрузке картинок некоторые описания иногда оставалось очень далеко от картинки).

См. также Opencartforum.ru: Кривое отображение при отсутствии картинки товара. Там есть иллюстрация того, от чего именно это спасает.

Проверено на v1.5.1.2 и 1.5.1.3 - нет никаких отличий.

commit 771675b8c92df253457d29eafe804b56aabc8240
Author: Ruslan Brest <rb@labtodo.com>
Date:   Tue Sep 27 14:04:59 2011 +0300
    [+] Указание размеров картинок в product/category
    
    чтобы не ехала вёрстка (при медленной подгрузке картинок некоторые описания
    иногда оставалось очень далеко от картинки)
diff --git a/public_html/catalog/controller/product/category.php b/public_html/catalog/controller/product/category.php
index 6cc4b86..cd86bfd 100644
--- a/public_html/catalog/controller/product/category.php
+++ b/public_html/catalog/controller/product/category.php
@@ -100,8 +100,10 @@ class ControllerProductCategory extends Controller {
 
            if ($category_info['image']) {
                $this->data['thumb'] = $this->model_tool_image->resize($category_info['image'], $this->config->get('config_image_category_width'), $this->config->get('config_image_category_height'));
+               $this->data['thumb_attr'] = 'width="'.$this->config->get('config_image_category_width').'" height="'.$this->config->get('config_image_category_height').'"';
            } else {
                $this->data['thumb'] = '';
+               $this->data['thumb_attr'] = '';
            }
 
            $this->data['description'] = html_entity_decode($category_info['description'], ENT_QUOTES, 'UTF-8');
@@ -190,6 +192,8 @@ class ControllerProductCategory extends Controller {
                $this->data['products'][] = array(
                    'product_id'  => $result['product_id'],
                    'thumb'       => $image,
+                   'thumb_w'     => $this->config->get('config_image_product_width'),
+                   'thumb_h'     => $this->config->get('config_image_product_height'),
                    'name'        => $result['name'],
                    'description' => $descr_plaintext,
                    'price'       => $price,
diff --git a/public_html/catalog/view/theme/default/template/product/category.tpl b/public_html/catalog/view/theme/default/template/product/category.tpl
index dd795de..e5e080c 100644
--- a/public_html/catalog/view/theme/default/template/product/category.tpl
+++ b/public_html/catalog/view/theme/default/template/product/category.tpl
@@ -9,7 +9,7 @@
   <?php if ($thumb || $description) { ?>
   <div class="category-info">
     <?php if ($thumb) { ?>
-    <div class="image"><img src="<?php echo $thumb; ?>" alt="<?php echo $heading_title; ?>" /></div>
+    <div class="image"><img src="<?php echo $thumb; ?>" alt="<?php echo $heading_title; ?>" <?php echo $thumb_attr; ?> /></div>
     <?php } ?>
     <?php if ($description) { ?>
     <?php echo $description; ?>
@@ -70,7 +70,7 @@
     <?php foreach ($products as $product) { ?>
     <div>
       <?php if ($product['thumb']) { ?>
-      <div class="image"><a href="<?php echo $product['href']; ?>"><img src="<?php echo $product['thumb']; ?>" title="<?php echo $product['name']; ?>" alt="<?php echo $product['name']; ?>" /></a></div>
+      <div class="image"><a href="<?php echo $product['href']; ?>"><img src="<?php echo $product['thumb']; ?>" width="<?php echo $product['thumb_w']; ?>" height="<?php echo $product['thumb_h']; ?>" title="<?php echo $product['name']; ?>" alt="<?php echo $product['name']; ?>" /></a></div>
       <?php } ?>
       <div class="name"><a href="<?php echo $product['href']; ?>"><?php echo $product['name']; ?></a></div>
       <div class="description"><?php echo $product['description']; ?></div>

Opencart 1.5.1.3 &#45; не отображаются заказы в админке

- Posted in Uncategorized by

Несколько человек обращались с одинаковым вопросом:

при заказе через модуль quickcheckout для opencart 1.5.1.3 не отображаются заказы в админке (Продажи->Заказы) 1.5.1.3. Тема нестандартная, но все скопировано и все работает (кроме заказов в админке). При этом в Отчеты->Продажи->Заказы отображается количество заказов. Подскажите пожалуйста как решить проблему.

Сообщаю, что я тут не при чём - это ошибка #616 в Opencart. Заказы не отображаются правильно и при заказах обычной формой. Там же описан кратенький рецепт решения (изменить is_null на empty в 6 или 7 строке).

Opencart 1.5.1.3 (admin): пара мелких улучшений Admin Dashboard

- Posted in Uncategorized by

Сегодня пара мелких, но полезных визуальных улучшений админки:

  • Выделение цветом разрешенных элементов в списках расширений (Дополнения / доставка, оплата и т.п.);
  • Dashboard - выделение красным пунктов, ожидающих модерации;
  • подсветка строки под курсором в таблицах (hover) (кажется было раньше, здесь для 1.5.1.3 уже за компанию попалось под руку)
  • Вспомните, как вы пропускали новые комментарии и ожидающих активации партнеров, а также с трудом пытались сориентироваться на большом экране, какой же модуль разрешён, а какой запрещён...

    Вспомнили? Тогда информация будет вам полезна:

    commit f9c192a6c30b7b8db5a5621b391680451c1c6d7d
    Author: Ruslan Brest <rb@labtodo.com>
    Date:   Fri Dec 30 20:37:51 2011 +0200
        [+] admin UI: Выделение цветом разрешенных элементов в списках расширений; Dashboard - выделение красным пунктов, ожидающих модерации
    diff --git a/upload/admin/controller/common/home.php b/upload/admin/controller/common/home.php
    index 06b5567..c2b1a7e 100644
    --- a/upload/admin/controller/common/home.php
    +++ b/upload/admin/controller/common/home.php
    @@ -147,16 +147,22 @@ class ControllerCommonHome extends Controller {
            
            $this->data['total_customer'] = $this->model_sale_customer->getTotalCustomers();
            $this->data['total_customer_approval'] = $this->model_sale_customer->getTotalCustomersAwaitingApproval();
    +       if( $this->data['total_customer_approval'] > 0 )
    +           $this->data['total_customer_approval'] = sprintf('<span class="attn">%s</span>', $this->data['total_customer_approval']);
            
            $this->load->model('catalog/review');
            
            $this->data['total_review'] = $this->model_catalog_review->getTotalReviews();
            $this->data['total_review_approval'] = $this->model_catalog_review->getTotalReviewsAwaitingApproval();
    +       if( $this->data['total_review_approval'] > 0 )
    +           $this->data['total_review_approval'] = sprintf('<span class="attn">%s</span>', $this->data['total_review_approval']);
            
            $this->load->model('sale/affiliate');
            
            $this->data['total_affiliate'] = $this->model_sale_affiliate->getTotalAffiliates();
            $this->data['total_affiliate_approval'] = $this->model_sale_affiliate->getTotalAffiliatesAwaitingApproval();
    +       if( $this->data['total_affiliate_approval'] > 0 )
    +           $this->data['total_affiliate_approval'] = sprintf('<span class="attn">%s</span>', $this->data['total_affiliate_approval']);
                    
            $this->data['orders'] = array(); 
            
    diff --git a/upload/admin/controller/extension/feed.php b/upload/admin/controller/extension/feed.php
    index 6d8cf42..8ba93ff 100644
    --- a/upload/admin/controller/extension/feed.php
    +++ b/upload/admin/controller/extension/feed.php
    @@ -87,7 +87,7 @@ class ControllerExtensionFeed extends Controller {
                                        
                    $this->data['extensions'][] = array(
                        'name'   => $this->language->get('heading_title'),
    -                   'status' => $this->config->get($extension . '_status') ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),
    +                   'status' => $this->config->get($extension . '_status') ? '<span class="enabled">'.$this->language->get('text_enabled').'</span>' : $this->language->get('text_disabled'),
                        'action' => $action
                    );
                }
    diff --git a/upload/admin/controller/extension/payment.php b/upload/admin/controller/extension/payment.php
    index 50502c3..fc49d39 100644
    --- a/upload/admin/controller/extension/payment.php
    +++ b/upload/admin/controller/extension/payment.php
    @@ -97,7 +97,7 @@ class ControllerExtensionPayment extends Controller {
                    $this->data['extensions'][] = array(
                        'name'       => $this->language->get('heading_title'),
                        'link'       => $link,
    -                   'status'     => $this->config->get($extension . '_status') ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),
    +                   'status'     => $this->config->get($extension . '_status') ? '<span class="enabled">'.$this->language->get('text_enabled').'</span>' : $this->language->get('text_disabled'),
                        'sort_order' => $this->config->get($extension . '_sort_order'),
                        'action'     => $action
                    );
    diff --git a/upload/admin/controller/extension/shipping.php b/upload/admin/controller/extension/shipping.php
    index e801811..e5c6b4c 100644
    --- a/upload/admin/controller/extension/shipping.php
    +++ b/upload/admin/controller/extension/shipping.php
    @@ -88,7 +88,7 @@ class ControllerExtensionShipping extends Controller {
                                            
                    $this->data['extensions'][] = array(
                        'name'       => $this->language->get('heading_title'),
    -                   'status'     => $this->config->get($extension . '_status') ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),
    +                   'status'     => $this->config->get($extension . '_status') ? '<span class="enabled">'.$this->language->get('text_enabled').'</span>' : $this->language->get('text_disabled'),
                        'sort_order' => $this->config->get($extension . '_sort_order'),
                        'action'     => $action
                    );
    diff --git a/upload/admin/controller/extension/total.php b/upload/admin/controller/extension/total.php
    index acbb06f..ebde251 100644
    --- a/upload/admin/controller/extension/total.php
    +++ b/upload/admin/controller/extension/total.php
    @@ -88,7 +88,7 @@ class ControllerExtensionTotal extends Controller {
                                            
                    $this->data['extensions'][] = array(
                        'name'       => $this->language->get('heading_title'),
    -                   'status'     => $this->config->get($extension . '_status') ? $this->language->get('text_enabled') : $this->language->get('text_disabled'),
    +                   'status'     => $this->config->get($extension . '_status') ? '<span class="enabled">'.$this->language->get('text_enabled').'</span>' : $this->language->get('text_disabled'),
                        'sort_order' => $this->config->get($extension . '_sort_order'),
                        'action'     => $action
                    );
    diff --git a/upload/admin/view/stylesheet/stylesheet.css b/upload/admin/view/stylesheet/stylesheet.css
    index fe82124..53f488f 100644
    --- a/upload/admin/view/stylesheet/stylesheet.css
    +++ b/upload/admin/view/stylesheet/stylesheet.css
    @@ -517,3 +517,12 @@ table.form > tbody > tr > td {
        padding: 10px; 
        min-height: 180px;  
     }
    +
    +/**** UI improvement ****/
    +.enabled {color: green;}
    +.attn {
    +   padding: 3px;
    +   background: #FFD1D1 10px center no-repeat;
    +   border: 1px solid #F8ACAC;
    +   color: #555555;
    +}
    \ No newline at end of file
    commit f825c12b92afe6f20137b38814a7b72f3381e729
    Author: Ruslan Brest <rb@labtodo.com>
    Date:   Fri Dec 30 20:04:14 2011 +0200
        [+] admin UI: подсветка строки под курсором в таблицах (hover)
    diff --git a/upload/admin/view/stylesheet/stylesheet.css b/upload/admin/view/stylesheet/stylesheet.css
    index bb9e451..fe82124 100644
    --- a/upload/admin/view/stylesheet/stylesheet.css
    +++ b/upload/admin/view/stylesheet/stylesheet.css
    @@ -304,6 +304,10 @@ a.button, .list a.button {
        padding: 0px 5px;
        background: #FFFFFF;
     }
    +.list tbody tr:hover td {
    +   background:  #e6f1ff;
    +   /*background: #ffe9a3;*/
    +}
     .list .left {
        text-align: left;
        padding: 7px;

    Почему я уважаю email (и может ещё Jabber), а скайп, аську и прочую чатико&#45;переписку (VK, FB) &#45;&#45; нет

    - Posted in Uncategorized by

    Преимущества email:

    • не отвлекает тогда, когда ему хочется. В работе программиста это очень важный момент. Критически важный;
    • Переписка может без доп. усилий храниться в одном месте, на сервере. И быть доступной с нескольких компьютеров (в т.ч. чужих) и телефонов;
    • возможность сводить переписку в единое место -- это возможность настроить раз единые правила фильтрации и постепенно их дополнять;
    • простота - друг совершенства. Настроить уведомления на SMS при поступлении почты от определенной группы собеседников или при срабатывании какого-либо правила -- никаких проблем. Отфильтровать и настроить такое уведомление в ICQ/Skype... Ну-у-у, попробуйте. И учтите весь зоопарк устройств, которые могут понадобиться;
    • правила обработки email могут храниться и обрабатываться на сервере. Необязательно держать у себя включенное и подключенное к интернет устройство, чтобы оно занималось фильтрацией (а 99.99% времени - простаивало и жрало батарейку без всякой пользы). И не надо головной боли при смене устройства. Получил SMS о чем-то важном в почте - подключился, забрал почту, читаешь.

    Аська, скайп, телефон:

    • очень мешают тем, что могут прервать мыслительный процесс в самый неподходящий момент;
    • историю хранить в едином месте нереально. Особенно этим страдает Скайп и телефон;
    • в телефоне логов разговоров вообще не остается. Особенно при деловых разговорах. Или обсуждении деталей задач. Или условий. Человек иногда с удивлением узнает, что именно он говорил или писал, когда видит логи. Даже самый искренний. Потому что совершенно искренне считал, что сказал по-другому. И привычка фиксации часто спасает от скандалов. Речь вообще даже не о злом умысле. Просто об особенностях психологии и памяти человека в стрессовых условиях;
    • Скайп имеет самый идиотскую реализацию просмотра истории и поиска, которую я видел. А внутренности логов лежат не в виде текста, HTML или XML, а в бинарном виде. Но если бы это позволяло ему хотя бы быстро работать... Так нет же. Дождаться загрузки длинного лога - целая вечность проходит;
    • если угораздило обсуждать что-то важное в дороге и забыл или не смог перенести это вовремя на десктоп или в онлайн-хранилище -- найти потом, где это было, когда и на каком девайсе -- целый подвиг. Особенно если дел много. Перенести с телефона важные детали или присланные в процессе разговора длинные ссылки -- сплошная головная боль, потому что мобильные ICQ/Jabber клиенты обычно понятия не имеют об экспорте. Совсем другое дело при использовании email.
    • в аське часты сообщения "привет" и "ты здесь?", после которых нет ничего. Представьте себе, что чувствует занятый человек, просматривая раз в 10-30 минут накопившиеся сообщения, чтобы ответить на самое важное, а остальные минут 20-30 иметь возможность посвятить очередной задаче без отвлечений? Я на такие вопросы и приветы обычно вообще не отвечаю, и вот почему. Если есть что-то важное - человек обычно пишет о проблеме сразу, а я могу быстро отреагировать, когда в свободный промежуток увидел конкретный вопрос среди десятка других бестолковых сообщений-пустышек. Если там только "приветы", то обычно человеку просто одиноко и разговоры в аське превращаются не в решение проблем, а долгое обмусоливание и размышления вслух;
    • обсуждение одного и того же вопроса по email занимает 10-20 минут, в ICQ/скайпе -- минимум час-полтора. Поскольку в разговоре возникают паузы (то у одного, то у другого собеседника) и писать "словесного мусора" приходится гораздо больше, чем обычно пишешь в ответе на email. В общем, чат отвлекает от дел гораздо больше;
    • использование IM и чатов приводит к более частой отсылке отрывочных фраз, не всегда полностью завершённых, которые нетерпеливый собеседник может прервать новыми вопросами и обсуждениями, не дождавшись конца мысли. В итоге идёт винегрет обсуждения, часто нескольких вопросов, и разобраться в этой каше, что к чему относится, впоследствии становится очень трудно. Кто читал логи бурных быстрых обсуждений в попытке выловить из них конкретные задачи, планы и историю обсуждения вопроса или нескольких - поймёт, о чём речь. Кто пытался восстановить ситуацию по вчерашним-позавчерашним срочным разговорам, когда приходится переключаться между несколькими проектами (и все подробности в голове просто не удержишь) -- тоже в курсе проблемы;
    • иллюзия постоянной доступности человека в аське/скайпе/джаббере - лишь иллюзия. Когда именно я увижу сообщение - зависит лишь от наличия свободного времени, а не от сигнала. Чаще я смотреть туда не стану по каждому прерыванию, поскольку не в службе поддержки работаю, а для работы мне надо сосредоточиться и иметь возможность думать о задаче в течение достаточно длинных промежутков времени. Программисты так устроены: мы держим в голове массу деталей и связей, и нам надо построить в голове модель происходящих процессов, чтобы в ней ориентироваться. И если задачи сложные, а не 5-минутные, любое отвлечение способно разрушить весь этот воздушный замок и процесс "втягивания" приходится начинать заново.

    Резюме

    Почта удобна тем, что я в нее смотрю, когда свободен. И вся переписка хранится в едином месте. Доступная и с телефона, и с любого компьютера. В отличие от асек и скайпов, где концов не соберешь, потому что понять невозможно, где обсуждали тот вопрос, а где этот, а где файлы и пароли присылались, и на каком компьютере или телефоне этот лог разговора остался и где его теперь искать.

    В общем, поймите: не человек - придаток машины, реагирующий на звоночки, а машина является инструментом думающего человека. И только человек решает, отвечать ли на звонки (как телефонные, так и их аналоги), когда он занят. А когда свободен - почту проверять раз в пять минут и чаще никто не мешает, уведомления на SMS получать тоже. Поверьте, скорость получения уведомлений там ничуть не хуже, чем у IM-клиентов.

    Поэтому я за почту.

    Скорость реакции на почту и IM - одинаковая (сюрприз!). Поскольку всё равно определяется скоростью моей реакции на ситуацию, а не скоростью света и чьими-то желаниями.

    Hint: как облегчить другим работу с вашими письмами

    Несколько мелочей и микро-правил, которые способны сделать другим жизнь проще при работе с вашими письмами.

    Необязательно, но весьма желательно:

    • Никакого HTML оформления. Забудьте. Только plain text;
    • приветствия в эл. письмах при регулярной переписке -- штука бесполезная. То же самое обычно можно сказать о цитировании и перечислении даты и времени письма, на которое отвечаем. Через некоторое время люди перестают обращать внимание на эти служебные строки, иногда там просто "слепое пятно" образуется. Если на большом экране эти 1-2 строки мы просто "пропускаем мимо глаз", то на смартфонах это занимает пол-экрана. Лучше, когда сразу идёт текст по делу;
    • то же, но в меньшей степени, относится к подписи. Уместно в первом письме к новому собеседнику включить полную подпись со всеми контактами и телефонами, а в последующих, если переписка уже длится некоторое время, лучше иметь короткий вариант: с 1-2 контактами или единственной ссылкой на сайт (на страницу со всеми контактами). То ли на персональном сайте, то ли где-то в соцсетях (Linkedin, VK, Facebook, Google+), то ли в блоге (Livejournal, Wordpress, Blogspot и т.п.) Иметь сейчас страницу с полным списком контактов совсем несложно, заводить для этого свой сайт-визитку необязательно.

    Внутренности писем:

    • разделяйте абзацы пустой строкой (два раза Enter, а не один). Если отвечаете после цитаты - также отделяйте ответ пустой строкой. Не пишите сразу на следующей строке после квотинга. Этим вы спасёте мозг и пальцы тех, кто работает с почтой на мобильных устройствах (смартфонах, в частности);
    • атомарность, одно письмо -- один вопрос. Лучше послать 10 коротких писем, чем одно большое с 10 разными вопросами. Это поможет легче работать с письмами как с задачами, а также спасёт в очередной раз мобильных пользователей (если не понимаете, о чём я - вы ни разу не пытались ответить на длинное письмо, находясь в пути и имея немного свободного времени). Как следствие - это способно значительно ускорить получение ответов: проще сразу ответить на 3-4 более простых вопроса с телефона, а пару более объёмных оставить для десктопа, чем если надо ответить на большое письмо с несколькими темами/проблемами. Редактировать большое письмо пальцами на смартфоне, пытаясь разбить его на более мелкие -- замучаешься;
    • если есть возможность - настройте почтовый клиент так, чтобы текст цитируемого письма располагался после подписи. Но в случае больших писем это будет неудобно. В случае с атомарными короткими сообщениями - очень удобно.

    Hint: как облегчить себе работу с почтой

    • Исповедуйте правило пустого инбокса;
    • не пользуйтесь почтовым ящиком как хранилищем. Всё, что касается конкретных проектов - сразу сохраняйте в папке с проектом (если письмо вообще стоит хранить) в виде обычного текста. Имя файла должно включать как минимум дату (в ISO формате: YYYY-MM-DD). Можно ещё время, email или ник отправителя. Совсем необязательно сохранять одно письмо в одном файле: цепочки обсуждений удобно записывать в один большой файл (txt или markdown), а аттачменты складывать рядом (предваряя имя файла датой-временем). Но разрастание файла быстро становится неудобным, так что пробуйте и выбирайте по обстоятельствам золотую середину;

    Не складируйте письма: всё, на что можно сразу ответить - отвечайте и удаляйте письмо. Не надо их разбрасывать по папкам, хранить в почтовом клиенте, сортировать с тем, чтобы когда-то почистить, создавать многочисленные правила автоматической сортировки. Всё это - пустая трата времени.

    Что даёт сохранение писем в архиве в виде обычных текстовых файлов?

    • По ним легко и просто искать: как по именам файлов, так и по содержимому;
    • Их можно поместить в систему контроля версий для более удобной и надёжной работы с изменениями;
    • Их легко архивировать и переносить с проектом, не дёргаясь и не собирая хвосты из рабочего и личного почтового ящика, аськи, скайпа, IRC, и ещё Вася что-то с клиентом обсуждал отдельно в четверг, и ещё-не-помню-где=кажется-что-то-было... Всё, относящееся к проекту, собрано в одной папке, а не разбросано в нескольких программах. Возможно, у вас есть багтрекер -- это замечательно. Но тоже накладывает определенные ограничения. Если вы постоянно работаете в команде, и всегда в одной - пользуйтесь багтрекером. Потому что в этом случае велик шанс, что у вас есть дизайнеры и директор, далёкие от VCS, плюс ACL и клиенты с возможностью пускать их в PM/CRM/helpdesk инструмент с веб-доступом. Главное, чтобы было одно централизованное место для поиска всей связанной с проектом информации;
    • Из текстового `markdown` формата легко получить всевозможные красиво оформленные форматы: html, PDF, doc/ods/docx;
    • Рекомендую завести одно персональное место в качестве хранилища знаний (внешнего мозга), плюс в каждом проекте складывать в папку doc всю переписку и дела по этому проекту. Это позволит легко дать доступ к материалам проекта другим участникам при росте команды, а вас быстро приучит разделять личное (в т.ч. и личные проекты) и рабочее. Таким образом, у вас будет всего 2 места для поисков: либо в папке проекта, либо в персональном "внешнем мозге". У меня ещё есть отдельное "более медленное" место для материалов из интернета и книг. Там я храню их в запакованном виде и ищу по именам файлов и папок (файловой системе). Поскольку эти материалы более фундаментальные и реже используются для регулярной оперативной работы и редактирования.

    См. также