Commit f3925de4 authored by Eric Oulashin's avatar Eric Oulashin
Browse files

Created a file lister (in JS) that lists files in the user's current file

directory with a lightbar interface, as well as message windows etc.

If the user does not have an ANSI terminal, this lister will run Synchronet's
stock file lister interface.
parent dbf0a87a
Pipeline #2672 passed with stage
in 9 minutes and 44 seconds
......@@ -285,6 +285,29 @@ The 'key down' behavior can be called explicitly, if needed, by calling the DoKe
It takes 2 parameters: An object of selected item indexes (as passed to GetVal()) and, optionally,
the pre-calculated number of items.
lbMenu.DoKeyDown(pNumItems, pSelectedItemIndexes);
For screen refreshing, DDLightbarMenu includes the function DrawPartial(), which can be used to
redraw only a portion of the menu, specified by starting X & Y coordinates, width, and height.
The starting X & Y coordinates are relative to the upper-left corner of the menu (not absolute
screen coordinates) and start at (1, 1). The function signature looks like this:
DrawPartial(pStartX, pStartY, pWidth, pHeight, pSelectedItemIndexes)
The parameters:
pStartX: The column of the character in the menu to start at
pStartY: The row of the character in the menu to start at
pWidth: The width of the content to draw
pHeight: The height of the content to draw
pSelectedItemIndexes: Optional - An object containing indexes of selected items
Another function, DrawPartialAbs(), provies the same functionality but with absolute screen coordinates
(also starting at (1, 1) in the upper-left corner):
DrawPartialAbs(pStartX, pStartY, pWidth, pHeight, pSelectedItemIndexes)
The parameters:
pStartX: The column of the character in the menu to start at
pStartY: The row of the character in the menu to start at
pWidth: The width of the content to draw
pHeight: The height of the content to draw
pSelectedItemIndexes: Optional - An object containing indexes of selected items
*/
if (typeof(require) === "function")
......@@ -451,6 +474,8 @@ function DDLightbarMenu(pX, pY, pWidth, pHeight)
this.DrawBorder = DDLightbarMenu_DrawBorder;
this.WriteItem = DDLightbarMenu_WriteItem;
this.WriteItemAtItsLocation = DDLightbarMenu_WriteItemAtItsLocation;
this.DrawPartial = DDLightbarMenu_DrawPartial;
this.DrawPartialAbs = DDLightbarMenu_DrawPartialAbs;
this.GetItemText = DDLightbarMenu_GetItemText;
this.Erase = DDLightbarMenu_Erase;
this.SetItemHotkey = DDLightbarMenu_SetItemHotkey;
......@@ -730,6 +755,8 @@ function DDLightbarMenu_Draw(pSelectedItemIndexes, pDrawBorders, pDrawScrollbar)
// the rest of the height of the menu.
if (numItemsWritten < numPossibleItems)
{
var numberFormatStr = "%" + this.itemNumLen + "s ";
var itemFormatStr = "%-" + itemLen + "s";
for (; numItemsWritten < numPossibleItems; ++numItemsWritten)
{
writeTheItem = ((this.nextDrawOnlyItems.length == 0) || (this.nextDrawOnlyItems.indexOf(numItemsWritten) > -1));
......@@ -738,8 +765,8 @@ function DDLightbarMenu_Draw(pSelectedItemIndexes, pDrawBorders, pDrawScrollbar)
console.gotoxy(curPos.x, curPos.y++);
console.print("\1n");
if (this.numberedMode)
printf("\1n%" + this.itemNumLen + "s ", "");
var itemText = addAttrsToString(format("%-" + itemLen + "s", ""), this.colors.itemColor);
printf(numberFormatStr, "");
var itemText = addAttrsToString(format(itemFormatStr, ""), this.colors.itemColor);
console.print(itemText);
}
}
......@@ -876,6 +903,209 @@ function DDLightbarMenu_WriteItemAtItsLocation(pIdx, pHighlight, pSelected)
this.WriteItem(pIdx, null, pHighlight, pSelected);
}
// Draws part of the menu, starting at a certain location within the menu and
// with a given width & height (for screen refreshing). The start X and Y location
// are relative to the menu (not the screen), and they start at (1, 1) in the upper-left
//
// Parameters:
// pStartX: The column of the character in the menu to start at
// pStartY: The row of the character in the menu to start at
// pWidth: The width of the content to draw
// pHeight: The height of the content to draw
// pSelectedItemIndexes: Optional - An object containing indexes of selected items
function DDLightbarMenu_DrawPartial(pStartX, pStartY, pWidth, pHeight, pSelectedItemIndexes)
{
// Sanity check the parameters
if (typeof(pStartX) !== "number" || typeof(pStartY) !== "number" || typeof(pWidth) !== "number" || typeof(pHeight) !== "number")
return;
if (pStartX < 1 || pStartX > this.size.width)
return;
if (pStartY < 1 || pStartY > this.size.height)
return;
// Fix the width & height if needed
var width = pWidth;
if (width > (this.size.width - pStartX + 1))
width = (this.size.width - pStartX + 1);
var height = pHeight;
if (height > (this.size.height - pStartY + 1))
height = (this.size.height - pStartY + 1);
var selectedItemIndexes = { }; // For multi-select mode
if (typeof(pSelectedItemIndexes) == "object")
selectedItemIndexes = pSelectedItemIndexes;
// If borders are enabled, draw any border characters in the region first
// The X & Y locations are 1-based
var lastLineNum = (pStartY + this.pos.y + height) - 1; // Last line # on the screen
if (lastLineNum > this.pos.y + this.size.height - 1)
lastLineNum = this.pos.y + this.size.height - 1;
if (this.borderEnabled)
{
var lastX = pStartX + width - 1;
for (var lineNum = pStartY + this.pos.y - 1; lineNum <= lastLineNum; ++lineNum)
{
// Top line
if (lineNum == this.pos.y)
{
console.print("\1n" + this.colors.borderColor);
for (var posX = pStartX; posX <= lastX; ++posX)
{
console.gotoxy(posX, lineNum);
if (posX == this.pos.x)
console.print(this.borderChars.upperLeft);
else if (posX == this.pos.x + this.size.width - 1)
console.print(this.borderChars.upperRight);
else
console.print(this.borderChars.top);
}
}
// Bottom line
else if (lineNum == this.pos.y + this.size.height - 1)
{
console.print("\1n" + this.colors.borderColor);
for (var posX = pStartX; posX <= lastX; ++posX)
{
console.gotoxy(posX, lineNum);
if (posX == this.pos.x)
console.print(this.borderChars.lowerLeft);
else if (posX == this.pos.x + this.size.width - 1)
console.print(this.borderChars.lowerRight);
else
console.print(this.borderChars.bottom);
}
}
// Somewhere between the top & bottom line
else
{
var printedBorderColor = false;
for (var posX = pStartX; posX <= lastX; ++posX)
{
console.gotoxy(posX, lineNum);
if (posX == this.pos.x)
{
if (!printedBorderColor)
{
console.print("\1n" + this.colors.borderColor);
printedBorderColor = true;
}
console.print(this.borderChars.left);
}
else if (posX == this.pos.x + this.size.width - 1)
{
if (!printedBorderColor)
{
console.print("\1n" + this.colors.borderColor);
printedBorderColor = true;
}
console.print(this.borderChars.right);
}
}
}
}
}
// Calculate the width and starting index of the menu items
// Note that pStartX is relative to the menu, not the screen
var itemLen = width;
var writeMenuItems = true; // Might not if the draw area only includes the scrollbar or border
var itemTxtStartIdx = pStartX - 1;
if (this.borderEnabled)
{
if (itemTxtStartIdx > 0)
--itemTxtStartIdx; // pStartX - 2
if (pStartX == 1)
--itemLen;
// Starts on 2 & width is 5: 2, 3, 4, 5, 6
var lastCol = this.pos.x + pStartX + width - 1;
if (this.pos.x + pStartX + width - 1 >= lastCol) // The last column drawn will contain the right border char
--itemLen;
if ((pStartX == 1 && width == 1) || pStartX == this.size.width)
writeMenuItems = false;
else if (this.scrollbarEnabled && !this.CanShowAllItemsInWindow() && pStartX == this.size.width-1)
writeMenuItems = false;
}
if (this.scrollbarEnabled && !this.CanShowAllItemsInWindow())
{
var scrollbarCol = this.borderEnabled ? this.pos.x + this.size.width - 2 : this.pos.x + this.size.width - 1;
if (this.pos.x + pStartX + width - 1 >= scrollbarCol) // The last column drawn includes the scrollbar
--itemLen;
if (!this.borderEnabled && pStartX == this.size.width)
writeMenuItems = false;
// Just draw the whole srollbar to ensure it's updated
this.DisplayInitialScrollbar(this.scrollbarInfo.solidBlockLastStartRow, this.scrollbarInfo.numSolidScrollBlocks);
}
if (itemTxtStartIdx < 0)
itemTxtStartIdx = 0;
// Write the menu items
if (writeMenuItems)
{
var blankItemTextFormatStr = "\1n%" + itemLen + "s";
for (var lineNum = pStartY + this.pos.y - 1; lineNum <= lastLineNum; ++lineNum)
{
var startX = pStartX;
// If borders are enabled, skip the top & bottom lines since borders were already drawn
if (this.borderEnabled)
{
if (lineNum == this.pos.y || lineNum == lastLineNum)
continue;
else
{
if (pStartX + this.pos.x - 1 == this.pos.x)
++startX;
}
}
// Write the menu item text
var itemIdx = this.topItemIdx + (lineNum - this.pos.y);
if (this.borderEnabled) --itemIdx;
var highlightItem = itemIdx == this.selectedItemIdx;
var itemText = this.GetItemText(itemIdx, null, highlightItem, selectedItemIndexes.hasOwnProperty(this.selectedItemIdx));
var shortenedText = substrWithAttrCodes(itemText, itemTxtStartIdx, itemLen);
// If shortenedText is empty (perhaps there's no menu item for this line),
// then make shortenedText consist of all spaces at the proper length
if (shortenedText.length == 0)
shortenedText = format(blankItemTextFormatStr, "");
console.gotoxy(startX, lineNum);
console.print(shortenedText + "\1n");
}
}
}
// Draws part of the menu, starting at a certain location within the menu and
// with a given width & height (for screen refreshing). For this version, the start X
// and Y location are absolute on the screen. They start at (1, 1) in the upper-left.
//
// Parameters:
// pStartX: The column of the character in the menu to start at
// pStartY: The row of the character in the menu to start at
// pWidth: The width of the content to draw
// pHeight: The height of the content to draw
// pSelectedItemIndexes: Optional - An object containing indexes of selected items
function DDLightbarMenu_DrawPartialAbs(pStartX, pStartY, pWidth, pHeight, pSelectedItemIndexes)
{
if (typeof(pStartX) !== "number" || typeof(pStartY) !== "number" || typeof(pWidth) !== "number" || typeof(pHeight) !== "number")
return;
// Calculate the start X & Y coordinates relative to the menu (1-based), and adjust height &
// width if necessary. Then draw partial.
var height = pHeight;
var width = pWidth;
var startX = pStartX - this.pos.x + 1;
var startY = pStartY - this.pos.y + 1;
if (startX < 1)
{
var XDiff = 1 - startX;
startX += XDiff;
width -= XDiff;
}
if (startY < 1)
{
var YDiff = 1 - startY;
startY += YDiff;
height -= YDiff;
}
this.DrawPartial(startX, startY, width, height, pSelectedItemIndexes);
}
// Gets the text of a menu item with colors applied
//
// Parameters:
......@@ -1258,10 +1488,6 @@ function DDLightbarMenu_GetVal(pDraw, pSelectedItemIndexes)
if (mk !== null && mk.mouse !== null)
{
goAheadAndExit = !mouseNoAction; // Only really needed with an input timer?
// Temporary
console.print("\1n\r\nHere! - mouseNoAction: " + goAheadAndExit + ", goAheadAndExit: " + goAheadAndExit + "\r\n");
console.pause();
// End Temporary
}
if (goAheadAndExit)
{
......@@ -1513,7 +1739,7 @@ function DDLightbarMenu_GetVal(pDraw, pSelectedItemIndexes)
if (this.multiSelect)
{
if (Object.keys(selectedItemIndexes).length == 0)
selectedItemIndexes[this.selectedItemIdx] = true;
selectedItemIndexes[+(this.selectedItemIdx)] = true;
}
else
retVal = this.GetItem(this.selectedItemIdx).retval;
......@@ -1539,8 +1765,8 @@ function DDLightbarMenu_GetVal(pDraw, pSelectedItemIndexes)
if (allowSelectItem)
{
var added = false; // Will be true if added or false if deleted
if (selectedItemIndexes.hasOwnProperty(this.selectedItemIdx))
delete selectedItemIndexes[this.selectedItemIdx];
if (selectedItemIndexes.hasOwnProperty(+(this.selectedItemIdx)))
delete selectedItemIndexes[+(this.selectedItemIdx)];
else
{
var addIt = true;
......@@ -1548,7 +1774,7 @@ function DDLightbarMenu_GetVal(pDraw, pSelectedItemIndexes)
addIt = (Object.keys(selectedItemIndexes).length < this.maxNumSelections);
if (addIt)
{
selectedItemIndexes[this.selectedItemIdx] = true;
selectedItemIndexes[+(this.selectedItemIdx)] = true;
added = true;
}
}
......@@ -1620,15 +1846,15 @@ function DDLightbarMenu_GetVal(pDraw, pSelectedItemIndexes)
this.selectedItemIdx = userEnteredItemNum-1;
if (this.multiSelect)
{
if (selectedItemIndexes.hasOwnProperty(this.selectedItemIdx))
delete selectedItemIndexes[this.selectedItemIdx];
if (selectedItemIndexes.hasOwnProperty(+(this.selectedItemIdx)))
delete selectedItemIndexes[+(this.selectedItemIdx)];
else
{
var addIt = true;
if (this.maxNumSelections > 0)
addIt = (Object.keys(selectedItemIndexes).length < this.maxNumSelections);
if (addIt)
selectedItemIndexes[this.selectedItemIdx] = true;
selectedItemIndexes[+(this.selectedItemIdx)] = true;
}
// TODO: Put a check-mark next to the selected item
// TODO: Screen refresh?
......@@ -1715,7 +1941,7 @@ function DDLightbarMenu_DoKeyDown(pSelectedItemIndexes, pNumItems)
if (this.selectedItemIdx < numItems-1)
{
// Draw the current item in regular colors
this.WriteItemAtItsLocation(this.selectedItemIdx, false, selectedItemIndexes.hasOwnProperty(this.selectedItemIdx));
this.WriteItemAtItsLocation(this.selectedItemIdx, false, selectedItemIndexes.hasOwnProperty(+(this.selectedItemIdx)));
++this.selectedItemIdx;
// Draw the new current item in selected colors
// If the selected item is below the bottom of the menu, then we'll need to
......@@ -1730,7 +1956,7 @@ function DDLightbarMenu_DoKeyDown(pSelectedItemIndexes, pNumItems)
{
// The selected item is not below the bottom of the menu, so we can
// just draw the selected item highlighted.
this.WriteItemAtItsLocation(this.selectedItemIdx, true, selectedItemIndexes.hasOwnProperty(this.selectedItemIdx));
this.WriteItemAtItsLocation(this.selectedItemIdx, true, selectedItemIndexes.hasOwnProperty(+(this.selectedItemIdx)));
}
}
else
......@@ -1740,7 +1966,7 @@ function DDLightbarMenu_DoKeyDown(pSelectedItemIndexes, pNumItems)
if (this.wrapNavigation)
{
// Draw the current item in regular colors
this.WriteItemAtItsLocation(this.selectedItemIdx, false, selectedItemIndexes.hasOwnProperty(this.selectedItemIdx));
this.WriteItemAtItsLocation(this.selectedItemIdx, false, selectedItemIndexes.hasOwnProperty(+(this.selectedItemIdx)));
// Go to the first item and scroll to the top if necessary
this.selectedItemIdx = 0;
var oldTopItemIdx = this.topItemIdx;
......@@ -1750,7 +1976,7 @@ function DDLightbarMenu_DoKeyDown(pSelectedItemIndexes, pNumItems)
else
{
// Draw the new current item in selected colors
this.WriteItemAtItsLocation(this.selectedItemIdx, true, selectedItemIndexes.hasOwnProperty(this.selectedItemIdx));
this.WriteItemAtItsLocation(this.selectedItemIdx, true, selectedItemIndexes.hasOwnProperty(+(this.selectedItemIdx)));
}
}
}
......
; The sort order for the file list
; NATURAL: Natural sort order (same as DATE_A)
; NAME_AI: Filename ascending, case insensitive sort order
; NAME_DI: Filename descending, case insensitive sort order
; NAME_AS: Filename ascending, case sensitive sort order
; NAME_DS: Filename descending, case sensitive sort order
; DATE_A: Import date/time ascending sort order
; DATE_D: Import date/time descending sort order
sortOrder=NATURAL
; The name of the color theme configuration file
themeFilename=defaultTheme.cfg
This diff is collapsed.
; Default color theme
; Filename in the file list
filename=\1n\1b\1h
; File size in the file list
fileSize=\1n\1m\1h
; Description in the file list
desc=\1n\1w
; Background color for the highlighted (selected) file menu itme
bkgHighlight=\1n4
; Highlight filename color for the file list
filenameHighlight=\1c\1h
; Highlight file size color for the file list
fileSizeHighlight=\1c\1h
; Highlight description color for the file list
descHighlight=\1c\1h
; File timestamp color for showing an extended file description
fileTimestamp=\1g\1h
; For the extended file information box border
fileInfoWindowBorder=\1r
; For the title of the extended file information box
fileInfoWindowTitle=\1g
; Error box border
errorBoxBorder=\1g\1h
; Error message color
errorMessage=\1y\1h
; Success message color
successMessage=\1c
; Batch download confirm/info window border color
batchDLInfoWindowBorder=\1r
; Batch download info window title color
batchDLInfoWindowTitle=\1g
; Multi-file action confirm window border color
confirmFileActionWindowBorder=\1r
; Multi-file action confirm window title color
confirmFileActionWindowWindowTitle=\1g
; Colors related to moving a file
; The color of the file area menu border (for moving a file)
fileAreaMenuBorder=\1b
; The file area entry background color for 'normal' colors (for moving a file)
fileNormalBkg=\1n4
; The file library/directory number for 'normal' colors (for moving a file)
fileAreaNum=\1w
; The file library/directory description for 'normal' colors (for moving a file)
fileAreaDesc=\1w
; The number of directories/files for 'normal' colors (for moving a file)
fileAreaNumItems=\1w
; The file area entry background color for 'highlight' colors (for moving a file)
fileAreaMenuHighlightBkg=\1n7
; The file library/directory number for 'highlight' colors (for moving a file)
fileAreaNumHighlight=\1b
; The file library/directory description for 'highlight' colors (for moving a file)
fileAreaDescHighlight=\1b
; The number of directories/files for 'highlight' colors (for moving a file)
fileAreaNumItemsHighlight=\1b
\ No newline at end of file
Digital Distortion File Lister
Version 2.00
Release date: 2022-02-06
by
Eric Oulashin
Sysop of Digital Distortion
BBS internet address: digitaldistortionbbs.com
Alternate address: digdist.bbsindex.com
Email: eric.oulashin@gmail.com
This file describes the Digital Distortion File Lister.
Contents
========
1. Disclaimer
2. Introduction
3. Installation & Setup
- Command shell setup
- Background: Running JavaScript scripts in Synchronet
4. Configuration file & color/text theme configuration file
1. Disclaimer
=============
I cannot guarantee that this script is 100% free of bugs. However, I have
tested it, and I used it often during development, so I have some confidence
that there are no serious issues with it (at least, none that I have seen).
2. Introduction
===============
This release is version 2.00 because I had previously released a message lister
mod for Synchronet which was just a list header and a command bar to display
under the list, and it still used Synchronet's stock file list. Now that
Synchronet provides a JavaScript interface to its filebases (as of version
3.19), more customization is possible with JavaScript.
Digital Distortion File Lister is a script for Synchronet that provides an
enhanced user interface (for ANSI terminals) for listing files in the user's
current file directory. This file lister uses a lightbar interface to list the
files, a 'command bar' at the bottom of the screen allowing the user to use the
left & right arrow keys or the first character of the action to select an
action. The file lister also uses message boxes to display information.
If the user's terminal does not support ANSI, the file lister will run the
stock Synchronet file lister interface instead.
When adding files to the user's batch download queue or (for the sysop)
selecting files to move or delete, multi-select mode can be used, allowing
the user to select multiple files using the spacebar. If the spacebar is not
used, the file at the current highlighted lightbar location will be used.
For viewing file information or viewining file contents, only the current file
where the lightbar location will be used.
For the lightbar file list, basic descriptions and short filenames are used in
order for the information for each file to fit on a single line in the list.
The user can view extended information for each file, in which case a window
will be displayed with the filename, size, timestamp, and extended description.
The file lister also provides the ability to view files (according to
Synchronet's viewable files configuration), and adding files to the user's
batch download queue. Additionally, sysops can delete files and move files to
another file directory.
3. Installation & Setup
=======================
Aside from readme.txt revision_history.txt, Digital Distortion File Lister is
comprised of the following files:
1. ddfilelister.js The Digital Distortion File Lister script
2. ddfilelister.cfg The file lister configuration file
3. defaultTheme.cfg The default theme file containing colors used in the
file lister
The configuration files are plain text files, so they can be edited using any
editor.
The .js script and .cfg files can be placed together in any directory. When
the lister reads the configuration file & theme file, the lister will first
look in your sbbs/mods directory, then sbbs/ctrl, then in the same directory
where the .js script is located. So, if you desire, you could place
ddfilelister.js in sbbs/exec and the .cfg file sin your sbbs/ctrl directory,
for example.
Command shell setup
-------------------
Running the file lister involves simply having the BBS run a command to run
ddfilelister.js. No command-line parameters are required. The command to run
ddfilelister.js can be placed in a command shell for a command key, or in
SCFG > External Programs > Online Programs (Doors) in one of your program
groups, and then you could have your command shell run the lister via the
internal program code you configured in SCFG.
Installing into a command shell is described in the subsection "Installing
into a command shell".
Background: Running JavaScript scripts in Synchronet
----------------------------------------------------
The command line to run this script would be as follows (if the script is in
your sbbs/xtrn/ddfilelister directory):
?../xtrn/ddfilelister/ddfilelister.js
In a Baja script, you can use the 'exec' command to run a JavaScript script, as
in the following example:
exec "?../xtrn/ddfilelister/ddfilelister.js"
In a JavaScript script, you can use the bbs.exec() function to run a JavaScript
script, as in the following example:
bbs.exec("?../xtrn/ddfilelister/ddfilelister.js");
To install the file lister as an external program (in SCFG in External
Programs > Online Programs (Doors)), see the following document for more
information:
http://wiki.synchro.net/howto:door:index?s[]=doors
4. Configuration file & color/text theme configuration file
===========================================================
Digital Distortion File Lister allows changing some settings and colors via
configuration files. The configuration files are plain text and can be edited
with any text editor. These are the configuration files used by Digital
Distortion File Lister:
- ddfilelister.cfg: The main configuration file
- defaultTheme.cfg: The default theme configuration file which defines colors
for items displayed in the file lister. The name of this file can be
specified in ddfilelister.cfg, so that alternate "theme" configuration files
can be used if desired.
Each setting in the configuration files has the format setting=value, where
"setting" is the name of the setting or color, and "value" is the corresponding
value to use. The colors specified in the theme configuration file are
Synchronet color/attribute codes. Comments are allowed in the configuration
files - Commented lines begin with a semicolon (;).
Digital Distortion File Lister will look for the configuration files in the
following directories, in the following order:
1. sbbs/mods
2. sbbs/ctrl
3. The same directory as ddfilelister.js
If you customize your configuration files, you can copy them to your sbbs/mods
or sbbs/ctrl directory so that they'll be more difficutl to accidentally
override if you update your xtrn/DDMsgReader from the Synchronet CVS
repository, where this reader's files are checked in.
The configuration settings are described in the sections below:
Main configuration file (DDMsgReader.cfg)
-----------------------------------------
Setting Description
------- -----------
sortOrder String: The file sort order to use.
Valid values are:
NATURAL: Natural sort order (same as DATE_A)
NAME_AI: Filename ascending, case insensitive sort order
NAME_DI: Filename descending, case insensitive sort order
NAME_AS: Filename ascending, case sensitive sort order
NAME_DS: Filename descending, case sensitive sort order
DATE_A: Import date/time ascending sort order
DATE_D: Import date/time descending sort order
themeFilename The name of the configuration file to
use for colors & string settings
Theme configuration file
------------------------
The convention for the setting names in the theme configuration file is that
setting names ending in 'Text' are for whole text strings, and the setting
names that don't end in 'Text' are for colors.
Setting Element in the file lister
------- --------------------------
filename Filename in the file list
fileSize File size in the file list
<