<commit_before>###############################################################################
#
# SageMathCloud: A collaborative web-based interface to Sage, IPython, LaTeX and the Terminal.
#
#    Copyright (C) 2015, <NAME>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

###

File Usage Notifications

AUTHORS:
   - first version written by <NAME>, July 25-?, 2015, while unemployed.

DOC:

To mark a file as read: @props.redux.getActions('file_use').mark_file(@props.project_id, @props.path, 'chat')

TODO:

- [x] (0:30)  basic structure and plan
- [x] (0:15?) (0:22) sorted file use by last_edited timestamp
- [x] (0:30?) (0:24) display items a little more readably
- [x] (0:30?) (0:55) search
- [x] (0:30?) (0:27) click to open file
- [x] (0:45?) (0:25) -- proper handling of .sage-chat, ipython, etc. extensions -- seems not working right -- see hub.
- [x] (0:45?) (1:22) notification number
- [x] (0:30?) deal with this in misc_page.coffee: `#u = require('activity').important_count()`
- [x] (1:45) fix subtle backend database issues needed for marking read/seen
- [x] (0:45?) (2:06) mark read
    - [x] (0:42) make an action that takes a single id or array of them as input and marks them all read/seen/etc.
    - [x] (0:24) make clicking mark that one as read
    - [x] (1:00) mark all as read button
- [x] (0:45?) (0:03) mark all seen
- [x] (0:30?) (0:12) click to open file needs to open the chat if there are unseen chats
- [x] (1:00?) (1:02) if list of projects you collaborate on changes, must reset the file_use table, since the files you watched change as a result; client or server side?
- [x] (0:45?) (0:18) delete old polling based activity notification code from hub; delete old activity notification code from page
- [x] (1:00?) (0:30) cursor and enter to open first thing in notification search -- like in log
- [x] (2:00?) (2:15) make pretty:
   - [x] make wider
   - [x] move mark_all_read button to upper right
   - [x] spacing around file_use item
   - [x] color to indicate read
   - [x] color to indicate unseen
   - [x] comment indication
   - [x] truncate long project name
   - [x] truncate long user name
   - [x] truncate long filename
   - [x] nicer layout
   - [x] file type icons
   - [x] special highlight first entry so user knows can open on enter
   - [x] use timeago for when
   - [x] truncate too many names
- [x] (2:00?) optimize
   - [x] (0:30?) (0:30) only show first few notifications and have a button to show more
   - [x] (1:30?) (0:29) switch to immutable.js info and shouldComponentUpdate and optimize when do search


LATER/UNRELATED:

- [ ] (1:00?) address this comment in client.coffee "TODO: must group all queries in one call."
- [ ] (1:00?) in general, open_file needs some sort of visual feedback while it is happening (in any situation)

###


# Magic constants:

# Maximum number of distinct user names to show in a notification
MAX_USERS = 5
# How long after opening log to mark all seen
MARK_SEEN_TIME_S = 3
# Length to truncate project title and filename to.
TRUNCATE_LENGTH = 50
# Number of notifications to show if "Show All" isn't clicked
SHORTLIST_LENGTH = 40


# standard modules
async     = require('async')
immutable = require('immutable')

# smc-specific modules
misc = require('smc-util/misc')

editor = require('./editor')

# react in smc-specific modules
{React, ReactDOM, Actions, Store, Table, rtypes, rclass, Redux, redux}  = require('./smc-react')
{r_join, Icon, Loading, LoginLink, SearchInput, TimeAgo} = require('./r_misc')<commit_msg>delete/change some comments in file_use<commit_after>###############################################################################
#
# SageMathCloud: A collaborative web-based interface to Sage, IPython, LaTeX and the Terminal.
#
#    Copyright (C) 2015, <NAME>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

###

File Usage Notifications

AUTHORS:
   - first version written by <NAME>, July 25-?, 2015, while unemployed.

DOC:

To mark a file as read:

    redux.getActions('file_use').mark_file(project_id, path, 'chat')

###


# Magic constants:

# Maximum number of distinct user names to show in a notification
MAX_USERS = 5
# How long after opening log to mark all seen
MARK_SEEN_TIME_S = 3
# Length to truncate project title and filename to.
TRUNCATE_LENGTH = 50
# Number of notifications to show if "Show All" isn't clicked
SHORTLIST_LENGTH = 40


# standard modules
async     = require('async')
immutable = require('immutable')

# smc-specific modules
misc = require('smc-util/misc')

editor = require('./editor')

# react in smc-specific modules
{React, ReactDOM, Actions, Store, Table, rtypes, rclass, Redux, redux}  = require('./smc-react')
{r_join, Icon, Loading, LoginLink, SearchInput, TimeAgo} = require('./r_misc')
{'fraction_non_alphanumeric': 0.15277100601332683, 'fraction_numerical': 0.024540874370225906, 'mean_word_length': 4.007323026851099, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2734649', 'n_tokens_mistral': 1940, 'n_tokens_neox': 1809, 'n_words': 791}